// -------------------------------------------------------------------- //
// FILE 		: DragAndDrop.cpp										//
// DATE 		: 15/03/2004											//
// AUTOR		: Aymeric							//
// DESCRIPTION  : class DragAndDrop										//
// -------------------------------------------------------------------- //



#include <vcl.h>
#include "DragAndDrop.h"


// -------------------------------------------------------------------- //
// TDragAndDrop() constructor											//
// in  : the form, the bitmap picture									//
// out : nothing														//
// -------------------------------------------------------------------- //

TDragAndDrop::TDragAndDrop(TForm *DestForm, Graphics::TBitmap *CleanBackground)
{
	mpDestForm=DestForm;
	// -- we save a copy of the original background
	mpbmpBackgroundCopy=CleanBackground;
	// -- no dragging for the moment, so mISDragging is false
	mIsDragging=false;
	mPostingMessages=true;
}


// -------------------------------------------------------------------- //
// ~TDragAndDrop() destructor											//
// in  : 																//
// out : 																//
// -------------------------------------------------------------------- //

TDragAndDrop::~TDragAndDrop()
{
	// -- I don't need to do a 'new', so I don't need to delete...
	//delete mpbmpBackgroundCopy;
	//delete mpbmpBlit;
	//delete mpbmpBackgroundSave;
	//delete mpDestForm;
}


// -------------------------------------------------------------------- //
// GetBlitPos() return the current position of the blit					//
// in  : nothing														//
// out : a point with the blit's coordinates							//
// -------------------------------------------------------------------- //

TPoint TDragAndDrop::GetBlitPos()
{
        return(Point(mrectBlitPos.Left,mrectBlitPos.Top));
}


// -------------------------------------------------------------------- //
// StartDragging() initialize proprieties to start the drag				//
// in  : mouse's coordonates, blit's coordonates, blit's bitmap and		//
//		 three options													//
// out : nothing														//
// -------------------------------------------------------------------- //

void TDragAndDrop::StartDragging(int X,int Y, TPoint ptBlitPos, Graphics::TBitmap *bmpBlitToMove, bool CursorRelative, bool ShowBlit, bool Transparent)
{
	mpbmpBlit=bmpBlitToMove;
	// -- we calculate the distance between the mouse's coordonates and
	// the blit position
	mCursorDiff.x=X-ptBlitPos.x;
	mCursorDiff.y=Y-ptBlitPos.y;
	mrectBlitPos=Rect(ptBlitPos.x,ptBlitPos.y,ptBlitPos.x+mpbmpBlit->Width,ptBlitPos.y+mpbmpBlit->Height);
	mrectBlitSize=mrectBlitPos;
	// -- we start the dragging so mIsDragging becomes true
	mIsDragging=true;
	mpbmpBlit->Transparent=Transparent;
	mpbmpBackgroundSave=mpbmpBackgroundCopy;
}


// -------------------------------------------------------------------- //
// MoveTo()	move the current blit to the coordonates in parameters		//
// in  : coordonates of destination and an option (to place the blit)	//
// out : nothing														//
// -------------------------------------------------------------------- //

void TDragAndDrop::MoveTo(TPoint Dest, bool CursorRelative)
{
	if (CursorRelative)
	{
		// -- if the CursorRelative is true the blit follows the mouse
		int X=Dest.x-mCursorDiff.x;
		int Y=Dest.y-mCursorDiff.y;
		mpDestForm->Canvas->CopyRect(mrectBlitPos,mpbmpBackgroundSave->Canvas,mrectBlitPos);
		mpDestForm->Canvas->Draw(X,Y,mpbmpBlit);
		mrectBlitPos=Rect(X,Y,X+mpbmpBlit->Width,Y+mpbmpBlit->Height);
	}
	else
	{
		mrectBlitPos=Rect(Dest.x,Dest.y,Dest.x+mpbmpBlit->Width,Dest.y+mpbmpBlit->Height);
		mpDestForm->Canvas->CopyRect(mrectBlitPos,mpbmpBackgroundSave->Canvas,mrectBlitPos);
		mpDestForm->Canvas->Draw(Dest.x,Dest.y,mpbmpBlit);
	}
}


// -------------------------------------------------------------------- //
// EndDragging() stop the dragging										//
// in  : an option (a boolean to show the blit)							//
// out : nothing														//
// -------------------------------------------------------------------- //

void TDragAndDrop::EndDragging(bool ShowBlit)
{
	mIsDragging=false;
	mpbmpBackgroundSave->Canvas->CopyRect(Rect(0,0,mpDestForm->Width,mpDestForm->Height),mpDestForm->Canvas,Rect(0,0,mpDestForm->Width,mpDestForm->Height));
}


// -------------------------------------------------------------------- //
// SlideBlit() move a blit from a source coordonates to a destination	//
// in  : source's coordonates, destination's coordonates, blit's bitmap //
//		 options (speed, resolution)									//
// out : nothing														//
// -------------------------------------------------------------------- //

void TDragAndDrop::SlideBlit(int SourceX, int SourceY,int DestX, int DestY, Graphics::TBitmap *bmpBlitToMove, int Speed, int Res)
{
	StartDragging(SourceX,SourceY,Point(SourceX,SourceY),bmpBlitToMove);
	if (Res==0) Res=1;

	int ResX=Res,ResY=Res;

	// -- ResX and ResY are used to move the blit in the correct place in
	// the 2 dimensions

	if ( SourceX > DestX ) ResX=-ResX;
	if ( SourceY > DestY ) ResY=-ResY;

	while ( SourceX != DestX || SourceY != DestY )
	{
		if (mPostingMessages) Application->ProcessMessages();

		SourceX = SourceX + ResX;
		SourceY = SourceY + ResY;

		if ( (SourceX < DestX) && (ResX < 0) ) SourceX=DestX;
		else if ( (SourceX > DestX) && (ResX > 0) ) SourceX=DestX;
		if ( (SourceY < DestY) && (ResY < 0) ) SourceY=DestY;
		else if ( (SourceY > DestY) && (ResY > 0) ) SourceY=DestY;

		MoveTo(Point(SourceX,SourceY),true);
		Sleep(Speed);
	}
	mpDestForm->Canvas->CopyRect(mrectBlitPos,mpbmpBackgroundSave->Canvas,mrectBlitPos);
	EndDragging();

}


// -------------------------------------------------------------------- //
// SlideBlit() the same function that before but with different params	//
// in  : the coordonates are in TPoint									//
// out : nothing														//
// -------------------------------------------------------------------- //

void TDragAndDrop::SlideBlit(TPoint Source,TPoint Dest, Graphics::TBitmap *bmpBlitToMove, int Speed, int Res)
{
	SlideBlit(Source.x, Source.y, Dest.x, Dest.y, bmpBlitToMove, Speed, Res);
}

