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

#include <vcl.h>
#pragma hdrstop

#include "SwitchProgFormUnit.h"
#include "GlobalUnit.h"
#include "Instruments.h"
#include "VSTiFormUnit.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TextButton"
#pragma link "PNGButton"
#pragma link "GeneralDialogPanel"
#pragma link "CKBox"
#pragma resource "*.dfm"


TSwitchProgForm *SwitchProgForm;
//---------------------------------------------------------------------------

__fastcall TSwitchProgForm::TSwitchProgForm(TComponent* Owner, BYTE iFont, BYTE iProg, BYTE iChno )
	: TForm(Owner)
{
	m_iChno = m_iChnoOrig = iChno;
	m_iProg = m_iProgOrig = iProg;
	m_iFontOrig = iFont;
	m_iFont = ( iFont==0xFF && !g_bExtFont )? g_idFont : iFont;
	m_bVSTi = iFont!=0xFF && iFont>=0x80;
}
//---------------------------------------------------------------------------

__fastcall TSwitchProgForm::~TSwitchProgForm()
{
	f_MM_Stop();

	if( m_lvSoundFont ){
		delete m_lvSoundFont;
		m_lvSoundFont = NULL;
	}

	if( m_lvProgram ){
		delete m_lvProgram;
		m_lvProgram = NULL;
	}
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::FormCreate(TObject *Sender)
{
	m_BKGPanel->Font->Size = g_szFont9;
	m_btnOk->FontSize = g_szFont9;
	m_btnCancel->FontSize = g_szFont9;
	m_btnSet->FontSize = g_szFont9;

	m_lvSoundFont = new TListPanel(this);
	m_lvSoundFont->Parent = m_panFont;
	m_lvSoundFont->Align = alClient;
//	m_lvSoundFont->Parent = m_BKGPanel;
//	m_lvSoundFont->SetBounds( 27, 79, 156, 204 );
	m_lvSoundFont->SetTextFont(g_strTxtFontName, g_szFont9);

	m_lvProgram = new TListPanel(this);
	m_lvProgram->Parent = m_panProg;
	m_lvProgram->Align = alClient;
//	m_lvProgram->Parent = m_BKGPanel;
//	m_lvProgram->SetBounds( 201, 79, 156, 204 );
	m_lvProgram->SetTextFont(g_strTxtFontName, g_szFont9);
	m_lvProgram->OnDblClick = ProgramDblClick;

	if( m_bVSTi ){
		m_tabVSTi->BringToFront();
		m_tabVSTi->Down = true;
		m_tabSF2->Down = false;
		m_btnSet->Visible = true;
	}

	ResetComponents( true );

	SetTransparent( this );
}
//---------------------------------------------------------------------------

void TSwitchProgForm::ResetComponents( bool bInit )
{
	InitSoundFontList();
	InitProgramList();

	if( !bInit ){
		m_lvSoundFont->ResetScroll();
		m_lvProgram->ResetScroll();
	}

	m_lblProgram->Caption = m_bVSTi ? L"通道/乐器" : L"音色/乐器";

	m_btnOk->Enabled = !( m_lvSoundFont->SelectedItemIndex<0
							|| m_lvProgram->SelectedItemIndex<0 );
	m_btnSet->Enabled = m_bVSTi && m_lvSoundFont->SelectedItemIndex>=0;
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::InitSoundFontList()
{
	m_lvSoundFont->Clear();

	int iSel = -1;
	if( m_bVSTi ){
		for( int i=0; i<g_lstVSTi.size(); i++ ){
			VSTINFO* pVSTi = g_lstVSTi[i];
			TListPanelItem* pItem = new TListPanelItem( pVSTi->strVSTName, DoItemClick );
			pItem->Tag = i + 0x80;

			if( m_iFont==pItem->Tag ){
				iSel = i;
			}

			m_lvSoundFont->AddItem( pItem );
		}
	}
	else{
		for( int i=0; i<g_lstFonts.size(); i++ ){
			FONTINFO* pFont = g_lstFonts[i];

			if( m_iChno==9 && pFont->nDrumCount>0
							|| m_iChno!=9 && pFont->nInstCount>0 ){
				TListPanelItem* pItem = new TListPanelItem( pFont->strFontName, DoItemClick );
				pItem->Tag = i;

				if( g_bExtFont && m_iFont==0xFF ){
					int ind = m_iProg / 8;
					if( g_lstFonts[i]==g_lstCZFonts[ind] )
						iSel = m_lvSoundFont->ItemsCount;
				}
				else if( i==m_iFont ){
					iSel = m_lvSoundFont->ItemsCount;
				}

				m_lvSoundFont->AddItem( pItem );
			}
		}
	}

	m_lvSoundFont->SelectedItemIndex = iSel;
}

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

void __fastcall TSwitchProgForm::InitProgramList()
{
	m_lvProgram->Clear();

	if( m_lvSoundFont->SelectedItemIndex<0 )
		return;

	int ind = -1;
	if( m_bVSTi ){
		VSTINFO* pInfo = g_lstVSTi[m_iFont-0x80];
		int iNamedChan = -1, iPlugin = -1;
		if( pInfo->aPlugins.size()>0 ){
			iPlugin = 0;
			iNamedChan = pInfo->aPlugins[iPlugin]->id;
		}
		for( int i=0; i<16; i++ ){
			char text[32];

			if( i==iNamedChan ){
				strcpy( text, pInfo->aPlugins[iPlugin]->name );

				if( ++iPlugin<pInfo->aPlugins.size() )
					iNamedChan = pInfo->aPlugins[iPlugin]->id;
				else
					iNamedChan = -1;
			}
			else
				sprintf( text, "Channel %d", i+1 );

			TListPanelItem* pItem = new TListPanelItem( text, DoItemClick );
			pItem->Tag = i;
			m_lvProgram->AddItem( pItem );

			if( m_lvSoundFont->SelectedItemIndex>=0 && pItem->Tag==m_iChno )
				ind = i;
		}
	}
	else{
		FONTINFO* pFI = NULL;

		if( g_bExtFont && m_iFont==0xFF ){
			int ind = m_iProg / 8;
			pFI = g_lstCZFonts[ind];
		}
		else{
			pFI = g_lstFonts[m_iFont];
		}

		int num = m_iChno==9 ? pFI->nDrumCount : pFI->nInstCount;
		FONTPRESET* pSet = ( m_iChno==9 ? pFI->aDrums : pFI->aInsts );
		char** strInst = NULL;

		if( m_iChno!=9 ){
			if( !strcmp( pFI->strFontName, g_strDefaultSoundSet ) || !strcmp( pFI->strFontName, "Pop default" ) )
				strInst = GM_INSTRUMENT;
			else{
				bool bExtend = false;
				for( int i=0; i<16; i++ ){
					if( pFI == g_lstCZFonts[i] ){
						bExtend = true;
						break;
					}
				}

				if( bExtend )
					strInst = GM_INSTRUMENT;
			}
		}

		for( int i=0; i<num; i++ ){
			char* text = strInst ? strInst[pSet[i].id] : pSet[i].text;

			TListPanelItem* pItem = new TListPanelItem( text, DoItemClick );
			pItem->Tag = pSet[i].id;
			m_lvProgram->AddItem( pItem );

			if( pItem->Tag==m_iProg )
				ind = i;
		}
	}

	m_lvProgram->SelectedItemIndex = ind;
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::DoItemClick(TListPanel *Sender, int Index)
{
	if( Index<0 || Index>=Sender->ItemsCount )
		return;

	TListPanelItem* pItem = Sender->GetItem( Index );
	int iSel = pItem->Tag;

	if( Sender==m_lvSoundFont && ( m_iFont!=iSel || m_bVSTi ) ){
		bool bReset = m_iFont!=iSel;

		if( bReset ){
			m_iFont = iSel;
			m_lvProgram->Clear();
		}

		if( m_bVSTi ){
			ShowVSTiPanel( bReset );
		}
		else{
			f_MM_Stop();

			m_iProg = -1;
			InitProgramList();
			m_lvProgram->ResetScroll();
		}
	}
	else if( Sender==m_lvProgram && ( m_bVSTi && m_iChno!=iSel
									|| !m_bVSTi && m_iProg!=iSel )){
		f_MM_Stop();

		if( m_bVSTi )
			m_iChno = iSel;
		else
			m_iProg = iSel;
	}

	m_btnOk->Enabled = !( m_lvSoundFont->SelectedItemIndex<0
							|| m_lvProgram->SelectedItemIndex<0 );
	m_btnSet->Enabled = m_bVSTi && m_lvSoundFont->SelectedItemIndex>=0;
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::ProgramDblClick(TObject *Sender)
{
	if( m_lvProgram->SelectedItemIndex>=0 ){
		TListPanelItem* pItem = m_lvProgram->GetItem( m_lvProgram->SelectedItemIndex );
		int iChno = m_bVSTi ? pItem->Tag : -1,
			iProg = m_bVSTi ? -1 : pItem->Tag;
		char* strFile = m_iFont==0xFF ? NULL : m_iFont<0x80 ? g_lstFonts[m_iFont]->strFileName
														: g_lstVSTi[m_iFont-0x80]->strFileName;

		f_MM_PlayDemo( Handle, m_iStartBar, iChno, iProg, m_iFont, strFile );
	}
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::VSTSetClick(TObject *Sender)
{
	ShowVSTiPanel( false );
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::SF2Click(TObject *Sender)
{
	if( m_bVSTi )
		SwitchFontType( false );
}
//---------------------------------------------------------------------------

void __fastcall TSwitchProgForm::VSTiClick(TObject *Sender)
{
	if( !m_bVSTi )
		SwitchFontType( true );
}
//---------------------------------------------------------------------------

void TSwitchProgForm::SwitchFontType( bool bVSTi )
{
	f_MM_Stop();

	BYTE iFont = m_iFontOrig;
	m_iFont = ( iFont==0xFF && !g_bExtFont )? g_idFont : iFont;
	m_iProg = m_iProgOrig;
	m_iChno = m_iChnoOrig;
	m_bVSTi = bVSTi;

	if( bVSTi )
		m_tabVSTi->BringToFront();
	else
		m_tabSF2->BringToFront();

	m_tabVSTi->Down = bVSTi;
	m_tabSF2->Down = !bVSTi;

	ResetComponents();
	m_btnSet->Visible = m_bVSTi;
}
//---------------------------------------------------------------------------

void TSwitchProgForm::ShowVSTiPanel( bool bReset )
{
	//显示VSTi设置窗口
	f_MM_Stop();

	int iChno = m_iChno<0 ? m_iChnoOrig : m_iChno;
	TVSTiForm* pVI = new TVSTiForm( NULL, m_iFont, iChno, m_iStartBar, m_lenBar );

	if( mrOk==pVI->ShowModal() ){
		VSTINFO* pInfo = g_lstVSTi[m_iFont-0x80];
		while( !pInfo->aPlugins.empty() ){
			delete pInfo->aPlugins.back();
			pInfo->aPlugins.pop_back();
		}

		char ch[16];
		char szName[16][64];
		int count = f_MM_GetVSTiPrograms( m_iFont, ch, szName );

		for( int i=0; i<count; i++ ){
			VSTPLUGIN* pProg = new VSTPLUGIN;
			pProg->id = ch[i];
			strcpy( pProg->name, szName[i] );

			pInfo->aPlugins.push_back( pProg );
		}

		m_iChno = pVI->m_iChno;

		InitProgramList();
		m_lvProgram->ResetScroll();

		if( pVI->IsEditable() )
			f_MM_SaveVSTParams( -1, m_iFont, true );
	}
	else{
		if( pVI->IsEditable() )
			f_MM_SaveVSTParams( -1, m_iFont, false );

		if( bReset ){
			m_iFont = m_iFontOrig;
			m_lvSoundFont->SelectedItemIndex = -1;
		}
	}

	delete pVI;
}
//---------------------------------------------------------------------------

