/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQMagnifier.h"

#include <math.h>

#include <QApplication>
#include <QDebug>
#include <QGraphicsPixmapItem>
#include <QImage>
#include <QMouseEvent>
#include <QPainter>
#include <QPixmap>

#include "MvQPlotView.h"
#include "MgQPlotScene.h"

#include "MgQLayoutItem.h"

static bool sceneRendering=false;

MvQMagnifierSlider::MvQMagnifierSlider(QList<float> &values, int actIndex,QColor colour)
{
	actCellIndex_=actIndex;
	
	cellHeight_=13.;
	cellWidth_=6.;	
	cellPen_=QPen(QColor(50,50,50));	

	handlerSize_=cellWidth_+4;

	panelPen_=QPen(Qt::black);	
	panelWidth_=cellWidth_+10;	

	for(int i=0; i < values.count(); i++)
	{
		int lightFactor=100+static_cast<int>(100.*static_cast<float>(i)/static_cast<float>(values.count()));
		qDebug() << lightFactor;
		cells_.push_back(new MvQMagnifierFactorCell(values[i],colour.lighter(lightFactor)));
	}
}


void MvQMagnifierSlider::setGeometry(float r)
{	
	radius_=r;

	cellSweepAngle_=(180./M_PI)*cellHeight_/radius_;
	
	cellBarStartAngle_=180.-cells_.count()*cellSweepAngle_/2.;
	cellBarEndAngle_=cellBarStartAngle_+cells_.count()*cellSweepAngle_;
	cellBarSweepAngle_=cellBarEndAngle_-cellBarStartAngle_;

	cellInnerRadius_=radius_+(panelWidth_-cellWidth_)/2.;
	cellOuterRadius_=radius_+panelWidth_-(panelWidth_-cellWidth_)/2.;

	panelInnerRadius_=radius_;
	panelOuterRadius_=radius_+panelWidth_;

}

float MvQMagnifierSlider::actCellAngle()
{
	return cellBarEndAngle_-(actCellIndex_+0.5)*cellSweepAngle_;
}

void MvQMagnifierSlider::handlerCentre(float &cx, float &cy)
{
	float r=(cellInnerRadius_+cellOuterRadius_)/2.;
	float an=actCellAngle();

	cx=r*cos(an*M_PI/180.);
	cy=r*sin(an*M_PI/180.);
}

bool MvQMagnifierSlider::checkPointInHandler(float x, float y)
{
	float r=(cellInnerRadius_+cellOuterRadius_)/2.;
	float an=actCellAngle();

	float cx=r*cos(an*M_PI/180.);
	float cy=r*sin(an*M_PI/180.);

	return (cx-x)*(cx-x) + (cy-y)*(cy-y) <=  handlerSize_*handlerSize_/4.;
}

bool MvQMagnifierSlider::checkPointInCell(float x, float y, int &index)
{
	index=-1;
	float dist=sqrt(x*x+y*y);       
	if(dist >= panelInnerRadius_  && dist <= panelOuterRadius_)
	{
		float angle=atan2f(y,x)*180./M_PI;
		if(angle < 0.) angle=360.+angle;
		if(angle >= cellBarStartAngle_ && angle <= cellBarEndAngle_)
		{
			index=static_cast<int>((cellBarEndAngle_-angle)/cellSweepAngle_);
			return true;
		}
	}	

	return false;		
}

bool MvQMagnifierSlider::checkPointInPanel(float x, float y)
{
	float dist=sqrt(x*x+y*y);       
	if(dist >= panelInnerRadius_  && dist <= panelOuterRadius_)
	{
		float angle=atan2f(y,x)*180./M_PI;
		if(angle < 0.) angle=360.+angle;
		if(angle >= cellBarStartAngle_ && angle <= cellBarEndAngle_)
		{
			return true;
		}
	}	

	return false;		
}


bool MvQMagnifierSlider::shiftHandler(float x, float y,int &index)
{
	float dist=sqrt(x*x+y*y);       
	if(dist < panelInnerRadius_  || dist > panelOuterRadius_)
		return false;	

	index =-1;
	
	float xc, yc;      
        handlerCentre(xc,yc);

	float dx=x-xc;
	float dy=y-yc;        

        float a=xc*xc+yc*yc;
        float b=(xc+dx)*(xc+dx)+(yc+dy)*(yc+dy);
        float c=dx*dx+dy*dy;
        
        float dfi=(a+b-c)/(2.*sqrt(a*b));
        dfi=acos(dfi)*180./M_PI; 
        float angle=actCellAngle()+((dy<0)?1:-1)*dfi;                	  

	index=static_cast<int>((cellBarEndAngle_-angle)/cellSweepAngle_);

	qDebug() << x << y << xc << yc << dfi << index;

	if(index >=0 && index < cells_.count() && index != actCellIndex_)
	{
		return true;
	}
	else
	{
		return false;
	}
}


MagnifierFrameData::MagnifierFrameData(float w, float minr, float maxr, int n) :
			width_(w), minRadius_(minr), maxRadius_(maxr), ptNum_(n)
{	
	float PI=3.1415926535;
	
	float an=0.;
	float an_step=2.*PI/ptNum_;
	for(int i=0; i< ptNum_; i++)
	{		
		coeffCos_.push_back(cos(an));
		coeffSin_.push_back(sin(an));		
		an+=an_step;					
		
	}		
}



MvQMagnifier::MvQMagnifier(MgQPlotScene *scene,MvQPlotView *view,QGraphicsItem *parent) : 
		          MvQPlotItem(scene,view,parent) 
{
	dataScene_=0;
	dataItem_=0;

	pointInMagnifier_=false;

	minRadius_=50.;
	innerFrameWidth_=3;
	outerFrameWidth_=7;
	frameWidth_=innerFrameWidth_+outerFrameWidth_;
	
	//Default geometry 
	radius_=100.;	
	centreX_=radius_+250.;
	centreY_=radius_+250.;

	//Init factor scales
	QList<float> factors;
	MvQMagnifierSlider *slider;

	//Set text magnification factors		
	factors << 1.5 << 2. << 2.5 << 3. << 3.5 << 4. ;	
	slider = new MvQMagnifierSlider(factors,1,QColor(Qt::red));
	slider->setGeometry(radius_);
	//slider->setHandlerSize(handlerPixmap_->width());
	sliders_[TextMode]=slider;

	//Set data magnification factors		
	factors.clear();
	factors << 2. << 5. << 10. << 25.;	
	slider = new MvQMagnifierSlider(factors,1,QColor(Qt::red));
	slider->setGeometry(radius_);
	//slider->setHandlerSize(handlerPixmap_->width());
	sliders_[DataMode]=slider;			

	//Slider handler pixmap
	QPixmap pxm(QString::fromUtf8(":/uPlot/magnifier_handler"));
	handlerPixmap_=new QPixmap(pxm.scaledToWidth(slider->handlerSize(),Qt::SmoothTransformation)); //!!

	magnifierMode_=TextMode;
	magnifierAction_=NoAction;
	actSlider_=sliders_[magnifierMode_];

	magnifierModeChanged_=false;

	//Set frame data
	frames_.push_back(MagnifierFrameData(6.,20.,150.,60));
	frames_.push_back(MagnifierFrameData(6.,150.,300.,80));
	frames_.push_back(MagnifierFrameData(6.,300.,1000.,100));
	
	actFrameIndex_=0;

	device_= new QImage(823,630,QImage::Format_RGB888);
	//device_= new QPixmap(823,630);
	painter_=new QPainter(device_);

	setPos(centreX_, centreY_);
	setFlag(QGraphicsItem::ItemIsMovable ); 

	actCellIndexAtHandlerActionStart_=0;  

	mouseInLens_=false;
}

MvQMagnifier::~MvQMagnifier()
{
}
	
bool MvQMagnifier::checkCircleInWindow(const float x,const float y,const float r) const
{	
	if(x+r < maxX_ && x-r > minX_ && y+r < maxY_ && y-r > minY_)
	{
		return true;
	}
	else	
	{
		return false;	
	}
}


bool MvQMagnifier::checkPointInWindow(const float x,const float y) const
{
	if((x-minX_)*(maxX_-x) < 0 || (y-minY_)*(maxY_-y) < 0)
	{
		return false;
	}
	else
	{
		return true;	
	}
}

bool MvQMagnifier::checkPointInMagnifier(const QPointF& pos)
{
	float dx=pos.x()-centreX_;
	float dy=pos.y()-centreY_;		
	float dist=sqrt(dx*dx+dy*dy);

	if(dist < radius_)
	{  
		return true;
	}
	return false;
}

MvQMagnifier::MagnifierPointType MvQMagnifier::identifyPoint(const QPointF& point)
{	
	//qDebug() << point;

	//If it is the first time
	if(centreX_ < -99999.) 
	{
		centreX_=point.x();
		centreY_=point.y();
	}	
	
	float dx=point.x();//-centreX_;
	float dy=point.y();//-centreY_;		
	float dist=sqrt(dx*dx+dy*dy);
	

	
	int index;
	if(actSlider_->checkPointInHandler(dx,dy))
	{
		return SliderHandlerPoint;
	}
	else if(actSlider_->checkPointInCell(dx,dy,index))
	{
		if(actSlider_->actCellIndex() != index)
		{
			actSlider_->setActCellIndex(index);
			reset();
			//updateMagnifierState();
			//update();
			emit factorChanged();
			return SliderCellPoint;	
		}
		return OuterPoint;

	}
	else if(dist < radius_-3)
	{  
		return LensPoint;
	}
	else if(dist >= radius_-3 && dist <= radius_+ frameWidth_+3)			
	{
		return FramePoint;
	}
				
	return OuterPoint;		
}

MvQMagnifier::ScenePointType MvQMagnifier::identifyScenePoint(const QPointF& scPos)
{	
  	if(checkPointInMagnifier(scPos))
	{		
		QPointF magPos=sceneToMagnifiedPos(scPos); 		
		if(checkPointInMagnifier(magPos))
		{
		  	return InnerScenePoint;
		}
		else
		{
		  	return CoveredScenePoint;
		}	
	}		
	
	return OuterScenePoint;
}

QPointF	MvQMagnifier::sceneToMagnifiedPos(const QPointF& scPos)
{
	float zoom=actSlider_->actFactorValue();
	QPointF cp(centreX_,centreY_);
	//return cp+(scPos-cp)/zoom;  	
	return (scPos-cp)*zoom+cp;
}  

QPointF	MvQMagnifier::magnifiedToScenePos(const QPointF& magPos)
{
	float zoom=actSlider_->actFactorValue();
	QPointF cp(centreX_,centreY_);
	return cp+(magPos-cp)/zoom;  	
}  

void MvQMagnifier::render(QPainter *painter)
{			
	float zoom=actSlider_->actFactorValue();						

	QRectF sourceRect(centreX_-radius_/zoom,centreY_-radius_/zoom,
			2.*radius_/zoom,2.*radius_/zoom);

	float devX=device_->width()/2;
	float devY=device_->height()/2;

	QRectF targetRect(devX-radius_,devY-radius_,
			2.*radius_,2.*radius_);

	painter_->fillRect(0,0,device_->width(),device_->height(),
			 QBrush(Qt::white));

	sceneRendering=true;
	//scene_->setMagnifierParams(zoom,sourceRect);
	//scene_->render(painter_,targetRect,sourceRect);

	plotScene_->renderForMagnifier(painter_,targetRect,sourceRect);

	sceneRendering=false;

	if(magnifierMode_ == DataMode)
	{
		foreach(QGraphicsItem *item,dataItem_->childItems())
		{
			item->setFlag(QGraphicsItem::ItemHasNoContents);
		}

		QList<QGraphicsItem *> itemList = dataScene_->items(sourceRect, Qt::IntersectsItemBoundingRect);
		foreach(QGraphicsItem *item,itemList)
		{
			item->setFlag(QGraphicsItem::ItemHasNoContents,false);
			//qDebug() << it->childItems().count() << it->parentItem()->data(0);
			//if( it->childItems().count() != 0)
			//	qDebug() << " " << it->childItems().at(0)->childItems().count();
		}

		/*QList<QGraphicsItem *> itemList = dataScene_->items(sourceRect, Qt::IntersectsItemBoundingRect);
		qDebug() << "rendered items:" << itemList.count();
		foreach(QGraphicsItem *it,itemList)
		{
			qDebug() << it->childItems().count() << it->parentItem()->data(0);
			if( it->childItems().count() != 0)
				qDebug() << " " << it->childItems().at(0)->childItems().count();
		}*/

		dataScene_->render(painter_,targetRect,sourceRect);	
	}


	//device_->copy(centreX_-radius_,centreY_-radius_,
	//		2.*radius_,2.*radius_).save("/var/tmp/dummy-user/demo.png");

	//device_->save("/var/tmp/dummy-user/demo.png");
	
	QPainterPath path;
	path.addEllipse(-radius_,-radius_,2.*radius_,2.*radius_);

	painter->setClipPath(path);
	painter->drawImage(QRectF(-radius_,-radius_,2.*radius_,2.*radius_),
			   device_->copy(devX-radius_,devY-radius_,2.*radius_,2.*radius_));
	
	painter->setClipping(false);

}

void MvQMagnifier::renderFrame(QPainter *painter)
{
	QConicalGradient innerGradient(0.,0.,-45.0);
	innerGradient.setColorAt(0.0,QColor(220,220,220));
	innerGradient.setColorAt(0.5,QColor(80,80,80));
	innerGradient.setColorAt(1.0,QColor(220,220,220));	

	QPainterPath innerFrame;	
	createRingSlice(innerFrame,0,360,radius_,radius_+innerFrameWidth_);
	painter->fillPath(innerFrame,innerGradient);

	QConicalGradient outerGradient(0.,0.,-45.0);
	outerGradient.setColorAt(0.0,Qt::darkGray);
	outerGradient.setColorAt(0.2,QColor(150,150,150));
	outerGradient.setColorAt(0.5,Qt::white);
	outerGradient.setColorAt(1.0,Qt::darkGray);

	QPainterPath outerFrame;	
	createRingSlice(outerFrame,0,360,radius_+innerFrameWidth_,radius_+frameWidth_);
	painter->fillPath(outerFrame,outerGradient);

	painter->setBrush(QBrush());
	painter->drawEllipse(QPointF(0.,0.),radius_,radius_);
	painter->drawEllipse(QPointF(0.,0.),radius_+innerFrameWidth_,radius_+innerFrameWidth_);
	painter->drawEllipse(QPointF(0.,0.),radius_+frameWidth_,radius_+frameWidth_);
}

void MvQMagnifier::renderSlider(QPainter *painter)
{
	float rad1, rad2, anStart, anSweep;
	float anStartInner, anEndInner, anSweepInner;
	float an, totalRotation;

	//Panel	
	QPainterPath panel;

	rad1=actSlider_->panelInnerRadius();
	rad2=actSlider_->panelOuterRadius();
	anStart=actSlider_->cellBarStartAngle();
	anSweep=actSlider_->cellBarSweepAngle();
	anStartInner=anStart-(180./M_PI)*10./rad1;
	anEndInner=anStart+anSweep+(180./M_PI)*10./rad1;
	anSweepInner=anEndInner-anStartInner;
	
	panel.moveTo(rad1*cos(anStartInner/180.*M_PI),
		     rad1*sin(anStartInner/180.*M_PI));
	panel.arcTo(-rad2,-rad2,2.*rad2,2.*rad2,-anStart,-anSweep);
	//panel.lineTo(rad1*cos(anEndInner/180.*M_PI),
	//	     rad1*sin(anEndInner/180.*M_PI)));

	panel.arcTo(-rad1,-rad1,2.*rad1,2.*rad1,-anEndInner,anSweepInner);

	QConicalGradient panelGradient(0.,0.,anStartInner);
	panelGradient.setColorAt(0.0,Qt::white);
	//panelGradient.setColorAt(0.2,QColor(150,150,150));
	panelGradient.setColorAt(anSweepInner/360.,Qt::darkGray);
	panelGradient.setColorAt(0.5,QColor(150,150,150));
	panelGradient.setColorAt(1.0,Qt::white);

	//createRingSlice(panel,anStart,anSweep,rad1,rad2);
	//painter->setBrush(QBrush());
	painter->setBrush(panelGradient);
	painter->drawPath(panel);

	//Cells
	QPainterPath cell;

	rad1=actSlider_->cellInnerRadius();
	rad2=actSlider_->cellOuterRadius();
	anStart=-actSlider_->cellSweepAngle();
	anSweep=actSlider_->cellSweepAngle();
	createRingSlice(cell,anStart,anSweep,rad1,rad2);
	
	
	an=360.-actSlider_->cellBarStartAngle();
	painter->rotate(an);
	totalRotation=an;
	for(int i=actSlider_->cellNum()-1 ; i >= 0; i--)
	{
		//qDebug() << slider_->cellColour(i);
		painter->setBrush(actSlider_->cellColour(i));
		painter->drawPath(cell);
		painter->rotate(-anSweep);
		totalRotation+=-anSweep;
	}

	painter->rotate(-totalRotation);

#if 0	
	//Render number panel
	if(mouseInLens_)
	{
		//TEXT PANEL background
		QPainterPath textPanel;
		int alpha=80;
		
		float maxTextWidth=0.;
		for(int i=0; i < actSlider_->cellNum(); i++)
		{
			QString txt=QString::number(actSlider_->factorValue(i));
			float w=painter->fontMetrics().boundingRect(txt).width();
			if(w > maxTextWidth)
				maxTextWidth=w;
		}

	
		float textRad1=actSlider_->panelInnerRadius()-maxTextWidth-8-4;
		float textRad2=actSlider_->panelInnerRadius();
		float textAnStart=actSlider_->cellBarStartAngle()-(180./M_PI)*10./actSlider_->panelInnerRadius();
		float textAnEnd=textAnStart+actSlider_->cellBarSweepAngle()+2.*(180./M_PI)*10./actSlider_->panelInnerRadius();
		float textAnSweep=textAnEnd-textAnStart;
	
		textPanel.moveTo(textRad1*cos(textAnStart/180.*M_PI),
		     textRad1*sin(textAnStart/180.*M_PI));
		textPanel.arcTo(-textRad2,-textRad2,2.*textRad2,2.*textRad2,-textAnStart,-textAnSweep);
		//panel.lineTo(rad1*cos(anEndInner/180.*M_PI),
		//	     rad1*sin(anEndInner/180.*M_PI)));

		textPanel.arcTo(-textRad1,-textRad1,2.*textRad1,2.*textRad1,-textAnEnd,textAnSweep);

		QConicalGradient textPanelGradient(0.,0.,textAnStart);
		textPanelGradient.setColorAt(0.0,QColor(255,255,255,alpha));
		//panelGradient.setColorAt(0.2,QColor(150,150,150));
		textPanelGradient.setColorAt(textAnSweep/360.,Qt::darkGray);
		textPanelGradient.setColorAt(0.5,QColor(150,150,150,alpha));
		textPanelGradient.setColorAt(1.0,QColor(255,255,255,alpha));

		//createRingSlice(panel,anStart,anSweep,rad1,rad2);
		//painter->setBrush(QBrush());
		painter->setBrush(textPanelGradient);
		painter->drawPath(textPanel);

		//Tetx panel text
		an=180.-actSlider_->cellBarStartAngle()-anSweep/2.;
		painter->rotate(an);
		totalRotation=an;
		for(int i=actSlider_->cellNum()-1 ; i >= 0; i--)
		{
			painter->drawText(QPointF(-(rad1-8),0),QString::number(actSlider_->factorValue(i)));
			painter->rotate(-anSweep);
			totalRotation+=-anSweep;
		}
		painter->rotate(-totalRotation);
	}
#endif

	//Handler
	painter->rotate(360.-actSlider_->actCellAngle());
        painter->drawPixmap((actSlider_->cellInnerRadius() + actSlider_->cellOuterRadius())/2.-handlerPixmap_->width()/2.,
		            -handlerPixmap_->height()/2.,
			    *handlerPixmap_);

	//painter->setBrush(Qt::blue);
	//painter->drawEllipse(QPointF((slider_->cellInnerRadius() + slider_->cellOuterRadius())/2.,0),
	//		      slider_->handlerSize()/2.,slider_->handlerSize()/2.);
}



void MvQMagnifier::createRing(QPainterPath& /*path*/,float /*innerRadius*/,float /*outerRadius*/)
{
	//path.arcTo(-outerRadius,-outerRadius,2.*outerRadius,2.*outerRadius,0,360);
	//path.arcTo(-innerRadius,-outerRadius,2.*outerRadius,2.*outerRadius,0,360);

	//path.moveTo(innerRadius*cos(startAngle/180.*M_PI),innerRadius*sin(startAngle/180.*M_PI));
	//path.arcTo(-outerRadius,-outerRadius,2.*outerRadius,2.*outerRadius,-startAngle,-sweepAngle);
	//path.arcTo(-innerRadius,-innerRadius,2.*innerRadius,2.*innerRadius,-(startAngle+sweepAngle),sweepAngle);
}

void MvQMagnifier::createRingSlice(QPainterPath& path,float startAngle,float sweepAngle, float innerRadius,float outerRadius)
{
	path.moveTo(innerRadius*cos(startAngle/180.*M_PI),innerRadius*sin(startAngle/180.*M_PI));
	path.arcTo(-outerRadius,-outerRadius,2.*outerRadius,2.*outerRadius,-startAngle,-sweepAngle);
	path.arcTo(-innerRadius,-innerRadius,2.*innerRadius,2.*innerRadius,-(startAngle+sweepAngle),sweepAngle);
}




void MvQMagnifier::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*o*/, QWidget* /*w*/)
{
	if(sceneRendering)
		return;

	painter->setRenderHint(QPainter::Antialiasing,true);

	//!!!!
	//painter->scale(1.,-1.);

	//renderFrame(painter);

	//painter->scale(1.,-1.);
	render(painter);
	//painter->scale(1.,-1.);

	painter->scale(1.,-1.);
	renderFrame(painter);	
	renderSlider(painter);
}

QRectF MvQMagnifier::boundingRect() const
{
	float r = radius_+ frameWidth_;
	if(r < actSlider_->panelOuterRadius())
		r=actSlider_->panelOuterRadius();

	QRectF f(-r,-r,2.*r,2.*r);
	//qDebug() << "br"; // << f << rect() << mapRectFromParent(rect());
	return f;
}

bool MvQMagnifier::contains(const QPointF &point) const
{
	//qDebug() << "contains" << point;
	bool b=QGraphicsItem::contains(point);
	//qDebug() << "contains" << point << b;
	return b;
}

/*bool MvQMagnifier::sceneEvent(QEvent *event)
{
	//qDebug() << "magnifier event" << event->type();
	return QGraphicsItem::sceneEvent(event);
}*/

void MvQMagnifier::mousePressEventFromView(QMouseEvent* event)
{
	//qDebug() << "magnifier press" << event->pos();
	//qDebug() << identifyPoint(event->pos());
	QPointF pos = mapFromScene(plotView_->mapToScene(event->pos()));

	switch(identifyPoint(pos))
	{
	case LensPoint:
		/*if(event->buttons() & Qt::RightButton)
		{
			changeMagnifierMode();
		}
		else
		{*/
			setSelected(true);
			magnifierAction_=MoveAction;
			dragPos_=pos;
		//}
		//qDebug() << "Lens selected";
		break;
	case FramePoint:
		setSelected(true);
		magnifierAction_=ResizeAction;
		//qDebug() << "Frame selected";
		break; 
	case SliderCellPoint:
		magnifierAction_=NoAction;
		//qDebug() << "Cell selected";
		break;
	case SliderHandlerPoint:
		magnifierAction_=HandlerAction;
		actCellIndexAtHandlerActionStart_=actSlider_->actCellIndex();
		//qDebug() << "Handler selected";
		break;
	default:
		magnifierAction_=NoAction;
		break;
	}
}

void MvQMagnifier::mouseMoveEventFromView(QMouseEvent* event)
{
	//qDebug() << "magnifier move"  << mapToScene(event->pos());
	if((event->buttons() & Qt::LeftButton) == 0)
		return;

	QPointF pos=plotView_->mapToScene(event->pos());
	
	if(magnifierAction_ == MoveAction)
	{
		QPointF dp= mapFromScene(pos)-dragPos_;
		centreX_+=dp.x();
		centreY_+=dp.y();
		setPos(centreX_, centreY_);
		dragPos_=mapFromScene(pos);
		emit positionChanged();
		
	}
	else if(magnifierAction_ == ResizeAction)
	{		
		float dist=sqrt(pow(centreX_-pos.x(),2) + pow(centreY_-pos.y(),2));
	
		//qDebug() << "dist" << dist;

		float maxRadius=(device_->width()<device_->height())?device_->width()/2:device_->height()/2;

		//qDebug() << "maxrad" << maxRadius;		

		//Check if magnifying glass is inside window and size is not too small
		if(dist >= minRadius_ && dist <= maxRadius)				
		{
			radius_=dist;			
		}
		else if(dist < minRadius_) 
		{
			return;
		}
		else if(dist > maxRadius) 
		{
			return;
		}

		prepareGeometryChange();
		actSlider_->setGeometry(radius_);
		update();

	}	
	else if(magnifierAction_ == HandlerAction)
	{
		int index;
		if(actSlider_->shiftHandler(pos.x()-centreX_,pos.y()-centreY_,index))
                {	        		
			actSlider_->setActCellIndex(index);
			reset();
			emit factorChanged();
	 	}
	}	
	
}
void MvQMagnifier::mouseReleaseEventFromView(QMouseEvent* /*event*/)
{
	/*QPointF pos=mapToScene(event->pos());

	if(magnifierAction_ == HandlerAction)
	{		
		if(magnifierMode_ == DataMode)
		{			
			if(actCellIndexAtHandlerActionStart_ != actSlider_->actCellIndex())
			{
				reset();
			}
	 	}
	}*/

	magnifierAction_=NoAction;	
}


void MvQMagnifier::changeMagnifierMode()
{
	prepareForReset();

	if(magnifierMode_ == TextMode)
	{
		magnifierMode_ = DataMode;
	}
	else
	{
		magnifierMode_ = TextMode;
	}

	actSlider_=sliders_[magnifierMode_];
	actSlider_->setGeometry(radius_);

	/*if(magnifierMode_ == DataMode)
	{
		updateMagnifierState();
		update();
	}
	else if(magnifierMode_ == TextMode)
	{
		if(dataScene_ !=0 && dataItem_ != 0)
		{
			dataItem_->clearPlotContents();
			dataScene_->removeItem(dataItem_);
			dataItem_->addToMainScene();
		}	
	}*/

	reset();
}

/*void MvQMagnifier::updateMagnifierState()
{
	if(magnifierMode_ == DataMode)
	{
		float zoom=actSlider_->actFactorValue();						

		if(dataScene_ !=0 && dataItem_ != 0)
		{
			dataScene_->removeItem(dataItem_);
			dataItem_->addToMainScene();
		}

		MgQPlotScene *scene=static_cast<MgQPlotScene*>(scene_);
		scene->updateMagnifier(zoom);
		
		MgQLayoutNode *lnode=scene->findMagnifierLayout();
		if(!lnode) return;

		dataItem_=static_cast<MgQMagnifierLayoutNode*>(lnode);

		scene->removeItem(dataItem_);
		
		if(!dataScene_)
		{
			dataScene_=new QGraphicsScene;
		}
	
		dataScene_->addItem(dataItem_);
	}
}*/

void MvQMagnifier::setActivated(bool flag)
{
	MvQPlotItem::setActivated(flag);

	if(flag)
	{
		reset();
		show();
	}
	else
	{		
		hide();
		prepareForReset();
	}
}


/*void MvQMagnifier::operationBegin()
{
	reset();
	show();
}


void MvQMagnifier::operationEnd()
{
	hide();
	prepareForReset();
}*/

/*!
  \brief prepare resetting the magnifier state

  \sa prepareForReset()
*/
void MvQMagnifier::prepareForReset()
{
	//Clear the garphics contents of the data node
	//remove it from the local scene and add it back to the 
	//main scene

	if(magnifierMode_ == DataMode)
	{
		if(dataScene_ !=0 && dataItem_ != 0)
		{
			dataScene_->removeItem(dataItem_);
			dataItem_->clearPlotContents();
			dataItem_->addToMainScene();
			dataItem_=0;
		}	
	}
}

void MvQMagnifier::reset()
{
	if(magnifierMode_ == DataMode)
	{
		//float zoom=actSlider_->actFactorValue();						

		if(!dataScene_)
		{
			dataScene_=new QGraphicsScene;
			dataItem_=0;
		}
	
		if(dataItem_ != 0)
		{
			dataScene_->removeItem(dataItem_);
			dataItem_->clearPlotContents();
			dataItem_->addToMainScene();
		}

		QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	
		//To be implemented!!!
		//dataItem_=plotScene_->updateMagnifier(zoom); 
		dataItem_=0;

		if(dataItem_)
		{		
			plotScene_->removeItem(dataItem_);
		
			if(!dataScene_)
			{
				dataScene_=new QGraphicsScene;
			}
	
			dataScene_->addItem(dataItem_);
		}

		QApplication::restoreOverrideCursor();
	}

	//???
	update();
}
