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

#pragma hdrstop

#include "PredefineProjectSetUnit.h"
#include "GlobalUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

#define ITEM_OVER		TColor(RGB(76, 82, 91))
#define ITEM_SELECTED	TColor(RGB(29, 31, 35))
#define ITEM_DEF		TColor(RGB(39, 42, 47))

#define ITEM_TEXT_COLOR	   TColor(RGB(189, 195, 200)) //	TColor(RGB(213, 221, 232))

#define BORDER 		    TColor(RGB(106, 111, 117))
#define BACKGRND		TColor(RGB(52, 55, 62))

#define MARGIN			2

//---------------------------------------------------------------------------
__fastcall TPrefineProjectSetItem::TPrefineProjectSetItem(TWinControl *Parent) : TGraphicControl(Parent)
{
	SetParentComponent(Parent);

	FIsSelected = false;
	FIsFocus = false;

	CtrlParent = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::SetSelected(bool Value)
{
	if(FIsSelected != Value) {
		FIsSelected = Value;
		Repaint();
    }
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::Paint()
{
	Canvas->Brush->Color = BACKGRND;
	Canvas->Font->Color = ITEM_TEXT_COLOR;//RGB(200,200,200);

	if(FIsSelected) {
		Canvas->Brush->Color = ITEM_SELECTED;
		Canvas->FillRect(ClientRect);
//		Canvas->Brush->Color = ITEM_SELECTED;
//		Canvas->FrameRect(ClientRect);
	}
	else if(FIsFocus) {
		Canvas->Brush->Color = ITEM_OVER;
		Canvas->FillRect(ClientRect);
//		Canvas->Brush->Color = ITEM_FOC;
//		Canvas->FrameRect(ClientRect);
	}
	else {
		Canvas->FillRect(ClientRect);
	}

	for(int i = 0; i < 8; i++) {
		int l = ClientRect.Left + i * (Width / 8);
		int t = ClientRect.Top;
		int r = l + (Width / 8);
		int b = ClientRect.Bottom - 2;

		TRect Rect(l, t, r, b);

		int ch =  PredefChord[i];

		int type = ch & 0x03;
		int key = (ch >> 2) + Key;

		if( key>11 ) key -= 12;

		DrawChord(Canvas, Rect, key, type);
	}
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::CMMouseEnter(TMessage &Message)
{
	FIsFocus = true;
	Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::CMMouseLeave(TMessage &Message)
{
    FIsFocus = false;
	Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::WMLButtonDown(TWMLButtonDown &Message)
{
	IsSelected = true;

	if(CtrlParent)
		CtrlParent->DoItemClick(this, Index);
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSetItem::DrawChord(TCanvas *Canvas, TRect Rect, int iKey, int iType)
{
	int iMainKey, iAjustKey; //调级数、升降
	GetChordDisplayKey(iKey, Key, iMainKey, iAjustKey);
	UniDrawChord(Canvas, Rect, iMainKey, iAjustKey, iType);
}
//---------------------------------------------------------------------------

void __fastcall TPrefineProjectSetItem::GetChordDisplayKey(int iKey, int iBaseKey, int& iMainKey, int& iAjustKey)
{
	iMainKey = -1;
	iAjustKey = 0;

	if( iKey<0 )
		return;

	if( !g_bAlphaKey ){
		iKey -= iBaseKey;
		if( iKey<0 ) iKey += 12;
	}

	switch( iKey ){
	case 0: iMainKey = 0;
		break;
	case 1: iAjustKey = -1;
	case 2: iMainKey = 1;
		break;
	case 3: iAjustKey = -1;
	case 4: iMainKey = 2;
		break;
	case 6: iAjustKey = 1;
	case 5: iMainKey = 3;
		break;
	case 7: iMainKey = 4;
		break;
	case 8: iAjustKey = -1;
	case 9: iMainKey = 5;
		break;
	case 10: iAjustKey = -1;
	case 11: iMainKey = 6;
		break;
	}
}
//---------------------------------------------------------------------------

void __fastcall TPrefineProjectSetItem::UniDrawChord(TCanvas *Canvas, TRect rcDraw, int iMainKey, int iAjustKey, int iType)
{
	String strMainKey, strAjustKey, strA, strN;

	if( iAjustKey==1 ) strAjustKey = L"#";
	else if( iAjustKey==-1 ) strAjustKey = L"b";

	if( iType==1 || iType==3 ) strA = L"m";
	if( iType==2 || iType==3 ) strN = L"7";

	int iMKeyLeft, iATypeLeft, iNTypeLeft, wChord(0),
		wMKey(12), wAKey(3), wType(8), wVKey(12), wIKey(6);

	if( !g_bAlphaKey ){ //罗马字母
		if( iMainKey==0 ){
			wMKey = iType>0 ? 6 : 8;
		}
		else if( iMainKey==1 ){
			wMKey = iType>0 ? 12 : 16;
		}
		else if( iMainKey==2 ){
			wIKey = 5;
			wMKey = iType>0 ? 16 : 18;
		}
		else if( iMainKey==3 ){
			wVKey = 11;
			wMKey = iType>0 ? 15 : 18;
		}
		else if( iMainKey==4 ){
			wMKey = iType>0 ? 10 : 16;
		}
		else if( iMainKey==5 ){
			wVKey = 11;
			wIKey = 5;
			wMKey = iType>0 ? 17 : 20;
		}
		else if( iMainKey==6 ){
			wVKey = 11;
			wIKey = 5;
			wMKey = iType>0 ? 22 : 26;
		}
	}
	else{   //英文字母
		if( iMainKey==5 ){ //A升降号靠近
			wAKey = 1;
		}
		else if( iMainKey==3 ){ //F下标靠近
			wMKey = 9;
		}
	}

	wChord += wMKey;
	if( iAjustKey!=0 ) wChord += wAKey;
	if( strA.Length()>0 ) wChord += wType - 1;
	if( strN.Length()>0 ) wChord += wType - 1;

	int iLeft = rcDraw.Left + ( rcDraw.Width() - wChord ) / 2,
		iOriTop = rcDraw.top + (rcDraw.Height() - 18) / 2;

	TFont *fntOld = new TFont;
	fntOld->Assign( Canvas->Font );

	Canvas->Font->Name = "Times New Roman";
	Canvas->Font->Quality = TFontQuality::fqClearTypeNatural;
//	Canvas->Font->Color = RGB(60,43,23);
	Canvas->Font->Style = TFontStyles()<<fsItalic<<fsBold;
	Canvas->Brush->Style = bsClear;

	//绘制升降调
	if( iAjustKey!=0 ){
		int iTop = iOriTop-2;
		if( iAjustKey==-1 || !g_bAlphaKey && iMainKey==6 )
			iTop++;

		Canvas->Font->Size = g_szFont8;  //升降字体大小
		Canvas->TextOut( iLeft, iTop, strAjustKey );

		iLeft += wAKey;
	}

	int iTop = iOriTop - 1;
	Canvas->Font->Size = g_szFont16;    //和弦字体大小
	if( g_bAlphaKey ){
		strMainKey = g_strAlphaTable[iMainKey];
		Canvas->TextOut( iLeft, iTop, strMainKey );
	}
	else{
		int l = iLeft;
		if( iMainKey<4 ){
			strMainKey = L"I";
			Canvas->TextOut( l, iTop, strMainKey );
			l += wIKey;

			if( iMainKey==3 ){
				strMainKey = L"V";
				Canvas->TextOut( l, iTop, strMainKey );
				l += wVKey;
			}
			else if( iMainKey>0 ){
				Canvas->TextOut( l, iTop, strMainKey );
				l += wIKey;

				if( iMainKey==2 ){
					Canvas->TextOut( l, iTop, strMainKey );
					l += wIKey;
				}
			}
		}
		else{
			strMainKey = L"V";
			Canvas->TextOut( l, iTop, strMainKey );
			l += wVKey;

			if( iMainKey>4 ){
				strMainKey = L"I";
				Canvas->TextOut( l, iTop, strMainKey );
				l += wIKey;

				if( iMainKey==6 ){
					Canvas->TextOut( l, iTop, strMainKey );
					l += wIKey;
				}
			}
		}
	}

	iLeft += wMKey;
	iTop = iOriTop + 6;

	//绘制A
	if( strA.Length()>0 ){
		Canvas->Font->Size = g_szFont9;
		Canvas->TextOut( iLeft+2, iTop, strA );

		iLeft += wType;
	}

	//绘制N
	if( strN.Length()>0 ){
		iTop += g_szFont8==g_szFont9 ? 2 : 3;
		Canvas->Font->Size = g_szFont8;
		Canvas->Font->Style = TFontStyles();
		Canvas->TextOut( iLeft+4, iTop, strN );
	}

	Canvas->Font->Assign( fntOld );
	delete fntOld;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
__fastcall TPrefineProjectSet::TPrefineProjectSet(TComponent *Owner) : TCustomControl(Owner)
{
	mContentArea = new TWinControl(this);

	mItemList = new TList();

	mItemWidth = 100;
	mItemHeight = 25;

	mCurrentItem = NULL;

	OnHide = NULL;
	OnShow = NULL;
}
//---------------------------------------------------------------------------
__fastcall TPrefineProjectSet::~TPrefineProjectSet()
{
	if(mItemList) {
		mItemList->Clear();
		delete mItemList;
		mItemList = NULL;
	}

	if(mContentArea) {
		delete mContentArea;
		mContentArea = NULL;
    }
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::AddItem(TPrefineProjectSetItem *Item)
{
	Item->Width = 400;
	Item->Height = mItemHeight;
	Item->Top = mItemList->Count * mItemHeight;
	Item->Left = 0;
	Item->Parent = mContentArea;
	Item->CtrlParent = this;

	mItemList->Add(Item);
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::SetSelectedIndex(int Value)
{
	mSelectedIndex = Value;

	TPrefineProjectSetItem *Item = (TPrefineProjectSetItem *)mItemList->Items[Value];
	Item->IsSelected = true;

	DoItemClick(Item, Value);
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::CreateParams(TCreateParams &Params)
{
    TCustomControl::CreateParams(Params);

    Params.Style = 0;

    Params.Style = WS_POPUP;
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::CreateWnd()
{
	TCustomControl::CreateWnd();
	mContentArea->Parent = this;
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::Hide()
{
	TCustomControl::Hide();
	SetActiveWindow(mActiveWndBak);

	if(OnHide) {
		OnHide(this);
    }
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::Show()
{
	TCustomControl::Show();

	mActiveWndBak = GetActiveWindow();
	SetActiveWindow(Handle);

	Height = mItemList->Count * mItemHeight + 4;

	if(OnShow) {
		OnShow(this);
	}
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::DoItemClick(TPrefineProjectSetItem *Item, int Index)
{
	if(mCurrentItem != Item) {
		if(mCurrentItem)
			mCurrentItem->IsSelected = false;

		mCurrentItem = Item;

		mSelectedIndex = Index;
	}

	Hide();
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
	TCanvas* tmpCanvas = new TCanvas();
	tmpCanvas->Handle  = Message.DC;

	tmpCanvas->Brush->Color = BACKGRND;
	tmpCanvas->FillRect(ClientRect);

	tmpCanvas->Brush->Color = BORDER;
	tmpCanvas->FrameRect(ClientRect);

	delete tmpCanvas;
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::WMSize(TWMSize &Message)
{
	mContentArea->Width = Width - 4;
	mContentArea->Height = Height - 4;
	mContentArea->Top = 2;
	mContentArea->Left = 2;

	for(int i = 0; i < mItemList->Count; i++) {
		TPrefineProjectSetItem *Item = (TPrefineProjectSetItem *)mItemList->Items[i];
		Item->Width = mContentArea->Width;
	}
	mItemWidth = mContentArea->Width;
}
//---------------------------------------------------------------------------
void __fastcall TPrefineProjectSet::WMKillFocus(TMessage &Message)
{
    Hide();
}
//---------------------------------------------------------------------------

