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

#ifndef ComboBoxComponentH
#define ComboBoxComponentH

#include <vcl.h>
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.Imaging.pngimage.hpp>
#include <Vcl.Imaging.pnglang.hpp>
#include <Vcl.Graphics.hpp>
//---------------------------------------------------------------------------
class TDropListScrollBar;
class TComboBoxItem;
class TDropListView;
class CBCapButton;
//---------------------------------------------------------------------------
/* 定义下拉列表项点击事件 */
typedef void __fastcall (__closure *TItemClickEvent)(TComboBoxItem* Sender, int Index);

/* 下拉列表框显示风格 */
enum DECLSPEC_DENUM TComboBoxMode : unsigned char {cbShowUp, cbShowDown};
//typedef System::Set<ComboBox_Mode, ComboBox_Mode::cbShowUp, ComboBox_Mode::cbShowDown> TComboBoxMode;
/* 定义下拉列表框变化事件 */
typedef void __fastcall (__closure *TComboBoxChangeEvent)(TComboBoxItem* Sender, int Index);

/**************************************************************************************************/
/**************************************************************************************************/
class  TDropListScrollBar : public TScrollBar
{
private:
//	int m_nTileHeight,   //add by tj 2013/11/18
	int	m_nThumbHeight,
		m_nThumbTop,
		m_nPreThumbTop,
		m_nDragPos,
		m_nDragPoint,
		m_iClicked,
		m_iHitPrev,
		m_nMax,
		m_nMin,
		m_nPos,
		m_nPage,
		m_nTrackPos;

	bool m_bPause,
		m_bNotify,
		m_bDrag,
		m_bTrace;

	TBitmap *u_pPicLineUp,
			*u_pPicLineDown;

	TTimer *m_pTimer;
	TCanvas *m_pCanvas;

	int HitTest( int X, int Y );
	void CalcThumbHeight();
	void CalcThumbTop();
	void DrawArrow( int iDirection, int iState );
	void DrawThumb( int iState, bool bEraseBk, int iPageUD=-1 );

	void __fastcall TimerProc(TObject* Sender);

	MESSAGE void __fastcall WMPaint(Winapi::Messages::TWMPaint &Message);
	MESSAGE void __fastcall WMLButtonDown(TWMMouse &Message);
	MESSAGE void __fastcall WMLButtonUp(TWMMouse &Message);
	MESSAGE void __fastcall WMLButtonDblClk(TWMMouse &Message);
	MESSAGE void __fastcall WMRButtonDown(TWMMouse &Message);  //add by tj 2013/11/18
	MESSAGE void __fastcall WMRButtonUp(TWMMouse &Message);    //add by tj 2013/11/18
	MESSAGE void __fastcall WMMouseMove(TWMMouse &Message);
//	MESSAGE void __fastcall CMMouseLeave(TMessage &Message);   //add by tj 2013/11/25 12:35
	MESSAGE void __fastcall SBMSetScrollInfo(TMessage &Message);
	MESSAGE void __fastcall SBMGetScrollInfo(TMessage &Message);

	BEGIN_MESSAGE_MAP
		MESSAGE_HANDLER(WM_PAINT, TWMPaint, WMPaint)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, TWMLButtonDown, WMLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONUP, TWMLButtonUp, WMLButtonUp)
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, TWMLButtonDblClk, WMLButtonDblClk)
		MESSAGE_HANDLER(WM_RBUTTONDOWN, TWMRButtonDown, WMRButtonDown)
		MESSAGE_HANDLER(WM_RBUTTONUP, TWMRButtonUp, WMRButtonUp) //add by tj 2013/11/18
		MESSAGE_HANDLER(WM_MOUSEMOVE, TWMMouseMove, WMMouseMove) //add by tj 2013/11/18
//		MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)   //add by tj 2013/11/25 12:35
		MESSAGE_HANDLER(SBM_SETSCROLLINFO, TMessage, SBMSetScrollInfo)
		MESSAGE_HANDLER(SBM_GETSCROLLINFO, TMessage, SBMGetScrollInfo)
	END_MESSAGE_MAP(TScrollBar)

protected:
	virtual void __fastcall PaintWindow(HDC DC);

public:
	TWinControl	*m_pWndCtrl;
	bool m_bAction;

	__fastcall virtual TDropListScrollBar(System::Classes::TComponent* AOwner);
	__fastcall ~TDropListScrollBar();

	void __fastcall CMMouseLeave(TObject *Sender); //add by tj 2013/11/25 12:35

	bool IsDraging(){ return m_bDrag; };
	void __fastcall SetPosition(int Value, bool bRedraw=true);
	void __fastcall SetPageSize(int Value, bool bRedraw=true);
	void __fastcall SetRange(int AMin, int AMax, bool bRedraw=true);
	void __fastcall GetScrollRange(int* nMin, int* nMax);
	int  __fastcall GetScrollPos();
	int  __fastcall GetPageSize();
};
/**************************************************************************************************/   
/**************************************************************************************************/
class TComboBoxItem : public TObject
{
private:
	int 			FTag;
	String  		FCaption;
	TItemClickEvent FOnItemClick;

	void __fastcall SetCaption(String Caption);

public:
	__fastcall TComboBoxItem(String Caption, TItemClickEvent OnItemClick);

	void __fastcall DrawItem(TCanvas *Canvas, TRect Rect, bool Selected);

__published:
	__property String Caption = {read = FCaption, write = FCaption};
	__property int Tag = {read = FTag, write = FTag};
	__property TItemClickEvent OnItemClicked = {read = FOnItemClick, write = FOnItemClick};
};
// ---------------------------------------------------------------------------
// 			TDropListView
// ---------------------------------------------------------------------------
class TDropListView : public TWinControl
{
private:
	TNotifyEvent 	FOnHide,		// 下拉列表隐藏事件
    				FOnShow;		// 下拉列表显示事件

             int    FItemHeight,
             		FItemWidth,
                    FShowItemsCount,
                    FDefItemIndex;

	TControlCanvas  *m_Canvas;
    TList			*m_ItemRectList,
    				*m_ItemList;

    TDropListScrollBar *m_ScrollBar;

    HWND m_pActiveWnd;

    int m_BeginIndex,
        m_EndIndex,
        m_CurrentItemIndex,
        m_RealShowCount,
        m_MouseX,
        m_MouseY;

    void __fastcall CreateScrollBar();

    void __fastcall DoItemsCountChange();
    void __fastcall DoItemClicked(int Index);
    void __fastcall DoItemSelect(int Index);
    void __fastcall DoKeyUpDown(int Index);
    void __fastcall DoShowItemsChange();

    int __fastcall CalcListHeight();
	int __fastcall GetItemsCount();
    TRect *__fastcall GetItemRect(int Index);

    void __fastcall SetShowItemsCount(int Value);

    MESSAGE void __fastcall WMEraseBkgnd(TWMEraseBkgnd &Message);
    MESSAGE void __fastcall WMKeyDown(TWMKeyDown &Message);
    MESSAGE void __fastcall WMKillFocus(TMessage &Message);
    MESSAGE void __fastcall WMLButtonDown(TWMLButtonDown &Message);
    MESSAGE void __fastcall WMMouseWheel(TWMMouseWheel &Message);
    MESSAGE void __fastcall WMPaint(TWMPaint &Message);
    MESSAGE void __fastcall WMSetFocus(TMessage &Message);
    MESSAGE void __fastcall WMVScroll(TWMScroll &Message);

    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_ERASEBKGND, TWMEraseBkgnd, WMEraseBkgnd)
        MESSAGE_HANDLER(CN_KEYDOWN, TWMKeyDown, WMKeyDown)
        MESSAGE_HANDLER(WM_KILLFOCUS, TMessage, WMKillFocus)
        MESSAGE_HANDLER(WM_LBUTTONDOWN, TWMLButtonDown, WMLButtonDown)
        MESSAGE_HANDLER(WM_MOUSEWHEEL, TWMMouseWheel, WMMouseWheel)
        MESSAGE_HANDLER(WM_PAINT, TWMPaint, WMPaint)
        MESSAGE_HANDLER(WM_SETFOCUS, TMessage, WMSetFocus)
        MESSAGE_HANDLER(WM_VSCROLL, TWMScroll, WMVScroll)
	END_MESSAGE_MAP(TWinControl)

protected:
	virtual void __fastcall CreateParams(TCreateParams &Params);
	virtual void __fastcall CreateWnd();
    virtual void __fastcall PaintWindow(HDC DC);

    DYNAMIC void __fastcall MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y);
    DYNAMIC void __fastcall MouseMove(TShiftState Shift, int X, int Y);
    DYNAMIC void __fastcall MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y);

public:
	__fastcall TDropListView(TComponent *Owner);
    __fastcall ~TDropListView();
	void __fastcall AddItem(TComboBoxItem* Item);
    void __fastcall Clear();
	TComboBoxItem *__fastcall GetItem(int Index);
    void __fastcall Hide();
    void __fastcall RemoveItem(int Index);
    void __fastcall ScrollPos(int Pos);
	void __fastcall Show();
	void __fastcall SetFontSize(int sz);
	void __fastcall SetFont(String name, int sz);

__published:
	__property int ListHeight = {read = CalcListHeight};
	__property int ItemHeight = {write = FItemHeight, read = FItemHeight, default = 16};

	__property TNotifyEvent OnHide = {write = FOnHide, read = FOnHide};
    __property TNotifyEvent OnShow = {write = FOnShow, read = FOnShow};

    __property int ShowItemsCount = {write = SetShowItemsCount, read = FShowItemsCount};

    __property int DefItemIndex = {read = FDefItemIndex, write = FDefItemIndex};
    __property int ItemsCount = {read = GetItemsCount};
};
/**************************************************************************************************/
/**************************************************************************************************/
class CBCapButton : public TGraphicControl
{
public:
		enum TModalResult{
			mrNone   = System::Int8(0x0),
			mrOk     = System::Int8(0x1),
			mrCancel = System::Int8(0x2),
			mrAbort  = System::Int8(0x3),
			mrRetry  = System::Int8(0x4),
			mrIgnore = System::Int8(0x5),
			mrYes    = System::Int8(0x6),
			mrNo     = System::Int8(0x7),
			mrClose  = System::Int8(0x8),
			mrHelp   = System::Int8(0x9),
			mrTryAgain = System::Int8(0xa),
			mrContinue = System::Int8(0xb),
			mrAll      = System::Int8(0xc),
			mrNoToAll  = System::Int8(0xd),
			mrYesToAll = System::Int8(0xe)
		};

private:
		COLORREF
				clrFrameExNormal,
				clrFrameExEnter,
				clrFrameExDisable,
				clrFrameNormal,
				clrLineNormal,
				clrRectNormal,
				clrRectDisable,
				clrCapArrowOpenBound[10],
				clrCapArrowOpenLine[4],
				clrExFrameBound[4],
				clrExFrameBoundDisable[4];

		TColor FBorderColor;
		TColor FInterFrameColor;
		TColor FInterColor;

		void __fastcall IniColor(int nstate);
		COLORREF __fastcall TransformColor(COLORREF icolor, int nNum=0, bool bplus=true);
		void __fastcall SetBorderColor(TColor iBorderColor);
		void __fastcall SetInterFrameColor(TColor iInterFrameColor);
		void __fastcall SetInterColor(TColor iInterColor);

		TNotifyEvent FOnMouseEnter;//on mouse enter notify event
		TNotifyEvent FOnMouseLeave;//on mouse leave notify event

        String FCaption;
//		System::Uitypes::TModalResult FModalResult;
		TModalResult FModalResult;

        void __fastcall SetCaption(String Value);

		MESSAGE void __fastcall CMMouseEnter(Winapi::Messages::TMessage &Msg); // to know when mouse is entered
		MESSAGE void __fastcall CMMouseLeave(Winapi::Messages::TMessage &Msg); // to know when mouse is leaved

		BEGIN_MESSAGE_MAP
			MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
			MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
		END_MESSAGE_MAP(TGraphicControl)

protected:
		bool FEnablePNG; //是否加载了png格式图片背景
		bool FDown; // value to know if we painting  mouse down
		int  EtatBtn; // 0=Normal 1=Mouse entered 2=Pressed 3=Disabled
		int  FStateCount;
		Vcl::Imaging::Pngimage::TPngImage *FPngImg; //our 4 states image


		DYNAMIC void __fastcall MouseDown(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y);
		DYNAMIC void __fastcall MouseUp(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y);
		virtual void __fastcall SetEnabled(bool Value);

public:

	__fastcall virtual CBCapButton(System::Classes::TComponent* AOwner);
	__fastcall virtual ~CBCapButton(void);

	void __fastcall SetStateCount( int count );
	void __fastcall SetPngImg(Vcl::Imaging::Pngimage::TPngImage *value); // we set the png image
	void __fastcall SetDown(bool value); // to know if mouse is down or not
	void __fastcall SetEnablePNG(bool Value);// to know if customer set png img
	virtual void __fastcall SetFontSize( int value );
	virtual void __fastcall SetFont( String name, int sz );
	virtual void __fastcall Paint(void); // override the painting of the component
	DYNAMIC void __fastcall Click(void);

__published:

	__property Action;
	__property Anchors = {default=3};
	__property bool Down = {read=FDown, write=SetDown, default=False};
	__property Enabled = {default=1};
	__property int ImgStates = {read=FStateCount, write=SetStateCount, default=4};
//	__property System::Uitypes::TModalResult ModalResult = {read=FModalResult, write=FModalResult, default=0};
	__property TModalResult ModalResult = {read=FModalResult, write=FModalResult, default=0};
	__property ParentShowHint = {default=1};
	__property Vcl::Imaging::Pngimage::TPngImage *PngImg = {read=FPngImg, write=SetPngImg};
	__property PopupMenu;
	__property ShowHint;
	__property Visible = {default=1};
	__property OnClick;
	__property OnContextPopup;
	__property OnMouseDown;
	__property OnMouseMove;
	__property OnMouseUp;
	__property System::Classes::TNotifyEvent OnMouseEnter = {read=FOnMouseEnter, write=FOnMouseEnter};
	__property System::Classes::TNotifyEvent OnMouseLeave = {read=FOnMouseLeave, write=FOnMouseLeave};
	__property bool EnablePNG = {read=FEnablePNG, write=SetEnablePNG, default=False};
	__property TColor BorderColor = {read=FBorderColor, write=SetBorderColor, default=TColor(0x83807d)};
	__property TColor InterFrameColor = {read=FInterFrameColor, write=SetInterFrameColor, default=TColor(0x302e2c)};
	__property TColor InterColor  = {read=FInterColor, write=SetInterColor, default=TColor(0x58504a)};
private:
	Vcl::Imaging::Pngimage::TPngImage *m_pPngButton, *m_pPngFoucusButton;
	Vcl::Imaging::Pngimage::TPngImage *pTmpDraw, *pTmpFoucusDraw;
	void  __fastcall PaintCustomer(void);
    void  __fastcall PaintCustomerText(void);

public:
	TRect  rtCaption;

__published:
	__property int FontSize = {write=SetFontSize, default=8};
    __property String Caption = {read=FCaption, write=SetCaption};

};
/**************************************************************************************************/
/**************************************************************************************************/
class PACKAGE TComboBoxComponent : public CBCapButton
{
private:
    TComboBoxChangeEvent  FOnChange;		// ComboBox变化事件
                     int  FItemHeight,
	                      FShowItemCount;
           TComboBoxMode  FShowMode;

    TDropListView *m_DropListView;	// 定义下拉列表框
             bool  m_IsMouseOver;
              int  m_ClickStat;		// .....


    void __fastcall DoItemClick(TComboBoxItem *Sender, int Index);

    // 处理下拉列表隐藏、显示事件
    void __fastcall DoDropListShow(TObject *Sender);
    void __fastcall DoDropListHide(TObject *Sender);

    int __fastcall GetDefaultItem();
    int __fastcall GetItemsCount();

    void __fastcall SetDefaultItem(int Value);
    void __fastcall SetItemHeight(int Value);
    void __fastcall SetShowItemCount(int Value);
    void __fastcall SetShowMode(TComboBoxMode Value);

    void __fastcall DoMouseEnter(TObject *Sender);
    void __fastcall DoMouseLeave(TObject *Sender);

	//MESSAGE void __fastcall CMMouseEnter(TMessage &Message);
    //MESSAGE void __fastcall CMMouseLeave(TMessage &Message);

    //BEGIN_MESSAGE_MAP
    //	MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMMouseEnter)
    //	MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMMouseLeave)
	//END_MESSAGE_MAP(CBCapButton)


protected:
    DYNAMIC void __fastcall MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y);
	DYNAMIC void __fastcall MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y);

	virtual void __fastcall SetParent(TWinControl* AParent);
public:
	__fastcall TComboBoxComponent(TComponent *Owner);
    __fastcall ~TComboBoxComponent();

	TComboBoxItem * __fastcall AddItem(String Caption);
    void __fastcall Clear();
	void __fastcall RemoveItem(int Index);
	TComboBoxItem * __fastcall GetItem(int Index);
	virtual void __fastcall SetFontSize( int value );
	virtual void __fastcall SetFont( String name, int size );
	__property int DefItemIndex = {read = GetDefaultItem, write = SetDefaultItem};
    __property int ItemsCount	= {read = GetItemsCount};

__published:
    __property TComboBoxChangeEvent OnChange 		= {read = FOnChange, write = FOnChange};

    __property           int ItemHeight 	= {read = FItemHeight, write = SetItemHeight, default = 20};
    __property           int ShowItemCount 	= {read = FShowItemCount, write = SetShowItemCount, default = 10};
	__property TComboBoxMode ShowMode 		= {read = FShowMode, write = SetShowMode, default = cbShowDown};
	__property TWinControl* Parent = {read=FParent, write=SetParent};
};
/**************************************************************************************************/
/**************************************************************************************************/

#endif
