// EventsHistoryPage.cpp : implementation file
//

#include "stdafx.h"
#include "supervis.h"
#include "EventsHistoryPage.h"

//included for _chdir
#include <direct.h> 


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CEventsHistoryPage property page

IMPLEMENT_DYNCREATE(CEventsHistoryPage, CPropertyPage)

CEventsHistoryPage::CEventsHistoryPage() : CPropertyPage(CEventsHistoryPage::IDD)
{
	//{{AFX_DATA_INIT(CEventsHistoryPage)
	m_bShowBankWithId = FALSE;
	m_bShowEventWithId = FALSE;
	m_lBankId = 0;
	m_lEventId = 0;
	m_bDebugBreak = FALSE;
	m_bFirstOccurence = FALSE;
	m_bWatchMode = FALSE;
	m_LCBPath = _T("");
	//}}AFX_DATA_INIT
}

CEventsHistoryPage::~CEventsHistoryPage()
{
}

void CEventsHistoryPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEventsHistoryPage)
	DDX_Control(pDX, IDC_WATCH_LIST, m_WatchList);
	DDX_Control(pDX, IDC_EVENTS_HISTORY_LIST, m_EventsList);
	DDX_Check(pDX, IDC_CHECK_BANK, m_bShowBankWithId);
	DDX_Check(pDX, IDC_CHECK_EVENT, m_bShowEventWithId);
	DDX_Text(pDX, IDC_EDIT_BANK_ID, m_lBankId);
	DDV_MinMaxLong(pDX, m_lBankId, 0, 256);
	DDX_Text(pDX, IDC_EDIT_EVENT_ID, m_lEventId);
	DDV_MinMaxLong(pDX, m_lEventId, 0, 1024);
	DDX_Check(pDX, IDC_CHECK_DEBUG_ON_EVENT, m_bDebugBreak);
	DDX_Check(pDX, IDC_CHECK_FIRST_OCCUR, m_bFirstOccurence);
	DDX_Check(pDX, IDC_CHECK_WATCH, m_bWatchMode);
	DDX_Text(pDX, IDC_EDIT_LCB_PATH, m_LCBPath);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CEventsHistoryPage, CPropertyPage)
	//{{AFX_MSG_MAP(CEventsHistoryPage)
	ON_BN_CLICKED(IDC_RESET_BUTTON, OnResetButton)
	ON_BN_CLICKED(IDC_CHECK_FIRST_OCCUR, OnCheckFirstOccur)
	ON_BN_CLICKED(IDC_CHECK_BANK, OnCheckBank)
	ON_BN_CLICKED(IDC_CHECK_EVENT, OnCheckEvent)
	ON_EN_CHANGE(IDC_EDIT_BANK_ID, OnChangeEditBankId)
	ON_EN_CHANGE(IDC_EDIT_EVENT_ID, OnChangeEditEventId)
	ON_BN_CLICKED(IDC_HELP_WATCH, OnHelpWatch)
	ON_BN_CLICKED(IDC_CHECK_WATCH, OnCheckWatch)
	ON_BN_CLICKED(IDC_EMPTY_WATCH, OnEmptyWatch)
	ON_BN_CLICKED(IDC_BROWSE_FOR_LCB, OnBrowseForLcb)
	ON_BN_CLICKED(IDC_PAUSE_BUTTON, OnPauseButton)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEventsHistoryPage message handlers

BOOL CEventsHistoryPage::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();

	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
	
	//Initialise the ClistCtrl containing Events descriptions
	LV_COLUMN* lvc;

	lvc = (LV_COLUMN*)malloc(sizeof(LV_COLUMN));

	lvc->mask = LVCF_FMT |LVCF_SUBITEM 
		| LVCF_TEXT | LVCF_WIDTH;			// members contain valid information
    lvc->fmt = LVCFMT_LEFT;					// Alignment of the column
    lvc->cx = 75;							// width of the column, in pixels
    lvc->pszText = "Time";					// column heading 
    lvc->iSubItem = 0;						// index of subitem associated with column
	m_EventsList.InsertColumn(0, lvc);


	lvc->pszText = "Event Name";			// column heading 
	lvc->cx = 125;							// width of the column, in pixels
    lvc->iSubItem = 1;						// index of subitem associated with column
	m_EventsList.InsertColumn(1, lvc);

	lvc->pszText = "Event Id";				// column heading 
	lvc->cx = 60;							// width of the column, in pixels
    lvc->iSubItem = 2;						// index of subitem associated with column
	m_EventsList.InsertColumn(2, lvc);
	
	lvc->pszText = "Bank Name";				// column heading 
	lvc->cx = 100;							// width of the column, in pixels
    lvc->iSubItem = 3;						// index of subitem associated with column
	m_EventsList.InsertColumn(3, lvc);
	
	lvc->pszText = "Bank Id";				// column heading 
	lvc->cx = 60;							// width of the column, in pixels
    lvc->iSubItem = 4;						// index of subitem associated with column
	m_EventsList.InsertColumn(4, lvc);

	
	lvc->cx = 100;							// width of the column, in pixels
	lvc->pszText = "Event Type";					// column heading 
    lvc->iSubItem = 5;						// index of subitem associated with column
	m_EventsList.InsertColumn(5, lvc);


	free( lvc );

	
	//Set the limit length of the edit box
	((CEdit *)(GetDlgItem(IDC_EDIT_BANK_ID)))->LimitText(3);
	((CEdit *)(GetDlgItem(IDC_EDIT_EVENT_ID)))->LimitText(3);

	//Set LCB Edit box
	((CEdit *)(GetDlgItem(IDC_EDIT_LCB_PATH)))->SetReadOnly( TRUE );


	//Add the LCB Path
	if (pSuperVisApp->m_cLCBPath == "NoLCBPath")
		m_LCBPath = "No LCB file found in the registry. Select One.";
	else
		m_LCBPath = pSuperVisApp->m_cLCBPath + pSuperVisApp->m_cLCBFileTitle + ".lcb";


	//Init du "pause" mode
	m_bPauseProcess = FALSE;
	
	UpdateData(FALSE);

	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}


void CEventsHistoryPage::RefreshEventsHistoList()
{


	long i;

	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();


	//Clear the list
	m_EventsList.DeleteAllItems();
	
	
	//Cycle through the pointer Array to filter
	for (i = 0; i < pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetSize(); i ++ )
	{
		FilterAndDisplayEvent(i);

	}	

}

void CEventsHistoryPage::FilterAndDisplayEvent(long lIndex)
{	

	char buffer[25];
	
	unsigned long ulBankId;
	unsigned long ulEventId;
	

	EventsHistElement *evtHisto, *evtHistoFirstOccurTest;
	
	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();

	evtHisto = (EventsHistElement *)(pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetAt(lIndex));

	ulBankId = (0xFFFF0000 & evtHisto->evt_Id) >> 16;
	ulEventId= (0x0000FFFF & evtHisto->evt_Id);

	//
	//Check if we have have to filter the events
	//******************************************

	//Retrieve data from the control
	PostMessage(WM_USER_UPDATE_DATA, 0, 0);

	//If the watch checkBox is checked we need to filter
	if(m_bWatchMode)
	{

		BOOL bIsInWatchList = FALSE;
		int i;
		int iCount = m_WatchList.GetCount();
		
		//if list is empty with dont display anything
		if (iCount == 0)
			return;
		
		
		for (i = 0; i < iCount; i++)
		{
			//Look through the watch list for the same Event ID
			if (evtHisto->evt_Id == (tdxId)m_WatchList.GetItemData(i))
				bIsInWatchList = TRUE;
			
		}

		//if the event wasnt in the watch list we leave
		if(!bIsInWatchList)
			return;


	} 
	else
	{

		if (m_bShowEventWithId)
		{
			if (m_lEventId != (long)ulEventId)
				return;

		}

		if (m_bShowBankWithId)
		{
			if (m_lBankId != (long)ulBankId)
				return;
		}
	}

	if(m_bFirstOccurence)
	{
		
		long i;

		//look in the Events array from 0 to the current event we are filtering.
		//We dont  want to compare it with himself , hence the " -1 " in the loop.
		for(i = 0; i < lIndex ; i++)
		{
			evtHistoFirstOccurTest = (EventsHistElement *)(pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetAt(i));
			if (evtHisto->evt_Id == evtHistoFirstOccurTest->evt_Id)
				return;
		}
	}

	
	//Check if we have to debugbreak before displaying the events
	if(m_bDebugBreak)
	{
		DebugBreak();
	}



	//Display time
	sprintf(buffer,"%02d:%02d:%02d:%03d",
		evtHisto->time.wHour,
		evtHisto->time.wMinute,
		evtHisto->time.wSecond,
		evtHisto->time.wMilliseconds);
	m_EventsList.InsertItem( 0, buffer );


	//Set the item data with the eventsArray index, to be used later for drag&drop, pop-memnu, etc.
	m_EventsList.SetItemData( 0, (DWORD)lIndex );


	//Event Name
	m_EventsList.SetItem(0, 1, LVIF_TEXT, (LPCSTR)evtHisto->cEvtName, 0, 0, 0, NULL );

	//Event ID 
	sprintf(buffer, "%lu", ulEventId);
	m_EventsList.SetItem(0, 2, LVIF_TEXT, buffer, 0, 0, 0, NULL );

	//Bank Name
	m_EventsList.SetItem(0, 3, LVIF_TEXT, (LPCSTR)evtHisto->cEvtBankName, 0, 0, 0, NULL );
	
	//Bank ID 
	sprintf(buffer, "%lu", ulBankId);
	m_EventsList.SetItem(0, 4, LVIF_TEXT, buffer, 0, 0, 0, NULL );
	
	
	
	//Type
	switch(evtHisto->evt_eType){

	case EVT_SON_STOP_ALL:
		sprintf(buffer, "EVT_SON_STOP_ALL");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_STOP_N_GO:
		sprintf(buffer, "EVT_SON_STOP_N_GO");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_EFFET:
		sprintf(buffer, "EVT_SON_EFFET");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_PITCH:
		sprintf(buffer, "EVT_SON_PITCH");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_VOLUME:
		sprintf(buffer, "EVT_SON_VOLUME");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_PAN:
		sprintf(buffer, "EVT_SON_PAN");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_PLAY:
		sprintf(buffer, "EVT_SON_PLAY");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;
	case EVT_SON_STOP:
		sprintf(buffer, "EVT_SON_STOP");
		m_EventsList.SetItem(0, 5, LVIF_TEXT, buffer, 0, 0, 0, NULL );
		break;

	}


}

void CEventsHistoryPage::OnResetButton() 
{

	int i;
	EventsHistElement* temp;

	
	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();

	
	//Free the events history array
	for (i= 0;  i < pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetSize() ;i++)
	{
		temp = (EventsHistElement *)(pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetAt(i));
		delete temp;
	}

	pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.RemoveAll();


	//Empty the CListCtrl
	m_EventsList.DeleteAllItems();
	
}

void CEventsHistoryPage::OnCheckFirstOccur() 
{
	
	//Update the variable
	UpdateData(TRUE);
	RefreshEventsHistoList();
	
}

void CEventsHistoryPage::OnCheckBank() 
{

	//Update the variable
	UpdateData(TRUE);

	if (m_bShowBankWithId)
	{
		GetDlgItem(IDC_CHECK_WATCH)->EnableWindow(FALSE);
	}
	else
	{
		GetDlgItem(IDC_CHECK_WATCH)->EnableWindow(TRUE);
	}

	RefreshEventsHistoList();
	
}

void CEventsHistoryPage::OnCheckEvent() 
{
	
	//Update the variable
	UpdateData(TRUE);
	
	if (m_bShowEventWithId)
	{
		GetDlgItem(IDC_CHECK_WATCH)->EnableWindow(FALSE);
	}
	else
	{
		GetDlgItem(IDC_CHECK_WATCH)->EnableWindow(TRUE);
	}
	
	RefreshEventsHistoList();
	
}


void CEventsHistoryPage::OnChangeEditBankId() 
{

	//Keep the bank Id in the 0 - 256 range
	UpdateData(TRUE);
	if (m_lBankId > 256)
	{
		m_lBankId = 256;
		UpdateData(FALSE);

	}

	RefreshEventsHistoList();

}

void CEventsHistoryPage::OnChangeEditEventId() 
{

	//Keep the Event Id in the 0 - 1024 range
	UpdateData(TRUE);
	if (m_lEventId > 1024)
	{
		m_lEventId = 1024;
		UpdateData(FALSE);

	}


	RefreshEventsHistoList();
	
}

void CEventsHistoryPage::OnHelpWatch() 
{

	MessageBox("The Watch List allow to show a selected group of events. Right-click on the Events List Historic to add a new events	","Watch List Help",MB_OK);
	
	
}

void CEventsHistoryPage::OnCheckWatch() 
{
	
	UpdateData(TRUE);

	
	if(m_bWatchMode)
	{
		//If we are in Watch List mode we disable the normal mode
		GetDlgItem(IDC_CHECK_BANK)->EnableWindow(FALSE);	
		GetDlgItem(IDC_EDIT_BANK_ID)->EnableWindow(FALSE);	
		GetDlgItem(IDC_CHECK_EVENT)->EnableWindow(FALSE);	
		GetDlgItem(IDC_EDIT_EVENT_ID)->EnableWindow(FALSE);	
	}
	else
	{
		
		GetDlgItem(IDC_CHECK_BANK)->EnableWindow(TRUE);	
		GetDlgItem(IDC_EDIT_BANK_ID)->EnableWindow(TRUE);	
		GetDlgItem(IDC_CHECK_EVENT)->EnableWindow(TRUE);	
		GetDlgItem(IDC_EDIT_EVENT_ID)->EnableWindow(TRUE);	
	}

	RefreshEventsHistoList();

}


void CEventsHistoryPage::SendEventInWatchList()
{
	unsigned long ulBankId;
	unsigned long ulEventId;
	int iArrayIndex;
	EventsHistElement *evtHisto;

	char buffer[50];

	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
	
	// The index of the selected item
	int i = m_EventsList.GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);


	//retrieve the array index 
	iArrayIndex = m_EventsList.GetItemData(i);
	
	
	//Retrieve the event
	evtHisto = (EventsHistElement *)(pSuperVisApp->m_SuperVisThread->m_apEventHistoArray.GetAt(iArrayIndex));

	ulBankId = (0xFFFF0000 & evtHisto->evt_Id) >> 16;
	ulEventId= (0x0000FFFF & evtHisto->evt_Id);

	
	sprintf(buffer, "%s   E%lu:B%lu",evtHisto->cEvtName, ulEventId, ulBankId);
	int iWatchListIndex = m_WatchList.AddString( buffer );


	//We associate the event ID with the itemdata of the listbox.
	//Will be use to compare when a new event will be add in the 
	//events Historic list.
	m_WatchList.SetItemData(iWatchListIndex, (DWORD)evtHisto->evt_Id);


}

void CEventsHistoryPage::OnEmptyWatch() 
{
	m_WatchList.ResetContent();
	RefreshEventsHistoList();
	
}

void CEventsHistoryPage::OnBrowseForLcb() 
{
	BrowseForLcb();
}


BOOL CEventsHistoryPage::PreTranslateMessage(MSG* pMsg) 
{
	
	//We send the updatedata(TRUE) here
	//We cannot pass the CWnd across thread and this cause problem while using updatedata
	if (pMsg->message == WM_USER_UPDATE_DATA){
		UpdateData(TRUE);
	}
	

	return CPropertyPage::PreTranslateMessage(pMsg);
}

void CEventsHistoryPage::OnPauseButton() 
{
	if(m_bPauseProcess)
	{
		m_bPauseProcess = FALSE;

		GetDlgItem(IDC_PAUSE_BUTTON)->SetWindowText("&Pause Process");

		//We refresh the list to add the event thatwe missed during pause.
		RefreshEventsHistoList();
	} 
	else
	{
		m_bPauseProcess = TRUE;

		GetDlgItem(IDC_PAUSE_BUTTON)->SetWindowText("&Unpause Process");
	}
	
}

BOOL CEventsHistoryPage::BrowseForLcb()
{

		int iNbChar;
	CString strFileName;
	
	CString cCurrentPath = m_LCBPath.Left(m_LCBPath.ReverseFind('\\') + 1);
	_chdir((LPCSTR)cCurrentPath);

	CFileDialog dlg( TRUE,"lcb","*.lcb",
	                 OFN_FILEMUSTEXIST,
	                 _T("SoundEditor|LCB |"));



	int nResponse = dlg.DoModal();
	
	if (nResponse == IDOK)
	{
		
		//We have to extract the path, GetpathName include the filename
		m_LCBPath = dlg.GetPathName();
		((CSupervisApp* )AfxGetApp())->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_LCBPath = m_LCBPath;
		UpdateData(FALSE);

		//To use with hybrid library
		((CSupervisApp*)AfxGetApp())->m_cLCBFileTitle = dlg.GetFileTitle();

		strFileName = dlg.GetFileName();

	
		iNbChar = m_LCBPath.GetLength() - strFileName.GetLength();
		((CSupervisApp* )AfxGetApp())->m_cLCBPath = m_LCBPath.Left( iNbChar );
		return TRUE;

	}
	else if (nResponse == IDCANCEL)
	{
		return FALSE;
	
	}

	return TRUE;	

}
