//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#pragma package(smart_init)

#include "TextButton.h"

////////////////////////////////////////////////////////////////////////////////////
#define PIXEL_EXTERNAL_FRAME       		 1    //外边界大小
#define PIXEL_INTERNAL_FARME       		 1    //内边界大小
#define PIXEL_INTERNAL_BOUND       		 1    //圆角大小
#define PIXLE_TEXT_LEFT_OFFSET           3    //文字左边偏移距离
#define PIXEL_TEXT_X                     Width - 2*PIXLE_TEXT_LEFT_OFFSET

static const COLORREF
			CLR_TXT_NOR             =  RGB( 156, 170, 189 ),
			CLR_TXT_HOT             =  RGB( 201, 214, 229 ),
			CLR_TXT_DIS             =  RGB( 75,  77,  79 ),

			clrFrameExBound         =  RGB(65,70,77),

			clrFrameExNormal        =  RGB(125,128,131),
			clrFrameExEnter         =  RGB(145,156,170),
			clrFrameExDisable		=  RGB(109,114,120),

			clrFrameBoundNormal     =  RGB(68,70,73),
			clrFrameBoundEnter      =  RGB(70,72,76),

			clrFrameNormal          =  RGB(44,46,48),
			clrLineNormal           =  RGB(44,46,48),

			clrRectNormal           =  RGB(74,80,88),
			clrRectDisable 	        =  RGB(100,106,113),

			//角从左到右，从上到下

			clrCapArrowOpenBound[10]=
									{ RGB(50,54,60),RGB(54,58,64),RGB(57,61,67),RGB(58,63,69),
									  RGB(58,63,69),RGB(62,67,74),RGB(64,69,76),
									  RGB(66,71,78),RGB(68,74,81),
									  RGB(71,77,85)},

			clrCapArrowOpenLine[4]  =
									{ RGB(59,64,70),
									  RGB(65,70,77),
									  RGB(69,75,82),
									  RGB(73,78,86)},
			clrExFrameBound[4] =
								  { RGB(81,87,94),
									RGB(94,100,107),
									RGB(113,118,124),
									RGB(126,130,136)
								  },
		clrExFrameBoundDisable[4] =
								  { RGB(77,83,91),
									RGB(86,91,99),
									RGB(98,103,110),
									RGB(105,110,117)
								  };
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TTextButton *)
{
	new TTextButton(NULL);
}
//---------------------------------------------------------------------------
namespace Textbutton
{
	void __fastcall PACKAGE Register()
	{
		TComponentClass classes[1] = {__classid(TTextButton)};
		RegisterComponents(L"Samples", classes, 0);
	}
}
//---------------------------------------------------------------------------
__fastcall TTextButton::TTextButton(TComponent* Owner)
	: TGraphicControl(Owner)
{
	Height      = 25;      //a default Height
	Width       = 75;      //a default Width
	FStateCount = 4; 	   //default state count
	FDown       = false;
	ShowHint    = true;
}

//---------------------------------------------------------------------------
__fastcall TTextButton::~TTextButton(void)
{

}

//---------------------------------------------------------------------------
void __fastcall TTextButton::Paint(void)
{
	if( FDown ) EtatBtn = 2;
	if( !Enabled ) EtatBtn = 3;

	PaintCustomer();
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::MouseDown(System::Uitypes::TMouseButton Button,
													System::Classes::TShiftState Shift, int X, int Y)
{
	TGraphicControl::MouseDown( Button, Shift, X, Y );

	if( Button==mbLeft && Enabled && FStateCount>2){
		EtatBtn = 2; // Pressed

		Paint();
		Refresh();
	}

	TCustomForm * parentForm = GetParentForm( this );
	if( parentForm && parentForm==Application->MainForm ){
		TPoint pt(X,Y);
		pt = ClientToParent( pt, parentForm );
		Application->MainForm->OnMouseDown( NULL, Button, Shift, pt.X, pt.Y );
	}
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::MouseUp(System::Uitypes::TMouseButton Button,
													System::Classes::TShiftState Shift, int X, int Y)
{
	TGraphicControl::MouseUp( Button, Shift, X, Y );

	if( Button==mbLeft && Enabled ){
		if( X>=0 && X<Width && Y>=0 && Y<Height )
			EtatBtn = 1; //Mouse Entered
		else
			EtatBtn = 0; //normal;

		Paint();
		Refresh(); //repaint component
	}
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::CMMouseEnter(Winapi::Messages::TMessage &Msg)
{
	if( Enabled && !ComponentState.Contains(csDesigning) ){
		EtatBtn = 1; // Mouse Entered

		Paint();
		Refresh(); //repainting the component
	}

	if( FOnMouseEnter )
		FOnMouseEnter(this); //if user set a mouse enter procedure then we execute it

}

//---------------------------------------------------------------------------
void __fastcall TTextButton::CMMouseLeave(Winapi::Messages::TMessage &Msg)
{
	if( Enabled && !ComponentState.Contains(csDesigning) ) {
		EtatBtn = 0; //Normal

		Paint();
		Refresh(); //repainting the component
	}

	if( FOnMouseLeave )
		FOnMouseLeave(this); //if user set a mouse leave procedure then we execute it
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::Click(void)
{
	TCustomForm * parentForm = GetParentForm( this );
	if( parentForm ){
		parentForm->ModalResult = FModalResult;
	}

	TGraphicControl::Click();
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetEnabled(bool Value)
{
	if(FStateCount<4) //can't be disable
		Value = true;

	TGraphicControl::SetEnabled(Value);

	if( Enabled )
		EtatBtn = 0;
	else
		EtatBtn = 3;

	Paint();
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetStateCount( int count )
{
	if( count>4 ) count = 4;
	if( count<2 ) count = 2;

	FStateCount = count;
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetDown(bool value)
{
	if( FStateCount<3 )
		value = false;

	FDown = value;
	if( FDown==False )
		EtatBtn = 0; //is the mouse down is false then we reset the component state to normal

	Paint();
	Refresh(); //we repaint the componet)
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetFontSize( int value )
{
	Canvas->Font->Size = value;
	Paint();
	Refresh();
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetFontName(System::Uitypes::TFontName value)
{
	Canvas->Font->Name = value;
	Paint();
	Refresh();
}

//---------------------------------------------------------------------------
void __fastcall TTextButton::SetTextFont(String name, int size)
{
	Canvas->Font->Name = name;
	Canvas->Font->Size = size;
	Paint();
	Refresh();
}

//---------------------------------------------------------------------------
void  __fastcall TTextButton::PaintCustomer(void)
{
	TRect rectDraw = GetClientRect();
	TRect tmpRet   = rectDraw;

	//================画外边框
	if(EtatBtn == 0){
		Canvas->Brush->Color = clrFrameExNormal;
		Canvas->Pen->Color   = clrFrameExNormal;
	}else if(EtatBtn == 3){
		Canvas->Brush->Color = clrFrameExDisable;
		Canvas->Pen->Color   = clrFrameExDisable;
	}else {
 		Canvas->Brush->Color = clrFrameExEnter;
		Canvas->Pen->Color   = clrFrameExEnter;
	}


	int X,Y;
	//上
	Y = 0;
	X = PIXEL_EXTERNAL_FRAME ;
	Canvas->MoveTo( X, Y );
	X = Width - PIXEL_EXTERNAL_FRAME ;
	Canvas->LineTo( X, Y );
	//下
	Y = Height - PIXEL_EXTERNAL_FRAME ;
	X = PIXEL_EXTERNAL_FRAME ;
	Canvas->MoveTo( X, Y );
	X = Width - PIXEL_EXTERNAL_FRAME ;
	Canvas->LineTo( X, Y );
	//左
	X = 0 ;
	Y = PIXEL_EXTERNAL_FRAME ;
	Canvas->MoveTo( X, Y );
	Y = Height - PIXEL_EXTERNAL_FRAME ;
	Canvas->LineTo( X, Y );
	//右
	X = Width - PIXEL_EXTERNAL_FRAME ;
	Y = PIXEL_EXTERNAL_FRAME ;
	Canvas->MoveTo( X, Y );
	Y = Height - PIXEL_EXTERNAL_FRAME ;
	Canvas->LineTo( X, Y );

	//画外边框圆角
	int iLPixl, iTPixl, iRPixl, iBPixl ;
	TRect tmpRetPic = rectDraw; //画内部区域渐变图像
	int iDistant = 1;   //画点right和bottom - 1
	for(int i=0;i<4;i++)
	{
		//角 4*4  上左右    下左右
		iLPixl   = tmpRetPic.Left + i;
		iTPixl   = tmpRetPic.Top;
		iRPixl   = tmpRetPic.Right - i - iDistant;
		iBPixl   = tmpRetPic.Bottom - iDistant;

		if(EtatBtn == 3)
			Canvas->Pen->Color   = clrExFrameBoundDisable[i];
		else
			Canvas->Pen->Color   = clrExFrameBound[i];
		Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
		Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
		Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
		Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;

		if(i>0){  //每个角对称
			iLPixl   = tmpRetPic.Left;
			iTPixl   = tmpRetPic.Top + i;
			iRPixl   = tmpRetPic.Right - iDistant;
			iBPixl   = tmpRetPic.Bottom - i - iDistant;
			Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
			Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
			Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
			Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
		}
	}

	//=================画内边框

	//画圆角
	if(EtatBtn == 0) Canvas->Pen->Color   = clrFrameBoundNormal;
	else  	         Canvas->Pen->Color   = clrFrameBoundEnter;


	tmpRet.Top   = PIXEL_EXTERNAL_FRAME;

	tmpRet.left  = PIXEL_EXTERNAL_FRAME;
	Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;

	tmpRet.left  = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;

	//////////////
	tmpRet.Top   = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;

	tmpRet.left  = PIXEL_EXTERNAL_FRAME;
	Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;

	tmpRet.left  = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->Pixels[tmpRet.left][tmpRet.top] = Canvas->Pen->Color;

	//画线
	Canvas->Pen->Color   = clrFrameNormal;

//	int X,Y;
	//上
	Y = PIXEL_EXTERNAL_FRAME;
	X = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	Canvas->MoveTo( X, Y );
	X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->LineTo( X, Y );
	//下
	Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	X = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	Canvas->MoveTo( X, Y );
	X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->LineTo( X, Y );
	//左
	X = PIXEL_EXTERNAL_FRAME ;
	Y = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	Canvas->MoveTo( X, Y );
	Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->LineTo( X, Y );
	//右
	X = Width - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Y = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	Canvas->MoveTo( X, Y );
	Y = Height - PIXEL_EXTERNAL_FRAME - PIXEL_INTERNAL_FARME;
	Canvas->LineTo( X, Y );

	//==============画内部区域
	if(3 == EtatBtn){
		Canvas->Brush->Color = clrRectDisable;
		Canvas->Pen->Color   = clrRectDisable;
	}else{
		Canvas->Brush->Color = clrRectNormal;
		Canvas->Pen->Color   = clrRectNormal;
	}

	tmpRet.Left   = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	tmpRet.Top    = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
	tmpRet.Right  = Width - tmpRet.Left;
	tmpRet.Bottom = Height - tmpRet.Top;

	Canvas->Rectangle(tmpRet.Left,  tmpRet.Top,
					  tmpRet.Right, tmpRet.Bottom);
	if(3 != EtatBtn)
	{
		if(2 == EtatBtn) // down
		{
			tmpRetPic   = rectDraw; //画内部区域渐变图像
			iDistant      = PIXEL_EXTERNAL_FRAME + PIXEL_INTERNAL_FARME;
			tmpRetPic.Left   +=  iDistant;
			tmpRetPic.Top    +=  iDistant;
			tmpRetPic.Right  -=  iDistant;
			tmpRetPic.Bottom -=  iDistant;

			iDistant = 1;   //画点right和bottom - 1

			int iTmpAdd = 0;//clrCapArrowOpenBound 当前位置
			for(int i=0; i<4; i++)
			{
				//边线
				Canvas->Brush->Color = clrCapArrowOpenLine[i];
				Canvas->FrameRect(tmpRetPic);

				int iadd = 0;//clrCapArrowOpenBound 当前位置增加
				for(int j=0; j<4-i; j++) {

					//角 4*4  上左右    下左右
					iLPixl   = tmpRetPic.Left + j;
					iTPixl   = tmpRetPic.Top;
					iRPixl   = tmpRetPic.Right - j - iDistant;
					iBPixl   = tmpRetPic.Bottom - iDistant;

					Canvas->Pen->Color   = clrCapArrowOpenBound[iTmpAdd+j];
					Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
					Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
					Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
					Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;

					if(j>0){  //每个角对称
						iLPixl   = tmpRetPic.Left;
						iTPixl   = tmpRetPic.Top + j;
						iRPixl   = tmpRetPic.Right - iDistant;
						iBPixl   = tmpRetPic.Bottom - j - iDistant;
						Canvas->Pixels[iLPixl][iTPixl] = Canvas->Pen->Color;
						Canvas->Pixels[iRPixl][iTPixl] = Canvas->Pen->Color;
						Canvas->Pixels[iLPixl][iBPixl] = Canvas->Pen->Color;
						Canvas->Pixels[iRPixl][iBPixl] = Canvas->Pen->Color;
					}

					iadd++;
				}

				iTmpAdd += iadd;

				tmpRetPic.Left   += iDistant;
				tmpRetPic.Top    += iDistant;
				tmpRetPic.Right  -= iDistant;
				tmpRetPic.Bottom -= iDistant;
			}
		}
	}

	PaintCustomerText();
}

//---------------------------------------------------------------------------
void  __fastcall TTextButton::PaintCustomerText(void)
{
	int X,Y;
	if( !Text.IsEmpty() ){
		if( EtatBtn==0 ){
			Canvas->Font->Color = CLR_TXT_NOR;
		}
		else if( EtatBtn==3 ){
			Canvas->Font->Color = CLR_TXT_DIS;
		}
		else{
			Canvas->Font->Color = CLR_TXT_HOT;
		}

		Canvas->Brush->Style  = bsClear;
		String strText        = FText;
		TSize size            = Canvas->TextExtent( strText );
		int   nLen            = strText.Length();

		if( size.Width > PIXEL_TEXT_X)
		{
			nLen  = nLen*(PIXEL_TEXT_X)/size.Width;
			nLen -= 1;

			if(nLen <= 0){
				strText  = strText.SubString(0, 1);
			}else{
				strText  = strText.SubString(0, nLen);
				strText += "..";
			}

			size  = Canvas->TextExtent( strText );
		}

		X         = PIXLE_TEXT_LEFT_OFFSET + ( PIXEL_TEXT_X - size.Width )/2;
		Y         = ( Height -size.Height )/2;

		Canvas->TextOut( X, Y, strText );
	}
}
//---------------------------------------------------------------------------
