// EIKRUBTL.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikrubtl.h>
#include <frmframe.h>

EXPORT_C CEikRubberBand::CEikRubberBand()
    {
    }

EXPORT_C CEikRubberBand::~CEikRubberBand()
    {
    }

EXPORT_C void CEikRubberBand::XorDraw() const
    {
	CWindowGc& gc=SystemGc();
	gc.SetDrawMode(CGraphicsContext::EDrawModeNOTSCREEN);
	gc.SetPenStyle(CGraphicsContext::ESolidPen);
    gc.SetBrushStyle(CGraphicsContext::ENullBrush);
	if (iRubberBandFlags&EDrawAsCircle)
		gc.DrawEllipse(iBandRect);
	else
		gc.DrawRect(iBandRect);
	gc.SetDrawMode(CGraphicsContext::EDrawModePEN);	   
	}

EXPORT_C void CEikRubberBand::XorDrawNow() const
	{
	ActivateGc();
	XorDraw();
	DeactivateGc();
	}

EXPORT_C void CEikRubberBand::Activate(const TPoint& aStartPos, const TRect& aRect, const TInt aFlags)
	{
	SetRectL(aRect);
	iRubberBandFlags=aFlags;
	iAnchorPos=aStartPos;
 	iBandRect=Rect();
	XorDrawNow();
	}

EXPORT_C void CEikRubberBand::NotifyDragPos(const TPoint& aPos)
	{
	const TRect originalBandRect=Rect();
	TPoint validPos=aPos;
	CheckDragPosIsValid(validPos);
	TRect newBandRect=iBandRect;
	TPoint offsetPos(0,0);
	if (iRubberBandFlags&TFrameOverlay::EEdgeLeft && ~iRubberBandFlags&EMaintainAspectDragVert)
		{
		offsetPos.iX=iAnchorPos.iX-originalBandRect.iTl.iX;
		newBandRect.iTl.iX=validPos.iX-offsetPos.iX;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeRight && ~iRubberBandFlags&EMaintainAspectDragVert)
		{
		offsetPos.iX=iAnchorPos.iX-originalBandRect.iBr.iX;
		newBandRect.iBr.iX=validPos.iX-offsetPos.iX;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeTop && ~iRubberBandFlags&EMaintainAspectDragHoriz)
		{
		offsetPos.iY=iAnchorPos.iY-originalBandRect.iTl.iY;
		newBandRect.iTl.iY=validPos.iY-offsetPos.iY;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeBottom && ~iRubberBandFlags&EMaintainAspectDragHoriz)
		{
		offsetPos.iY=iAnchorPos.iY-originalBandRect.iBr.iY;
		newBandRect.iBr.iY=validPos.iY-offsetPos.iY;
		}
	if (iRubberBandFlags&EAllowToFlip && iAnchorPos!=aPos)
		newBandRect=EnclosedRect(iAnchorPos,validPos);
	if (iRubberBandFlags&EMaintainAspect)
		{
		if (~iRubberBandFlags&EMaintainAspectDragVert && newBandRect.Width()!=iBandRect.Width())
			{
			iRubberBandFlags|=EMaintainAspectDragHoriz;
			const TInt newHeight=(newBandRect.Width()*originalBandRect.Height())/originalBandRect.Width();
			if (iRubberBandFlags&TFrameOverlay::EEdgeTop)
				newBandRect.iTl.iY=newBandRect.iBr.iY-newHeight;
			else if (iRubberBandFlags&TFrameOverlay::EEdgeBottom)
				newBandRect.iBr.iY=newBandRect.iTl.iY+newHeight;
			}
		else if (~iRubberBandFlags&EMaintainAspectDragHoriz && newBandRect.Height()!=iBandRect.Height())
			{
			iRubberBandFlags|=EMaintainAspectDragVert;
			const TInt newWidth=(newBandRect.Height()*originalBandRect.Width())/originalBandRect.Height();
			if (iRubberBandFlags&TFrameOverlay::EEdgeLeft)
				newBandRect.iTl.iX=newBandRect.iBr.iX-newWidth;
			else if (iRubberBandFlags&TFrameOverlay::EEdgeRight)
				newBandRect.iBr.iX=newBandRect.iTl.iX+newWidth;
			}
		}
	else if (iRubberBandFlags&EMoveWholeBand)
		{
		offsetPos=iAnchorPos-originalBandRect.iTl;
		newBandRect.iTl=validPos-offsetPos;
		newBandRect.iBr=newBandRect.iTl+originalBandRect.Size().AsPoint();
		}
	if (newBandRect!=iBandRect)
		{
		XorDrawNow();
		iBandRect=newBandRect;
		XorDrawNow();
		}
	}

EXPORT_C void CEikRubberBand::Deactivate()
	{
	XorDrawNow();
	SetRectL(iBandRect);
	iRubberBandFlags=0;
	}

void CEikRubberBand::CheckDragPosIsValid(TPoint& aPos)
	{
	TRect originalBandRect=Rect();
	TPoint offsetPos(0,0);
	if (iRubberBandFlags&TFrameOverlay::EEdgeLeft)
		{
		offsetPos.iX=iAnchorPos.iX-originalBandRect.iTl.iX;
		if (aPos.iX-offsetPos.iX>originalBandRect.iBr.iX-1)
			aPos.iX=originalBandRect.iBr.iX-1+offsetPos.iX;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeRight)
		{
		offsetPos.iX=iAnchorPos.iX-originalBandRect.iBr.iX;
		if (aPos.iX+offsetPos.iX<originalBandRect.iTl.iX+1)
			aPos.iX=originalBandRect.iTl.iX+1-offsetPos.iX;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeTop)
		{
		offsetPos.iY=iAnchorPos.iY-originalBandRect.iTl.iY;
		if (aPos.iY-offsetPos.iY>originalBandRect.iBr.iY-1)
			aPos.iY=originalBandRect.iBr.iY-1+offsetPos.iY;
		}
	if (iRubberBandFlags&TFrameOverlay::EEdgeBottom)
		{
		offsetPos.iY=iAnchorPos.iY-originalBandRect.iBr.iY;
		if (aPos.iY+offsetPos.iY<originalBandRect.iTl.iY+1)
			aPos.iY=originalBandRect.iTl.iY+1-offsetPos.iY;
		}
	}

TRect CEikRubberBand::EnclosedRect(const TPoint &aPointA,const TPoint &aPointB)
	{	// This should put into E32's TRect function
	TRect rect;
	if (aPointB.iX>aPointA.iX)
		{
		rect.iTl.iX=aPointA.iX;
		rect.iBr.iX=aPointB.iX;
		}
	else
		{
		rect.iTl.iX=aPointB.iX;
		rect.iBr.iX=aPointA.iX;
		}
	if (aPointB.iY>aPointA.iY)
		{
		rect.iTl.iY=aPointA.iY;
		rect.iBr.iY=aPointB.iY;
		}
	else
		{
		rect.iTl.iY=aPointB.iY;
		rect.iBr.iY=aPointA.iY;
		}
	rect.iBr+=TPoint(1,1);
	return(rect);
	}

//
//Class CEikRubberLine	  

EXPORT_C CEikRubberLine::CEikRubberLine()
    {
    }

EXPORT_C CEikRubberLine::~CEikRubberLine()
    {
    }

EXPORT_C void CEikRubberLine::XorDraw() const
    {
	CWindowGc& gc=SystemGc();
	gc.SetDrawMode(CGraphicsContext::EDrawModeXOR);
	gc.SetPenColor(TRgb(14*17,14*17,14*17)); // !! fix this
    gc.SetBrushStyle(CGraphicsContext::ENullBrush);
	gc.DrawLine(iAnchorPos,iMovingPos);
	gc.SetDrawMode(CGraphicsContext::EDrawModePEN);	   
	}

EXPORT_C void CEikRubberLine::XorDrawNow() const
	{
	ActivateGc();
	XorDraw();
	DeactivateGc();
	}

EXPORT_C void CEikRubberLine::Activate(const TPoint& aStartPos)
	{
	iAnchorPos=aStartPos;
	iMovingPos=iAnchorPos;
	}

EXPORT_C void CEikRubberLine::NotifyDragPos(const TPoint& aPos)
	{
	if (aPos!=iMovingPos)
		{
		XorDrawNow();
		iMovingPos=aPos;
		XorDrawNow();
		}
	}

EXPORT_C void CEikRubberLine::Deactivate()
	{
	XorDrawNow();
	}
