//	Name:	BottomBorder.cpp
//			Ported from Delphi code into C++
//
//	Date:	woensdag 12 mei 2004, 18:22:32	
//
//	Note:	This file cannot be compiled in this state.
//
//	List of changes:
//			- (1) Initial release (AV, 12-5-2004, 18:24)
//
//	(c) copyright Andreas Verhoeven 2004
//	Do not modify, reproduce or use this file without my permission!
//

//////////////////////////////////////////////////////////////////
// GDIPLUS HELPER FUNCTIONS

//This function draws a Gdiplus::Bitmap to a layered window
UINT BitmapIntoLayeredWindow(HWND hWnd, Bitmap& bmp)
{
	HDC screenDC( GetDC(0) );

	POINT sourcePos = {0};
	HDC sourceDC( CreateCompatibleDC(screenDC) );

	HBITMAP bufferBitmap = {0};
	bmp.GetHBITMAP(0, bufferBitmap);

	HBITMAP oldBmpSelInDC ( SelectObject(sourceDC, bufferBitmap) );

	POINT pos	= {Left, Top};
	SIZE  size	= {newWidth, newHeight};

	BLENDFUNCTION blendFunction = {0};
	blendFunction.blendOp = AC_SRC_OVER;
	blendFunction.SourceConstantAlpha = 255;
	blendFunction.AlphaFormat = AC_SRC_ALPHA;

	COLORREF colorKey( RGB(255,0,255) );
	DWORD flags( ULW_ALPHA);
	
	UINT res = UpdateLayeredWindow(hWnd, screenDC,
					&pos, & size,
					sourceDC, &sourcePos,
					colorKey, &blendFunction, flags
				);

	SelectObject(sourceDC, oldBmpSelInDC);
	DeleteObject(bufferBitmap);
	DeleteDC(sourceDC);
			
	ReleaseDC(0, screenDC);

	return res;
}
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
// CLASS DEFINITION
class BottomBorder
{
	private:
		HWND handle;				// handle to this borders window
		Parent& parent;				// reference to parent-object.
									// the parent-object keeps the main-window
									// properties and the 'global' properties.
									// everything is relative to the main-window.


		POINT begP;					// keeps track of current mouse-pos 
									// when resizing
		int resizeBorder1;			// the upper-border for the area where
									// resizing can be done
		int resizeBorder2;			// idem
		const UINT resizeTimerId;	// timer-constant used with SetTimer()

	public:
		BottomBorder(Parent& parent);

		void ReadSkinInfo(const TCHAR* ini);
		void Redraw(int newWidth, int newHeight) const;

		void onMouseMove(POINT& p);
		void onResizeTimer();
		void onMouseDown(WPARAM keys, POINT& p)
		void onMouseUp(WPARAM keys, POINT& p)
};
//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
// CLASS IMPLEMENTATION
const UINT BottomBorder::resizeTimerId = 30303; // random constant


BottomBorder::BottomBorder(Parent& parent) :
 parent(parent),
 begP(0),
 resizeBorder1(0),
 resizeBorder2(0)
// post: An BottomBorder object has been created
{

}

void BottomBorder::ReadSkinInfo(const TCHAR* ini)
// pre:  ini is not NULL
// post: the skins information has been read
{
	if(!ini) // Assert.pre(ini != NULL);
		return;

	resizeBorder1 = GetPrivateProfileInt(_T("Bottom"),_T("ResizeBorder1"),0,ini);
	resizeBorder2 = GetPrivateProfileInt(_T("Bottom"),_T("ResizeBorder2"),0,ini);
}

void BottomBorder::Redraw(int newWidth, int newHeight) const
// post: the border has been redrawn
{
	std::wstring prefix(L"");

	if (!Parent.isActive())
		prefix = L"inactive_";

	Bitmap buffer(newWidth,newHeight);
	Graphics g(&buffer);

	std::wstring fileName(Parent.GetSkinFolder() + prefix + L"bottom.png");
	Bitmap img(wstring.c_str() );

	TextureBrush brush(&img);

	if(img.GetWidth() > 0)
		brush.ScaleTransform(newWidth / img.GetWidth(), 1.0 );

	Rect r(0, 0, newWidth, newHeight);
	g.FillRectangle(brush,&r);

	BitmapIntoLayeredWindow(Handle,buffer);
}

void BottomBorder::onMouseMove(POINT& p)
// post: OnMouseMov event has been handled
{
	if( p.y > resizeBorder1 && y < resizeBorder2 )
			SetCursor( LoadCursor(0,IDC_SIZENS) );
	else
			SetCursor( LoadCursor(0, DC_ARROW) );
}

void BottomBorder::onMouseDown(WPARAM keys, POINT& p)
// post: OnMouseDown event has been handled
{
	if( p.y > resizeBorder1 && y < resizeBorder2 )	
	{
		begP = p;
		SetTimer(Handle,resizeTimerId,1,0);
	}
}

void BottomBorder::onResizeTimer()
// post:  resize-timer event has been handled
{
	POINT curPos = {0};
	GetCursorPos(&curPos);

	newHeight = Parent.Height - (begP.y - curPos.y);
	begP = curPos;

	parent.Redraw(parent.getLeft(), parent.getTop(), parent.getWidth(), newHeight);

}

void BottomBorder::onMouseUp(WPARAM keys, POINT& p)
// post: OnMouseUp event has been handled
{
	KillTimer(Handle,resizeTimerId);
}
//////////////////////////////////////////////////////////////////