//---------------------------------------------------------------------------
#include <vcl.h>
#include <Vcl.Imaging.pngimage.hpp>
#pragma hdrstop

#include "GlobalUnit.h"
#include "PreStylePanel.h"
#include "UseStylePanel.h"
#include "MessageFormUnit.h"
#include "MultiSwitchProgFormUnit.h"
#include "SwitchTextureForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

extern int 	w_xOffDrag, //图片左上角与鼠标距离
			w_yOffDrag;

__fastcall TPreStylePanel::TPreStylePanel(TComponent* AOwner)
	: TStylePanel(AOwner)
{
	m_strTitle = "预编风格";

	AddToolBtn( 3, "imgNewStyle", NewStyle, "新建自定义风格" );

	memset( m_nIECount, 0, sizeof(m_nIECount) );
}
//---------------------------------------------------------------------------

void TPreStylePanel::Init()
{
	//添加新内容
//	g_pPreStyle = NULL;
//	memset( m_nIECount, 0, sizeof(m_nIECount) );

	TPROSTYLE* pSelStyle = NULL;
	if( !g_aRecomStyles.empty() ){
		srand((unsigned)time(NULL));
		int n = rand() % g_aRecomStyles.size();

		pSelStyle = g_aRecomStyles[n];
	}

	if( pSelStyle ){
		SetPreStyle( pSelStyle->idLoc, pSelStyle->idStyle );
	}
}
//---------------------------------------------------------------------------

bool TPreStylePanel::HandleHoverEvent(TPoint ptMouse)
{
	int X = ptMouse.X,
		Y = ptMouse.Y;

	TCommonItem* pHoverItem = NULL;
	int iHoverLine = -1;
	bool bCanDrop = false;

	TCommonItem* pItem = HitTest( X, Y-m_nTitleHeight, NULL );
	if( pItem ){
		if( m_pDropItem && m_pDropItem!=m_pDragItem ){ //从外部拖动
			if( m_pDropItem->iType==SEGTYPE_STYLE ){
				pHoverItem = (TCommonItem*)m_aItems->Items[0];
				iHoverLine = -m_iTopLine;
			}
			else if( m_pDropItem->iType==SEGTYPE_TRACK ){
				iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
				pHoverItem = GetTrackHoverItem( pItem, iHoverLine );
			}
			else{
				iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
				pHoverItem = GetSegmentHoverItem( pItem, iHoverLine );
			}
		}
		else if( m_pDragItem && m_pDragItem->iType!=SEGTYPE_STYLE
								&& m_pDragItem->iType!=SEGTYPE_TRACK
								&& m_pDragItem!=pItem ){ //自身拖动
			if( pItem->iType==m_pDragItem->iType ){
				if( pItem->iType < SEGTYPE_INTRO
							|| pItem->GetSegNo()<4 && m_pDragItem->GetSegNo()<4
							|| pItem->GetSegNo()>=4 && m_pDragItem->GetSegNo()>=4 ){
					pHoverItem = pItem;
					iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
				}
			}
		}
	}
	else if( m_pDropItem && m_pDropItem->iType==SEGTYPE_STYLE ){
		bCanDrop = true;
	}

	SetUnfoldTimer( pItem, pHoverItem );
	SetHover( pHoverItem, iHoverLine );

	return pHoverItem!=NULL || bCanDrop;
}
//---------------------------------------------------------------------------

void TPreStylePanel::HandleDropEvent( int iState )
{
	if( !m_pDragItem && m_pDropItem ){
		TPROSTYLE* pTmpStyle = GetStyleInfo( -1, 0 );
		if( pTmpStyle ){ //当前正在编辑
			TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
			TStyleItem* pSrcStyItem = m_pDropItem->GetStyleItem();

			if( pStyItem->pStyle && pStyItem->pStyle->idLoc!=0 && pSrcStyItem->pStyle==pStyItem->pStyle ){
				MessageForm->ShowMessage( "该风格正在编辑中，不可使用！",
															MB_ICONERROR | MB_OK, "错误" );
				return;
			}
		}

		Stop();

		if( m_pDropItem->iType==SEGTYPE_STYLE ){ //替换整个当前风格
			if( !QueryStyleSave() )
				return;

			TStyleItem* pStyItem = (TStyleItem*)m_pDropItem;
			SetPreStyle( pStyItem->pStyle->idLoc, pStyItem->pStyle->idStyle );

			if( g_lstOpusStages.size()==0 ){
				TShiftState Shift( iState );
				if( Shift.Contains( ssCtrl ) && pStyItem->pStyle ){
					if( pStyItem->pStyle->idLoc==0 )
						PostMessage( Parent->Handle, UM_CHANGETT, false,
										pStyItem->pStyle->pOrigin->detail.iTempo );
					else if( pStyItem->pStyle->idLoc==1 )
						PostMessage( Parent->Handle, UM_CHANGETT, false,
										pStyItem->pStyle->pShare->iTempo );
					else
						PostMessage( Parent->Handle, UM_CHANGETT, false,
										pStyItem->pStyle->pLocal->iTempo );
				}
			}
		}
		else if( m_pHoverItem ){
			if( m_pDropItem->iType==SEGTYPE_TRACK ){
				TSegmentItem* pSeg = (TSegmentItem*)m_pHoverItem;
				if( m_pHoverItem->iType==SEGTYPE_TRACK )
					pSeg = (TSegmentItem*)m_pHoverItem->up;

				AddTrack( pSeg, (TTrackItem*)m_pDropItem );
			}
			else{ //添加片段
				TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
				TSegmentItem* pSrcSeg = (TSegmentItem*)m_pDropItem;
				TSegmentItem* pDestSeg = NULL;

				if( !pStyItem->IsUnfold() ){
					SetFold( pStyItem, 0 );
				}

				for( int i=0; i<pStyItem->aItems->Count; i++ ){
					TSegmentItem* pTmpSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
					if( pTmpSeg->iSegType==pSrcSeg->iSegType
							&& pTmpSeg->aItems->Count==pSrcSeg->aItems->Count ){
						bool bSame = true;
						for( int j=0; j<pTmpSeg->aItems->Count; j++ ){
							TTrack* pTrk1 = ((TTrackItem*)pTmpSeg->aItems->Items[j])->pTrack;
							bool bFound = false;

							for( int k=0; k<pSrcSeg->aItems->Count; k++ ){
								TTrack* pTrk2 = ((TTrackItem*)pSrcSeg->aItems->Items[k])->pTrack;

								if( pTrk1->iStyleLoc==pTrk2->iStyleLoc
											&& pTrk1->iStyleId==pTrk2->iStyleId
											&& pTrk1->iSegNo==pTrk2->iSegNo
											&& pTrk1->iChanNo==pTrk2->iChanNo
											&& pTrk1->iProg==pTrk2->iProg
											&& pTrk1->nVol==pTrk2->nVol ){
									bFound = true;
									break;
								}
							}

							if( !bFound ){
								bSame = false;
								break;
							}
						}

						if( bSame ){
							pDestSeg = pTmpSeg;
							break;
						}
					}
				}

				bool bAdd = false;
				if( !pDestSeg ){
					int index = -1;
					if( m_pHoverItem!=pStyItem ){
						for( int i=0; i<pStyItem->aItems->Count; i++ ){
							if( m_pHoverItem==pStyItem->aItems->Items[i] ){
								index = i;
								break;
							}
						}
					}

					pDestSeg = InsertSegment( index, pSrcSeg );
					bAdd = true;
				}

				int iLine = 1;//m_iHoverLine + 1;
				TCommonItem* pItem = GetNextItem( pStyItem );
				while( pItem && pItem!=pDestSeg ){
					iLine++;
					pItem = GetNextItem( pItem );
				}

				if( bAdd && iLine<=m_iTopLine )
					m_iTopLine++;

				SetSelect( pDestSeg, iLine-m_iTopLine );
			}
		}

		ResetScrollBar();

		ShowSelItem();

		SetFocus();
	}
	else if( m_pDragItem && m_pDragItem==m_pDropItem && m_pHoverItem
						&& m_pDragItem->iType!=SEGTYPE_STYLE
						&& m_pDragItem->iType!=SEGTYPE_TRACK
						&& m_pHoverItem->iType==m_pDragItem->iType ){
		if( m_pHoverItem->next==m_pDragItem || m_pHoverItem->prev==m_pDragItem ){
			SwapSegments( (TSegmentItem*)m_pDragItem, (TSegmentItem*)m_pHoverItem );

 //			int iLine = m_iSelLine;
			m_iSelLine = m_iHoverLine;
//			m_iHoverLine = iLine;
		}
		else{
			TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
			int indFrom = -1, indTo = -1;
			for( int i=0; i<pStyItem->aItems->Count; i++ ){
				if( m_pHoverItem==pStyItem->aItems->Items[i] ){
					indTo = i;

					if( indFrom>=0 )
						break;;
				}
				else if( m_pDragItem==pStyItem->aItems->Items[i] ){
					indFrom = i;

					if( indTo>=0 )
						break;
				}
			}

			MoveSegment( indFrom, indTo );
		}

		m_iSelLine = m_iHoverLine;

		Paint();
	}
}
//---------------------------------------------------------------------------

bool TPreStylePanel::StartDrag()
{
	return true;
}
//---------------------------------------------------------------------------

void TPreStylePanel::DeleteItem( TCommonItem *pItem, int iLine )
{
	int sType = pItem->GetSegType();
	vector<int> aSegNo;

	TCommonItem* pUp = NULL;
	TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
	TPROSTYLE* pStyle = pStyItem->pStyle;

	if( pItem->iType==SEGTYPE_TRACK ){
		pUp = pItem->up;
		TTrackItem* pTrk = (TTrackItem*)pItem;

		if( pTrk->pStyle->idLoc==(UINT)-1 && pTrk->pStyle->idStyle==0 ){
			if( pUp->aItems->Count==1 ){ //最后一个
				if( QuerySegmentDelete( -1, 0, sType, pItem->GetSegNo() ) )
					f_CM_DeleteTempSegment( -1, 0, sType, pItem->GetSegNo() );
				else
					return;
			}
		}
		else if( pStyle->idLoc!=0 && pStyle->idLoc!=(UINT)-1 && pTrk->pStyle==pStyle ){
			aSegNo.push_back( pItem->GetSegNo() );
		}
	}
	else{
		int iSN = -1;

		for( int i=0; i<pItem->aItems->Count; i++ ){
			TTrackItem* pTrk = (TTrackItem*)pItem->aItems->Items[i];
			if( pTrk->pStyle->idLoc==(UINT)-1 && pTrk->pStyle->idStyle==0 ){
				iSN = pTrk->GetSegNo();
				break;
			}
			else if( pStyle && pStyle->idLoc!=0 && pStyle->idLoc!=(UINT)-1
														&& pTrk->pStyle==pStyle ){
				bool bAdd = true;
				for( int j=0; j<aSegNo.size(); j++ ){
					if( aSegNo[j]==pTrk->GetSegNo() ){
						bAdd = false;
						break;
					}
				}

				if( bAdd ){
					for( int j=0; bAdd && j<pStyItem->aItems->Count; j++ ){
						TSegmentItem* pSegItem = (TSegmentItem*)pStyItem->aItems->Items[j];
						if( pSegItem!=pItem && pSegItem->iSegType==pItem->GetSegType() ){
							for( int t=0; t<pSegItem->aItems->Count; t++ ){
								TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[t];
								if( pTrkItem->pStyle==pStyle && pTrkItem->GetSegNo()==pTrk->GetSegNo() ){
									bAdd = false;
									break;
								}
							}
						}
					}
				}

				if( bAdd ){
					aSegNo.push_back( pTrk->GetSegNo() );
				}
			}
		}

		if( iSN>=0 ){
			if( QuerySegmentDelete( -1, 0, sType, iSN ) ){
				f_CM_DeleteTempSegment( -1, 0, sType, iSN );
			}
			else{
				return;
			}
		}

		TSegmentItem* pNextSeg = (TSegmentItem*)pItem->next;
		while( pNextSeg && pNextSeg->iSegType==sType ){
			if( sType<=SEGTYPE_FILL ){
				pNextSeg->iSegNo--;
//				pNextSeg->iInd--;
			}
			else{
				int iTon = pItem->GetSegNo() < 4 ? 0 : 1,
					iNextTon = pNextSeg->iSegNo < 4 ? 0 : 1;

				if( iTon==iNextTon ){
					pNextSeg->iSegNo--;
//					pNextSeg->iInd--;

				}
				else
					break;
			}

			pNextSeg = (TSegmentItem*)pNextSeg->next;
		}

		if( sType>=SEGTYPE_INTRO ){
			int s = sType - SEGTYPE_INTRO,
				n =	pItem->GetSegNo()<4 ? 0 : 1;

			m_nIECount[s][n]--;
		}
	}

	TStylePanel::DeleteItem( pItem, iLine );

	if( pUp && pUp->aItems->Count==0 ){
		DeleteItem( pUp, iLine-1 );
	}

	if( !aSegNo.empty() ){
		UINT idLoc = pStyle->idLoc, idStyle = pStyle->idStyle;
		for( int i=0; i<aSegNo.size(); i++ ){
			//首次须调入原本地风格
			f_CM_DeleteTempSegment( idLoc, idStyle, sType, aSegNo[i] );

			//之后在缓存中删除
			idLoc = -1;
			idStyle = 0;
		}

		TPROSTYLE* pTmpStyle = GetStyleInfo( -1, 0 );
		if( !pTmpStyle ){
			pTmpStyle = new TPROSTYLE;
			pTmpStyle->idLoc = -1;
			pTmpStyle->idStyle = 0;
			g_aTempStyles.push_back( pTmpStyle );
		}

		if( pStyle->idLoc!=0 && pStyle->idLoc!=(UINT)-1 ){
			for( int i=0; i<pStyItem->aItems->Count; i++ ){
				TSegmentItem* pSegItem = (TSegmentItem*)pStyItem->aItems->Items[i];
				for( int j=0; j<pSegItem->aItems->Count; j++ ){
					TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[j];
					if( pTrkItem->pStyle==pStyle ){
						pTrkItem->pStyle = pTmpStyle;
					}
				}
			}
		}
	}

	((TStyleItem*)m_aItems->First())->SetImport();
}
//---------------------------------------------------------------------------

bool TPreStylePanel::QuerySegmentDelete( UINT idLoc, UINT idStyle, int sType, int sNo )
{
	if( g_pUseStyle ){
		bool bQuery = false;
		for( int i=0; !bQuery && i<g_pUseStyle->aItems->Count; i++ ){
			TSegmentItem* pSeg = (TSegmentItem*)g_pUseStyle->aItems->Items[i];
			for( int j=0; !bQuery && j<pSeg->aItems->Count; j++ ){
				TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
				if( pTrk->pStyle->idLoc==idLoc && pTrk->pStyle->idStyle==idStyle
							&& pTrk->GetSegType()==sType && pTrk->GetSegNo()==sNo ){
					bQuery = true;
					break;
				}
			}
		}

		if( bQuery ){
			MessageForm->ShowMessage( "该片段正在使用中，无法删除！",
													MB_ICONERROR | MB_OK, "删除片段" );
			return false;
		}
	}

	return true;
}
//---------------------------------------------------------------------------

void TPreStylePanel::RestoreItems()
{
	bool bAuthority = SOFTWARE_ID==e_Pro_Lite || g_bLogon
								&& (g_infoUser.accountInfo.authority & 0x1000);

	TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
	TPROSTYLE* info = pStyItem->pStyle;

	for( int s=0; s<SEGTYPE_TRACK; s++ ){
		int rep = s<SEGTYPE_INTRO ? 1 : 2;
		for( int r=0; r<rep; r++ ){
			int nSegNum = info->idLoc==0 ? info->pOrigin->detail.nSegNum[s]
								: info->idLoc==1 ? info->pShare->nSegNum[s]
												: info->pLocal->nSegNum[s];
			int num = s<SEGTYPE_INTRO ? nSegNum
								: r==0 ? ( nSegNum & 0x0F )
										: ( nSegNum>>4 );

			if( num>0 ){
				DWORD opts = OPT_DEL | OPT_VOL | (s<SEGTYPE_INTRO ? OPT_BRUSH : 0);
				for( int i=0; i<num; i++ ){
					int sn = r==0 ? i : i+4;
					int vol = info->idLoc==0 ? 100
							: info->idLoc==1 ? info->pShare->nSegVol[s][sn]
											: info->pLocal->nSegVol[s][sn];
					TSegmentItem* pSegItem = pStyItem->AddSegment( s, sn, opts, 0, -1, vol );

					DWORD optsTk = OPT_DEL|OPT_FONTPROG|OPT_VOL;
					if( s<SEGTYPE_INTRO )
						optsTk |= OPT_TEXTURE;

					for( int j=0; j<16; j++ ){
						pSegItem->AddTrack( info, sn, j, optsTk, bAuthority );
					}

					if( pSegItem->aItems->Count>0 ){
						if( s==SEGTYPE_INTRO ){
							pSegItem->nBars = info->idLoc==0 ? info->pOrigin->detail.aIntroBars[sn]
											: info->idLoc==1 ? info->pShare->aIEBars[0][sn]
															: info->pLocal->aIEBars[0][sn];
							m_nIECount[0][r]++;
						}
						else if( s==SEGTYPE_ENDING ){
							pSegItem->nBars = info->idLoc==0 ? info->pOrigin->detail.aEndingBars[sn]
											: info->idLoc==1 ? info->pShare->aIEBars[1][sn]
															: info->pLocal->aIEBars[1][sn];
							m_nIECount[1][r]++;
						}
					}
					else{
						pStyItem->DeleteSegment( pSegItem );
					}
				}
			}
		}
	}
}
// ---------------------------------------------------------------------------

void TPreStylePanel::SetPreStyle( UINT idLoc, UINT idStyle )
{
	TStyleItem* pStyItem = NULL;

	TPROSTYLE* pInfo = GetStyleInfo( idLoc, idStyle );
	if( pInfo ){
		ClearAllItems();
		memset( m_nIECount, 0, sizeof(m_nIECount) );

		pStyItem = AddStyle( pInfo, OPT_FONTPROG | OPT_SAVE );
		RestoreItems();
		pStyItem->SetImport();

		m_pTopItem = pStyItem;
		SetFold( pStyItem, 0 );

		ResetScrollBar();
		Paint();
	}

	g_pPreStyle = pStyItem;
}
// ---------------------------------------------------------------------------

void __fastcall TPreStylePanel::SetStyleItem( TStyleItem* pStyItem )
{
	TStylePanel::SetStyleItem( pStyItem );

	if( pStyItem ){
		//统计IECount
		memset( m_nIECount, 0, sizeof(m_nIECount) );
		for( int i=0; i<pStyItem->aItems->Count; i++ ){
			TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
			if( pSeg->iSegType>=SEGTYPE_INTRO ){
				if( pSeg->iSegNo<4 )
					m_nIECount[pSeg->iSegType-SEGTYPE_INTRO][0]++;
				else
					m_nIECount[pSeg->iSegType-SEGTYPE_INTRO][1]++;
			}
		}

		pStyItem->SetImport();
	}
}
// ---------------------------------------------------------------------------

TSegmentItem* TPreStylePanel::InsertSegment( int index, TSegmentItem* pSrcSeg )
{
	TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();

	int ind = 0;
	DWORD opts = OPT_DEL|OPT_VOL;
	int stype = pSrcSeg->iSegType;
	if( stype<=SEGTYPE_FILL ){
		opts |= OPT_BRUSH;
	}

	if( index<0 || index>=pStyleItem->aItems->Count ){
		index = 0;
		for( int i=0; i<stype; i++ ){
			index += pStyleItem->nSegNum[i];
		}

		if( stype<=SEGTYPE_FILL ){
			ind = pStyleItem->nSegNum[stype];
			index += ind;
		}
		else{
			int t = stype-SEGTYPE_INTRO,
				n = pSrcSeg->iSegNo<4 ? 0 : 1;
			ind = m_nIECount[t][n];

			index += ind;

			if( n==1 ){
				ind += 4;
				index += m_nIECount[t][0];
			}
		}
	}
	else{
		if( stype>=SEGTYPE_INTRO && pSrcSeg->iSegNo>=4 )
			ind = 4;

		for( int i=0; i<pStyleItem->aItems->Count; i++ ){
			TSegmentItem* pTmpSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];

			if( pTmpSeg->iSegType==stype ){
				if( stype<=SEGTYPE_FILL ){
					if( i<index )
						ind++;
					else{
						pTmpSeg->iInd++;
						pTmpSeg->iSegNo++;
					}
				}
				else{
					int iSrcTon = pSrcSeg->iSegNo < 4 ? 0 : 1,
						iTmpTon = pTmpSeg->iSegNo < 4 ? 0 : 1;

					if( iSrcTon==iTmpTon ){
						if( i<index )
							ind++;
						else{
							pTmpSeg->iInd++;
							pTmpSeg->iSegNo++;
						}
					}
				}
			}
		}
	}

	TSegmentItem* pDestSeg = new TSegmentItem( pStyleItem, stype, ind,
													opts, 0, ind, pSrcSeg->volume );

	opts = OPT_DEL|OPT_FONTPROG|OPT_VOL;

	if( stype>SEGTYPE_FILL ){
		pDestSeg->nBars = pSrcSeg->nBars;

		int t = stype-SEGTYPE_INTRO,
		n = pDestSeg->iSegNo<4 ? 0 : 1;
		m_nIECount[t][n]++;
	}
	else{
		opts |= OPT_TEXTURE;
    }

	for( int i=0; i<pSrcSeg->aItems->Count; i++ ){
		TTrackItem* pSrcItem = (TTrackItem*)pSrcSeg->aItems->Items[i];
		TTrack* pSrcTrack = new TTrack( pSrcItem->pTrack );

		TTrackItem* pDestItem = pDestSeg->AddTrack( pSrcItem->pStyle, pSrcTrack, opts, true );
	}

	pStyleItem->InsertSegment( index, pDestSeg, 0 );
	m_nTotalLine++;

	pStyleItem->SetImport();

	return pDestSeg;
}
// ---------------------------------------------------------------------------

void TPreStylePanel::MoveSegment( int indFrom, int indTo )
{
	if( indFrom<0 || indTo<0 || indFrom==indTo )
		return;

	TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
	TSegmentItem *pSegFrom = (TSegmentItem*)pStyItem->aItems->Items[indFrom],
				 *pSegTo = (TSegmentItem*)pStyItem->aItems->Items[indTo];

	if( pSegFrom->prev )
		pSegFrom->prev->next = pSegFrom->next;
	if( pSegFrom->next )
		pSegFrom->next->prev = pSegFrom->prev;

	if( pSegTo->prev )
		pSegTo->prev->next = pSegFrom;
	pSegFrom->prev = pSegTo->prev;
	pSegTo->prev = pSegFrom;
	pSegFrom->next = pSegTo;

	pSegFrom->iSegNo = pSegTo->iSegNo;
	pSegFrom->iInd = pSegTo->iInd;

	if( indFrom>indTo ){ //先删后插
		pStyItem->aItems->Delete( indFrom );
		pStyItem->aItems->Insert( indTo, pSegFrom );

		for( int i=indTo+1; i<=indFrom; i++ ){
			((TSegmentItem*)pStyItem->aItems->Items[i])->iSegNo++;
			((TSegmentItem*)pStyItem->aItems->Items[i])->iInd++;
		}
	}
	else{ //先插后删
		pStyItem->aItems->Insert( indTo, pSegFrom );
		pStyItem->aItems->Delete( indFrom );

		for( int i=indFrom; i<indTo; i++ ){
			((TSegmentItem*)pStyItem->aItems->Items[i])->iSegNo--;
 			((TSegmentItem*)pStyItem->aItems->Items[i])->iInd--;
		}
	}


}
// ---------------------------------------------------------------------------

void TPreStylePanel::SwapSegments(  TSegmentItem* pItem1, TSegmentItem* pItem2  )
{
	if( !pItem1 || !pItem2 || pItem1==pItem2 )
		return;

    TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
	int ind1 = -1, ind2 = -1;
	TCommonItem* pSeg1 = NULL, *pSeg2 = NULL;

	for( int i=0; i<pStyItem->aItems->Count; i++ ){
		if( pItem1==pStyItem->aItems->Items[i]
						|| pItem2==pStyItem->aItems->Items[i]  ){
			if( ind1<0 ){
				ind1 = i;
				pSeg1 = (TCommonItem*)pStyItem->aItems->Items[i];
			}
			else{
				ind2 = i;
				pSeg2 = (TCommonItem*)pStyItem->aItems->Items[i];
				break;
			}
		}
	}

	if( pSeg1->prev )
		pSeg1->prev->next = pSeg2;
	if( pSeg2->next )
		pSeg2->next->prev = pSeg1;
	if( pSeg1->next!=pSeg2 )
		pSeg1->next->prev = pSeg2;
	if( pSeg2->prev!=pSeg1 )
		pSeg2->prev->next = pSeg1;

	TCommonItem* pTmpItem = pSeg1->prev;
	if( pSeg2->prev!=pSeg1 )
		pSeg1->prev = pSeg2->prev;
	else
		pSeg1->prev = pSeg2;
	pSeg2->prev = pTmpItem;

	pTmpItem = pSeg2->next;
	if( pSeg1->next!=pSeg2 )
		pSeg2->next = pSeg1->next;
	else
		pSeg2->next = pSeg1;
	pSeg1->next = pTmpItem;

	pStyItem->aItems->Delete( ind2 );
	pStyItem->aItems->Delete( ind1 );
	pStyItem->aItems->Insert( ind1, pSeg2 );
	pStyItem->aItems->Insert( ind2, pSeg1 );

	int iInd1 = pItem1->iInd, iSegNo1 = pItem1->iSegNo;
	pItem1->iInd = pItem2->iInd;
	pItem1->iSegNo = pItem2->iSegNo;
	pItem2->iInd = iInd1;
	pItem2->iSegNo = iSegNo1;
}
// ---------------------------------------------------------------------------

void TPreStylePanel::AddTempSegment( TSegmentItem* pSeg )
{
	Stop();

	int sType = pSeg->iSegType,
		sNo = pSeg->iSegNo;
	TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];

	int index = 0;
	for( int i=0; i<sType; i++ ){
		index += pStyItem->nSegNum[i];
	}

	if( sType<=SEGTYPE_FILL ){
		index += pStyItem->nSegNum[sType];
	}
	else{
		int t = sType-SEGTYPE_INTRO,
			n = sNo<4 ? 0 : 1;

		index += m_nIECount[t][0] + ( n==1 ? m_nIECount[t][1] : 0 );

		m_nIECount[t][n]++;
	}

	pStyItem->InsertSegment( index, pSeg, 0 );
	pStyItem->SetImport();

	m_nTotalLine++;
	ResetScrollBar();

	int iLine = 0;
	TCommonItem* pItem = pStyItem;
	while( pItem && pItem!=pSeg ){
		iLine++;
		pItem = GetNextItem( pItem );
	}

	SetSelect( pSeg, iLine-m_iTopLine );

	ShowSelItem();

	SetFocus();
}

TCommonItem* TPreStylePanel::GetSegmentHoverItem( TCommonItem* pItem, int& iHoverLine )
{
	TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
	TCommonItem* pHoverItem = NULL;

	bool bCanDrop = pStyItem->nSegNum[m_pDropItem->iType]<8;
	if( bCanDrop && m_pDropItem->iType >= SEGTYPE_INTRO ){
		int t = m_pDropItem->iType-SEGTYPE_INTRO,
			n = m_pDropItem->GetSegNo()<4 ? 0 : 1;
		bCanDrop = m_nIECount[t][n] < 4;
	}

	if( bCanDrop ){
		if( pItem->iType==m_pDropItem->iType ){
			if( pItem->iType < SEGTYPE_INTRO
						|| pItem->GetSegNo()<4 && m_pDropItem->GetSegNo()<4
						|| pItem->GetSegNo()>=4 && m_pDropItem->GetSegNo()>=4){
				pHoverItem = pItem;
			}
		}
		else{
			pHoverItem = pStyItem;
			iHoverLine = -m_iTopLine;
		}
	}

	if( !pHoverItem )
		iHoverLine = -1;

	return pHoverItem;
}
// ---------------------------------------------------------------------------

void __fastcall TPreStylePanel::DoImportSegment(TObject* Sender)
{
	if( m_pFocItem ){
		PostMessage( Parent->Handle, UM_IMPORTSEGMENT, 0, 0 );
	}
}
// ---------------------------------------------------------------------------

bool __fastcall TPreStylePanel::CheckModified()
{
	if( m_aItems->Count==0 )
		return false;

	TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];

	for( int i=0; i<pStyItem->aItems->Count; i++ ){
		TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
		for( int j=0; j<pSeg->aItems->Count; j++ ){
			TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
			if( pTrk->pStyle->idLoc==(UINT)-1 && pTrk->pStyle->idStyle==0 ){
				return true;
			}
		}
	}

	return false;
}
// ---------------------------------------------------------------------------

void __fastcall TPreStylePanel::NewStyle( TObject *Sender )
{
	if( Sender ){
		if( !QueryStyleSave() )
			return;
	}

	ClearAllItems();
	memset( m_nIECount, 0, sizeof(m_nIECount) );

	TStyleItem* pItem = new TStyleItem( NULL, OPT_FONTPROG | OPT_SAVE );
	pItem->SetImport();
	m_aItems->Add( pItem );

	m_pTopItem = pItem;
	SetFold( pItem, 0 );

	m_nTotalLine++;
	ResetScrollBar();
	Paint();

	g_pPreStyle = pItem;
}
// ---------------------------------------------------------------------------

bool TPreStylePanel::QueryStyleSave()
{
	if( CheckModified() ){
		String strMsg = "当前编辑的风格尚未保存，是否保存？";

		bool bUsed = false;
		if( g_pUseStyle ){
			for( int i=0; !bUsed && i<g_pUseStyle->aItems->Count; i++ ){
				TSegmentItem* pSeg = (TSegmentItem*)g_pUseStyle->aItems->Items[i];
				for( int j=0; j<pSeg->aItems->Count; j++ ){
					TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
					if( pTrk->pStyle->idLoc==(UINT)-1 && pTrk->pStyle->idStyle==0 ){
						bUsed = true;
						break;
					}
				}
			}
		}

		if( bUsed ){
			strMsg += "\n\n警告：不保存将导致当前工程失效！";
		}

		int ret = MessageForm->ShowMessage( strMsg, MB_ICONQUESTION|MB_YESNOCANCEL,
																			"提示" );
		if( mrCancel==ret ){
			return false;
		}
		else if( mrYes==ret ){
			Application->MainForm->Perform( UM_SAVELOCALSTYLE, 0, 0 );
		}
		else if( bUsed ){ //清空当前工程
			Application->MainForm->Perform( UM_NEWPROJECT, 0, 0 );
		}

		if( GetStyleInfo( -1, 0 ) ){
			 f_CM_DeleteTempStyle( 0 );
			 DeleteStyleInfo( -1, 0 );
		}
	}

	return true;
}
// ---------------------------------------------------------------------------

bool __fastcall TPreStylePanel::GetPrebeat( BYTE* pData, int& nSize )
{
	if( m_aItems->Count==0 )
		return false;

	TStyleItem* pStyItem = GetStyleItem();
	TTrack* pDrumTrk = NULL;
	for( int i=0; !pDrumTrk && i<pStyItem->aItems->Count; i++ ){
		TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
		int stype = pSeg->GetSegType();

		if( stype==SEGTYPE_VAR ){
			for( int j=0; j<pSeg->aItems->Count; j++ ){
				TTrack* pTrk = ((TTrackItem*)pSeg->aItems->Items[j])->pTrack;

				if( pTrk->iChanSpec==9 ){
					pDrumTrk = pTrk;
					break;
				}
			}
		}
	}

	if( pDrumTrk ){
		int nStageNum = 1;
		TStage* aStages = new TStage[nStageNum];
		aStages[0].iSegType = SEGTYPE_VAR;
		aStages[0].iSegKey = 0;
		aStages[0].nBarNum = 4;
		aStages[0].aChords = new TBarChords[aStages[0].nBarNum];
		for( int j=0; j<4; j++ ){
			aStages[0].aChords[j].iKey[0]
					= aStages[0].aChords[j].iKey[1]
					= aStages[0].aChords[j].iKey[2]
					= aStages[0].aChords[j].iKey[3] = 0;
			aStages[0].aChords[j].iType[0]
					= aStages[0].aChords[j].iType[1]
					= aStages[0].aChords[j].iType[2]
					= aStages[0].aChords[j].iType[3] = 0;
		}

		//tracks
		aStages[0].nTrkNum = 1;
		aStages[0].aTracks = new TComposeTrack[aStages[0].nTrkNum];
		aStages[0].aTracks[0].iStyleLoc = pDrumTrk->iStyleLoc;// >pStyle->idLoc;
		aStages[0].aTracks[0].iStyleId = pDrumTrk->iStyleId;// >pStyle->idStyle;
		aStages[0].aTracks[0].iSegNo = pDrumTrk->iSegNo;
		aStages[0].aTracks[0].iChanNo = pDrumTrk->iChanNo;
		aStages[0].aTracks[0].iChanSpec = pDrumTrk->iChanSpec;
		aStages[0].aTracks[0].iProg = pDrumTrk->iProg;
		aStages[0].aTracks[0].nVol = 110;

		int ret = f_CM_Compose( &nSize, pData, g_iMelodyTimeSignature, g_nMelodyTempo,
										nStageNum, aStages, false, NULL, NULL );

		if( ret==0 ){
			return true;
		}
	}

	return false;
}
// ---------------------------------------------------------------------------

void __fastcall TPreStylePanel::DoChangeFontProg(TObject* Sender)
{
	if( Sender )
		SetSelect( m_pFocItem, m_iFocLine );

	TMultiSwitchProgForm *form = new TMultiSwitchProgForm(this, m_pSelItem);
	if( mrOk==form->ShowModal() ){
		for(int i = 0; i < form->ItemChange->Count; i++) {
			TTrackItem *Item = (TTrackItem *)form->ItemChange->Items[i];
			//InstrumentChanged(Item);
		}
	}
	delete form;

	if( m_pSelItem->iType==SEGTYPE_STYLE )
		Repaint();
	else
		DrawItem( m_pSelItem, m_iSelLine, -1 );
}
// ---------------------------------------------------------------------------

void __fastcall TPreStylePanel::DoChangeTexture(TObject* Sender)
{
	Stop( STOP_ALL );

	if( Sender )
		SetSelect( m_pFocItem, m_iFocLine );

	TTrackItem *pItem = (TTrackItem *)m_pSelItem ;
	TTrack* pTrk = pItem->pTrack;
	char progOri = -1;
	int st = pItem->GetSegType();
	int sn = pTrk->iSegNo;

	if( pItem->pStyle->idLoc==0 ){
		for( int t=0; t<16; t++ ){
			if( pItem->pStyle->pOrigin->detail.tracks[st][sn][t].no==pTrk->iChanNo ){
				progOri = pItem->pStyle->pOrigin->detail.tracks[st][sn][t].prog;
				break;
			}
		}

	}else if( pItem->pStyle->idLoc!=1 ){
		for( int t=0; t<16; t++ ){
			if( pItem->pStyle->pLocal->trkRef[st][sn][t].chan==pTrk->iChanNo ){
				progOri = pItem->pStyle->pLocal->trkRef[st][sn][t].prog;
				break;
			}
		}
	}

	if( progOri!=-1 ) {
		TSwitchTextureForm *pProgPar = new TSwitchTextureForm(NULL, (1<<st), progOri, pTrk->iBank,
																	pTrk->iProg, pItem->pStyle,
																	pTrk->iChanNo, sn );

		if(pProgPar->ShowModal() == mrOk){
/*			TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();

			for( int s=0; s<pStyleItem->aItems->Count; s++ ){
				TSegmentItem* pSegItem = (TSegmentItem*)pStyleItem->aItems->Items[s];

				for( int t=0; t<pSegItem->aItems->Count; t++ ){
					TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[t];

					if( pTrkItem==pItem ) {
*/						if( pProgPar->m_bSetCur ) {
							pTrk->iProg = pProgPar->m_cSetProg;
							pTrk->nVol  = pProgPar->m_cSetVol;
							pTrk->iBank = 0xFF;
						}
						pTrk->iProgOrig = pProgPar->m_cSetProgOri;
						pTrk->iSegNo    = pProgPar->m_cSetSegNo;
						pTrk->iChanNo   = pProgPar->m_cSetchan;
						pTrk->nVolOrig  = pProgPar->m_cSetVolOri;
						pTrk->iStyleLoc = pProgPar->m_pSetStyle->idLoc;
						pTrk->iStyleId  = pProgPar->m_pSetStyle->idStyle;
						pItem->pStyle 	= pProgPar->m_pSetStyle;
/*
						break;
					}
				}
			}
*/
			DrawItem( m_pSelItem, m_iSelLine, -1 );
		}

		delete pProgPar;
	}
}
// ---------------------------------------------------------------------------

