// supervis.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "supervis.h"
#include "SNDinc.h"
#include "snddll.h"

#include "snddbg.h"
#include "sndplay.h"
#include "sndvect.h"
#include "sndres.h"
#include "sndini.h"
#include "sndtheme.h"
#include "sndvirt.h"
#include "sndevent.h"


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

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CSupervisApp

BEGIN_MESSAGE_MAP(CSupervisApp, CWinApp)
	//{{AFX_MSG_MAP(CSupervisApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSupervisApp construction

CSupervisApp::CSupervisApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance

	//Create the SuperVisater Main Mutex. Used to synchro thread;
	SuperVisMutex = new CMutex(FALSE, NULL, NULL );

	//Event used when waiting for SuperVisater Thread to complete initialisation
	LaunchSuperVisEvent = new CEvent(FALSE, TRUE, NULL, NULL );


	//Event used in AddHistoric synchronisaion
	AddHistoSyncEvent = new CEvent(FALSE, FALSE, NULL, NULL );


}

/////////////////////////////////////////////////////////////////////////////
// The one and only CSupervisApp object

CSupervisApp theApp;


BOOL CSupervisApp::InitInstance() 
{

	//Set the Key for registry. We have to init the function SetRegistrey() in
	//InitInstance() because it is a protected member function of CWinApp
/*
	//CString curDir;
	char curDir[256];
	GetCurrentDirectory(256,curDir);

	static char szDllDirectory[256]=".";


	//strncpy(curDir,SND_fn_szGetSoftDirectory(), sizeof(curDir) - 1);
	
	SetRegistryKey( "Ubi Sound Studio" );
	
	//Get the registry configuration

	//Key for the application
	m_iActivePage = GetProfileInt("Settings", "ActivePage", 0);
	m_iWindowLeft = GetProfileInt("Settings", "WindowLeft", 268);
	m_iWindowTop = GetProfileInt("Settings", "WindowTop", 121);
	m_iWindowRight = GetProfileInt("Settings", "WindowRight", 1048);
	m_iWindowBottom = GetProfileInt("Settings", "WindowBottom", 888);
	
	//SuperVisSetting key
	m_cBinaryLCBPath = GetProfileString("SettingsPage", "BinaryLCBPath", "NoLCBPath");
	m_cBinaryLCBFileTitle = GetProfileString("SettingsPage", "BinaryLCBFileTitle", "NoLCBFileTitle");
	m_bWindowOnTop = GetProfileInt("SettingsPage", "AlwaysOnTop", FALSE);
	m_iRefreshRate = GetProfileInt("SettingsPage", "RefreshRate", 500);


	//Key for the Mixer Page
	m_MixerPageRegKeys.iCheckBankId= GetProfileInt("MixerPage", "CheckBankId", 0);
	m_MixerPageRegKeys.iCheckResId= GetProfileInt("MixerPage", "CheckResId", 0);
	m_MixerPageRegKeys.bCheckFirstOccur= GetProfileInt("MixerPage", "CheckFirstOccur", 0);
	m_MixerPageRegKeys.iColTime= GetProfileInt("MixerPage", "ColTime", 77);
	m_MixerPageRegKeys.iColResName= GetProfileInt("MixerPage", "ColResName", 90);
	m_MixerPageRegKeys.iColResId= GetProfileInt("MixerPage", "ColResId", 35);
	m_MixerPageRegKeys.iColBankName= GetProfileInt("MixerPage", "ColBankName", 71);
	m_MixerPageRegKeys.iColBankId= GetProfileInt("MixerPage", "ColBankId", 54);
	m_MixerPageRegKeys.iColType = GetProfileInt("MixerPage", "ColType", 100);
	m_MixerPageRegKeys.iColVol= GetProfileInt("MixerPage", "ColVol", 50);
	m_MixerPageRegKeys.iColInfo= GetProfileInt("MixerPage", "ColInfo", 194);


	//Key for the EventsHistory Page
	m_EventPageRegKeys.iCheckBankId= GetProfileInt("EventHistoryPage", "CheckBankId", 0);
	m_EventPageRegKeys.iCheckEventId= GetProfileInt("EventHistoryPage", "CheckResId", 0);
	m_EventPageRegKeys.bCheckFirstOccur= GetProfileInt("EventHistoryPage", "CheckFirstOccur", 0);
	m_EventPageRegKeys.iColTime= GetProfileInt("EventHistoryPage", "ColTime", 75);
	m_EventPageRegKeys.iColEvtName= GetProfileInt("EventHistoryPage", "ColEvtName", 101);
	m_EventPageRegKeys.iColEvtId = GetProfileInt("EventHistoryPage", "ColEvtId", 52);
	m_EventPageRegKeys.iColBankName= GetProfileInt("EventHistoryPage", "ColBankName", 71);
	m_EventPageRegKeys.iColBankId= GetProfileInt("EventHistoryPage", "ColBankId", 51);
	m_EventPageRegKeys.iColEvtType = GetProfileInt("EventHistoryPage", "ColEvtType", 100);
	m_EventPageRegKeys.iColInfo = GetProfileInt("EventHistoryPage", "ColInfo", 212);

	//Key for the Micro&Object Page
	m_RegKeyMicPage.iColMicId= GetProfileInt("MicroPage", "iColMicId", 75);
	m_RegKeyMicPage.iColX= GetProfileInt("MicroPage", "iColX", 60);
	m_RegKeyMicPage.iColY= GetProfileInt("MicroPage", "iColY", 60);
	m_RegKeyMicPage.iColZ= GetProfileInt("MicroPage", "iColZ", 60);
	m_RegKeyMicPage.iColNx= GetProfileInt("MicroPage", "iColNx", 60);
	m_RegKeyMicPage.iColNy = GetProfileInt("MicroPage", "iColNy", 60);
	m_RegKeyMicPage.iColNz= GetProfileInt("MicroPage", "iColNz", 60);
	m_RegKeyMicPage.iColTx= GetProfileInt("MicroPage", "iColTx", 60);
	m_RegKeyMicPage.iColTy = GetProfileInt("MicroPage", "iColTy", 60);
	m_RegKeyMicPage.iColTz = GetProfileInt("MicroPage", "iColTz", 60);

	m_RegKeyObjPage.iColObjId= GetProfileInt("ObjectPage", "iColObjId", 102);
	m_RegKeyObjPage.iColX= GetProfileInt("ObjectPage", "iColX", 70);
	m_RegKeyObjPage.iColY= GetProfileInt("ObjectPage", "iColY", 70);
	m_RegKeyObjPage.iColZ= GetProfileInt("ObjectPage", "iColZ", 70);
	m_RegKeyObjPage.iColFreq= GetProfileInt("ObjectPage", "iColFreq", 78);
	m_RegKeyObjPage.iColVol = GetProfileInt("ObjectPage", "iColVol", 75);
	m_RegKeyObjPage.iColAsso= GetProfileInt("ObjectPage", "iColAsso", 125);


	//Key for Volume Line & Theme Page
	m_RegKeyThemePage.iColVolId= GetProfileInt("ThemePage", "iColVolId", 200);
	m_RegKeyThemePage.iColVol= GetProfileInt("ThemePage", "iColVol", 200);


	//Key for the Virtual Voices Page
	m_RegKeyVoicePage.iColVoiceId = GetProfileInt("VoicesPage", "iColVoiceId", 83);
	m_RegKeyVoicePage.iColPaused = GetProfileInt("VoicesPage", "iColPaused", 60);
	m_RegKeyVoicePage.iColResPtr = GetProfileInt("VoicesPage", "iColResPtr", 75);
	m_RegKeyVoicePage.iColResId = GetProfileInt("VoicesPage", "iColResId", 75);
	m_RegKeyVoicePage.iColLoop= GetProfileInt("VoicesPage", "iColLoop", 45);
	m_RegKeyVoicePage.iColNorm = GetProfileInt("VoicesPage", "iColNorm", 75);
	m_RegKeyVoicePage.iColInstance = GetProfileInt("VoicesPage", "iColInstance", 68);
	m_RegKeyVoicePage.iColAudibleV = GetProfileInt("VoicesPage", "iColAudibleV", 100);
	m_RegKeyVoicePage.iColHardV = GetProfileInt("VoicesPage", "iColHardV", 100);


	//Key for the Wav Voices Page
	m_RegKeyWavVoicePage.iColWavVoiceId = GetProfileInt("WavVoicesPage", "iColWavVoiceId", 60);
	m_RegKeyWavVoicePage.iColResPtr = GetProfileInt("WavVoicesPage", "iColResPtr", 100);
	m_RegKeyWavVoicePage.iColResId = GetProfileInt("WavVoicesPage", "iColResId", 75);
	m_RegKeyWavVoicePage.iColPaused = GetProfileInt("WavVoicesPage", "iColPaused", 60);
	m_RegKeyWavVoicePage.iColVol = GetProfileInt("WavVoicesPage", "iColVol", 60);
	m_RegKeyWavVoicePage.iColPan = GetProfileInt("WavVoicesPage", "iColPan", 75);
	m_RegKeyWavVoicePage.iColSpace = GetProfileInt("WavVoicesPage", "iColSpace", 75);
	m_RegKeyWavVoicePage.iColFreq = GetProfileInt("WavVoicesPage", "iColFreq", 75);
*/

	//Initialise
	m_bSuperVisaterActive = FALSE;

	return CWinApp::InitInstance();
}



int CSupervisApp::ExitInstance() 
{

	long i, j;
/*
	//Key for the application
	WriteProfileInt("Settings", "ActivePage", m_iActivePage);
	WriteProfileInt("Settings", "WindowLeft", m_iWindowLeft);
	WriteProfileInt("Settings", "WindowTop", m_iWindowTop);
	WriteProfileInt("Settings", "WindowRight", m_iWindowRight);
	WriteProfileInt("Settings", "WindowBottom", m_iWindowBottom);
	
	//SuperVisSetting key
	WriteProfileString("SettingsPage", "LCBPath", m_cBinaryLCBPath);
	WriteProfileString("SettingsPage", "LCBFileTitle", m_cBinaryLCBFileTitle);
	WriteProfileInt("SettingsPage", "AlwaysOnTop", m_bWindowOnTop);
	WriteProfileInt("SettingsPage", "RefreshRate", m_iRefreshRate);


	//Key for the Mixer Page
	WriteProfileInt("MixerPage", "CheckBankId", m_MixerPageRegKeys.iCheckBankId);
	WriteProfileInt("MixerPage", "CheckResId", m_MixerPageRegKeys.iCheckResId);
	WriteProfileInt("MixerPage", "CheckFirstOccur", m_MixerPageRegKeys.bCheckFirstOccur);
	WriteProfileInt("MixerPage", "ColTime", m_MixerPageRegKeys.iColTime);
	WriteProfileInt("MixerPage", "ColResName", m_MixerPageRegKeys.iColResName);
	WriteProfileInt("MixerPage", "ColResId", m_MixerPageRegKeys.iColResId);
	WriteProfileInt("MixerPage", "ColBankName", m_MixerPageRegKeys.iColBankName);
	WriteProfileInt("MixerPage", "ColBankId", m_MixerPageRegKeys.iColBankId);
	WriteProfileInt("MixerPage", "ColVol", m_MixerPageRegKeys.iColVol);
	WriteProfileInt("MixerPage", "ColType", m_MixerPageRegKeys.iColType);
	WriteProfileInt("MixerPage", "ColInfo", m_MixerPageRegKeys.iColInfo);


	//Key for the EventsHistory Page
	WriteProfileInt("EventHistoryPage", "CheckBankId", m_EventPageRegKeys.iCheckBankId);
	WriteProfileInt("EventHistoryPage", "CheckEventId", m_EventPageRegKeys.iCheckEventId);
	WriteProfileInt("EventHistoryPage", "CheckFirstOccur", m_EventPageRegKeys.bCheckFirstOccur);
	WriteProfileInt("EventHistoryPage", "ColTime", m_EventPageRegKeys.iColTime);
	WriteProfileInt("EventHistoryPage", "ColEvtName", m_EventPageRegKeys.iColEvtName);
	WriteProfileInt("EventHistoryPage", "ColEvtId", m_EventPageRegKeys.iColEvtId);
	WriteProfileInt("EventHistoryPage", "ColBankName", m_EventPageRegKeys.iColBankName);
	WriteProfileInt("EventHistoryPage", "ColBankId", m_EventPageRegKeys.iColBankId);
	WriteProfileInt("EventHistoryPage", "ColEvtType", m_EventPageRegKeys.iColEvtType);
	WriteProfileInt("EventHistoryPage", "ColInfo", m_EventPageRegKeys.iColInfo);


	//Key for the Micro&Object Page
	WriteProfileInt("MicroPage", "iColMicId", m_RegKeyMicPage.iColMicId);
	WriteProfileInt("MicroPage", "iColX", m_RegKeyMicPage.iColX);
	WriteProfileInt("MicroPage", "iColY", m_RegKeyMicPage.iColY);
	WriteProfileInt("MicroPage", "iColZ", m_RegKeyMicPage.iColZ);
	WriteProfileInt("MicroPage", "iColNx", m_RegKeyMicPage.iColNx);
	WriteProfileInt("MicroPage", "iColNy", m_RegKeyMicPage.iColNy);
	WriteProfileInt("MicroPage", "iColNz", m_RegKeyMicPage.iColNz);
	WriteProfileInt("MicroPage", "iColTx", m_RegKeyMicPage.iColTx);
	WriteProfileInt("MicroPage", "iColTy", m_RegKeyMicPage.iColTy);
	WriteProfileInt("MicroPage", "iColTz", m_RegKeyMicPage.iColTz);

	WriteProfileInt("ObjectPage", "iColObjId", m_RegKeyObjPage.iColObjId);
	WriteProfileInt("ObjectPage", "iColX", m_RegKeyObjPage.iColX);
	WriteProfileInt("ObjectPage", "iColY", m_RegKeyObjPage.iColY);
	WriteProfileInt("ObjectPage", "iColZ", m_RegKeyObjPage.iColZ);
	WriteProfileInt("ObjectPage", "iColFreq", m_RegKeyObjPage.iColFreq);
	WriteProfileInt("ObjectPage", "iColVol", m_RegKeyObjPage.iColVol);
	WriteProfileInt("ObjectPage", "iColAsso", m_RegKeyObjPage.iColAsso);


	//Key for Volume Line & Theme Page
	WriteProfileInt("ThemePage", "iColVolId", m_RegKeyThemePage.iColVolId);
	WriteProfileInt("ThemePage", "iColVol", m_RegKeyThemePage.iColVol);


	//Key for the Virtual Voices Page
	WriteProfileInt("VoicesPage", "iColVoiceId", m_RegKeyVoicePage.iColVoiceId);
	WriteProfileInt("VoicesPage", "iColPaused", m_RegKeyVoicePage.iColPaused);
	WriteProfileInt("VoicesPage", "iColResPtr", m_RegKeyVoicePage.iColResPtr);
	WriteProfileInt("VoicesPage", "iColResId", m_RegKeyVoicePage.iColResId);
	WriteProfileInt("VoicesPage", "iColLoop", m_RegKeyVoicePage.iColLoop);
	WriteProfileInt("VoicesPage", "iColNorm", m_RegKeyVoicePage.iColNorm);
	WriteProfileInt("VoicesPage", "iColInstance", m_RegKeyVoicePage.iColInstance);
	WriteProfileInt("VoicesPage", "iColAudibleV", m_RegKeyVoicePage.iColAudibleV);
	WriteProfileInt("VoicesPage", "iColHardV", m_RegKeyVoicePage.iColHardV);


	//Key for the Wav Voices Page
	WriteProfileInt("WavVoicesPage", "iColWavVoiceId", m_RegKeyWavVoicePage.iColWavVoiceId);
	WriteProfileInt("WavVoicesPage", "iColResPtr", m_RegKeyWavVoicePage.iColResPtr);
	WriteProfileInt("WavVoicesPage", "iColResId", m_RegKeyWavVoicePage.iColResId);
	WriteProfileInt("WavVoicesPage", "iColPaused", m_RegKeyWavVoicePage.iColPaused);
	WriteProfileInt("WavVoicesPage", "iColVol", m_RegKeyWavVoicePage.iColVol);
	WriteProfileInt("WavVoicesPage", "iColPan", m_RegKeyWavVoicePage.iColPan);
	WriteProfileInt("WavVoicesPage", "iColSpace", m_RegKeyWavVoicePage.iColSpace);
	WriteProfileInt("WavVoicesPage", "iColFreq", m_RegKeyWavVoicePage.iColFreq);

*/

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

	m_apEventHistoArray.RemoveAll();


	
	//Free the Resources array
	for (i= 0;  i < m_apResources.GetSize() ;i++)
	{
		ResourceElement* tempRes = (ResourceElement *)(m_apResources.GetAt(i));
		delete tempRes;
	}

	m_apResources.RemoveAll();


	//Free the Micros array
	for (i= 0;  i < m_apMicros.GetSize() ;i++)
	{
		MicroArrayElement* tempMic = (MicroArrayElement *)(m_apMicros.GetAt(i));
		delete tempMic;
	}

	m_apMicros.RemoveAll();


	//Free the Objects array
	for (i= 0;  i < m_apObjects.GetSize() ;i++)
	{
		ObjectArrayElement* tempObj = (ObjectArrayElement *)(m_apObjects.GetAt(i));
		delete tempObj;
	}

	m_apObjects.RemoveAll();


	//Free the VolumeLine array
	for (i= 0;  i < m_apVolumeLine.GetSize() ;i++)
	{
		VolumeArrayElement* tempVol = (VolumeArrayElement *)(m_apVolumeLine.GetAt(i));
		delete tempVol;
	}

	m_apVolumeLine.RemoveAll();


	//Free the WavVoices array
	for (i= 0;  i < m_apWavVoices.GetSize() ;i++)
	{
		WavVoiceArrayElement* tempWav = (WavVoiceArrayElement *)(m_apWavVoices.GetAt(i));
		delete tempWav;
	}

	m_apWavVoices.RemoveAll();


	VirtualVoiceModule*	tempModule;

	//Free the Module Virtual Voice array and all the arrays included within
	for (i= 0;  i < m_apVirtualVoiceModule.GetSize() ;i++)
	{
		
		tempModule = (VirtualVoiceModule *)(m_apVirtualVoiceModule.GetAt(i));	
		
		//Free the Virtual Voices array in the i-th module
		for (j= 0;  j < tempModule->apVirtualVoicesArray.GetSize() ;j++)
		{
			VirtualVoice* tempVoice = (VirtualVoice *)(tempModule->apVirtualVoicesArray.GetAt(j));
			delete tempVoice;
		}

		tempModule->apVirtualVoicesArray.RemoveAll();
		delete tempModule;
	}

	m_apVirtualVoiceModule.RemoveAll();



	return CWinApp::ExitInstance();
}


/*
 *=============================================================================
 *  Description : Launch the Supervisater PropertySheet dialog
  *=============================================================================
 *  Input  : SND_tdstInitStruct		*pInitStruct	
 *
 *  Output : Void.
 *=============================================================================
 *  Creation date : 23/03/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL SND_fn_vLaunchSupervisater(SND_tdstInitStruct *pInitStruct)
{

#ifdef SUPERVISATER
#if defined(_DLL_COMPILATION_MODE)
    SND_DllInitEntryPoints_StaticFunctions((HMODULE)pInitStruct->hProcessInstance );
#endif

	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{
		CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->LaunchSuperVisEvent, FALSE );
			
			//We start an UI Thread for the supervisater Interface
			pSuperVisApp->m_SuperVisThread = (CSuperVisThread*)
			AfxBeginThread(RUNTIME_CLASS(CSuperVisThread), THREAD_PRIORITY_NORMAL,
					0, CREATE_SUSPENDED);

			pSuperVisApp->m_SuperVisThread->ResumeThread();

			//We wait for a CEvent message to continue, Be sure that the Supervisater is fully loaded.
			sLock.Lock(INFINITE );
		
		}
		
	}
	END_TRY
	
#endif
}



/*
 *=============================================================================
 *  Description : Close the Supervisater PropertySheet dialog
  *=============================================================================
 *  Input  : Void
 *
 *  Output : Void.
 *=============================================================================
 *  Creation date : 23/03/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL SND_fn_vKillSupervisater()
{
#ifdef SUPERVISATER

	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{

		CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
		
		if(pSuperVisApp->m_bSuperVisaterActive)
		{


			pSuperVisApp->m_bSuperVisaterActive = FALSE;

			HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

			//Exit Automation
			pSuperVisApp->m_SuperVisThread->PostThreadMessage(WM_EXIT_AUTOMATION,0,(LPARAM)hEvent);
			
			WaitForSingleObject(hEvent,INFINITE);	
			CloseHandle(hEvent);


			//Kill the thread. Send Message to Windows to destroy the thread (not user defined message)
			pSuperVisApp->m_SuperVisThread->PostThreadMessage(WM_QUIT,0,0);
			
		}


	}
	END_TRY


#endif

}


/*
 *=============================================================================
 *  Description : Set the Supervisater as Active
 *					
 *=============================================================================
 *  Input  : void
 *
 *  Output : Void.
 *=============================================================================
 *  Creation date : 08/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL SND_fn_vSetSupervisaterActive(void)
{
	
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{

	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
	pSuperVisApp->m_bSuperVisaterActive = TRUE;

	}
	END_TRY
}


/*
 *=============================================================================
 *  Description : Retrieve the Supervisater state
 *					
 *=============================================================================
 *  Input  : void
 *
 *  Output : SndBool
 *=============================================================================
 *  Creation date : 08/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
SndBool SND_CALL SND_fn_bIsSupervisaterActive(void)
{

	
	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{

	CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
	return pSuperVisApp->m_bSuperVisaterActive;

	}
	END_TRY
}



/*
 *=============================================================================
 *  Description : Add an object int the Micro&Object property page
 *					
 *=============================================================================
 *  Input  : long indice
 *			 long type
 *			 long asso
 *			 SND_tduRefEvt evt
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vAddEventToObject(long indice,long type,long asso,SND_tduRefEvt evt)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{
		CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
		
		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			
			ObjectArrayElement  *pObj;

			long lSize  = pSuperVisApp->m_apObjects.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pObj = (ObjectArrayElement *)(pSuperVisApp->m_apObjects.GetAt(i));
				
				if (pObj->lId == indice)
				{
					return;
				}
			}
			
			ObjectArrayElement  *pObject =  new ObjectArrayElement;

			pObject->lId = indice;
			pObject->dPosX = 0;
			pObject->dPosY = 0;
			pObject->dPosZ = 0;
			pObject->dFreq = 0;
			pObject->lDistToMicro = 0;
			pObject->evt_pstPtr = evt.pstPtr;
			pObject->evt_Id = evt.pstPtr->Id;
			pObject->evt_eType = evt.pstPtr->eType;
			pObject->lAsso = asso;


			//Look for the size of the Objects Array
			long lArraySize = pSuperVisApp->m_apObjects.GetSize();

			if(lArraySize >= ARRAY_SIZE)
			{
				//Keep the array smaller than ARRAY_SIZE. remove the first array element.
				pSuperVisApp->m_apObjects.RemoveAt(0);

			}

			//Add Object element in the global pointer Array
			long lObjectIndex = pSuperVisApp->m_apObjects.Add(pObject);

//			pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MicroAndObjectsPage.RefreshObjectList();

		
			//Release
			sLock.Unlock();

		}

	}
	END_TRY
}


/*
 *=============================================================================
 *  Description : Destruct an object
 *					
 *=============================================================================
 *  Input  : long indice
 *			 long asso
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vKillEventToObjectPrivate(long indice,long asso)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{
		CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
		
		if(pSuperVisApp->m_bSuperVisaterActive)
		{
			
			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			ObjectArrayElement  *pObj;

			long lSize  = pSuperVisApp->m_apObjects.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pObj = (ObjectArrayElement *)(pSuperVisApp->m_apObjects.GetAt(i));
				
				if (pObj->lId == indice)
				{

					//All element index above "i" will be shifted
					pSuperVisApp->m_apObjects.RemoveAt(i);
					delete pObj;
				}
//				pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MicroAndObjectsPage.RefreshObjectList();
				break;
			}

			//Release
			sLock.Unlock();
		}

	}
	END_TRY

}



/*
 *=============================================================================
 *  Description : Set Object parameters.
 *					
 *=============================================================================
 *  Input  : long indice
 *			 SoundParam* par
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vSetPosObject(long indice,SoundParam* par)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())
	
	TRY
	{
		CSupervisApp* pSuperVisApp = (CSupervisApp*)AfxGetApp();
		
		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			ObjectArrayElement  *pObject;

			long lSize  = pSuperVisApp->m_apObjects.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pObject = (ObjectArrayElement *)(pSuperVisApp->m_apObjects.GetAt(i));
				
				if (pObject->lId == indice)
				{

					pObject->dPosX = ((double)par->Pos.x)/(0x10000);
					pObject->dPosY = ((double)par->Pos.y)/(0x10000);
					pObject->dPosZ = ((double)par->Pos.z)/(0x10000);
					pObject->dFreq = ((double)par->Freq)/(0x10000);
					pObject->ucVol = par->ucVol;


					//TODO: calculer dist to mic
					pObject->lDistToMicro = 0;

/*
					texte2[0]=0;
					SNDLST2_M_DynamicForEachElementOf(&dbg_micros.pList,pdbgMicro,i)
					{
						vect.x=pdbgObj->par.Pos.x-pdbgMicro->par.pos.x;
						vect.y=pdbgObj->par.Pos.y-pdbgMicro->par.pos.y;
						vect.z=pdbgObj->par.Pos.z-pdbgMicro->par.pos.z;
						sprintf(texte,"%6.3f-",M_RealToDoubleSnd(dbgSND_fn_rPseudoNormeVectorSnd(&vect)));
						strncat(texte2,texte,sizeof(texte2)-1-strlen(texte2));
					}
					
*/		
					break;
				}

			}
			
			
			//Release
			sLock.Unlock();

		}

	}
	END_TRY

}

/*
 *=============================================================================
 *  Description : Add a micro in the Micro and object page. Not data are
 *				available intially so its all set to zero.
 *					
 *=============================================================================
 *  Input  : long indice -> Micro Id
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 21/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vAddMicro(long indice)
{


	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	TRY
	{


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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			MicroArrayElement  *pMicro =  new MicroArrayElement;

			pMicro->lId = indice;
			pMicro->dPosX = 0;
			pMicro->dPosY = 0;
			pMicro->dPosZ = 0;
			pMicro->dNormX = 0;
			pMicro->dNormY = 0;
			pMicro->dNormZ = 0;
			pMicro->dTransX = 0;
			pMicro->dTransY = 0;
			pMicro->dTransZ = 0;

			//Add Envent history element in the global pointer Array
			long lMicroIndex = pSuperVisApp->m_apMicros.Add(pMicro);

			//Release
			sLock.Unlock();
		}

	}
	END_TRY

}


/*
 *=============================================================================
 *  Description : Delete a Micro. Use
 *					the micro Id to know wich one it is
 *					
 *=============================================================================
 *  Input  : long indice -> Micro Id
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 21/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vKillMicro(long indice)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	TRY
	{

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			MicroArrayElement  *pMicro;

			long lSize  = pSuperVisApp->m_apMicros.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pMicro = (MicroArrayElement *)(pSuperVisApp->m_apMicros.GetAt(i));
				if (pMicro->lId == indice)
				{
					//All element index above "i" will be shifted
					pSuperVisApp->m_apMicros.RemoveAt(i);
					delete pMicro;
				}
				break;

			}
			

			//Release
			sLock.Unlock();
		}
		
	}
	END_TRY
}


/*
 *=============================================================================
 *  Description : Set the Positio, Normal and Tangeante of a Micro. Use
 *					the micro Id to know wich it is
 *					
 *=============================================================================
 *  Input  : long indice -> Micro Id
 *			 MicroParam* par -> data to be used 
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 21/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vSetPosMicro(long indice,MicroParam* par)
{


	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	TRY
	{


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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			MicroArrayElement  *pMicro;

			long lSize  = pSuperVisApp->m_apMicros.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pMicro = (MicroArrayElement *)(pSuperVisApp->m_apMicros.GetAt(i));
				if (pMicro->lId == indice)
				{
					pMicro->dPosX = ((double)par->pos.x)/(0x10000);
					pMicro->dPosY = ((double)par->pos.y)/(0x10000);
					pMicro->dPosZ = ((double)par->pos.z)/(0x10000);
					pMicro->dNormX = ((double)par->dirnor.x)/(0x10000);
					pMicro->dNormY = ((double)par->dirnor.y)/(0x10000);
					pMicro->dNormZ = ((double)par->dirnor.z)/(0x10000);
					pMicro->dTransX = ((double)par->dirtan.x)/(0x10000);
					pMicro->dTransY = ((double)par->dirtan.y)/(0x10000);
					pMicro->dTransZ = ((double)par->dirtan.z)/(0x10000);
		
					break;
				}

			}

			//Release
			sLock.Unlock();

		}

	}
	END_TRY
}

/*
 *=============================================================================
 *  Description : Exported Events Historic function. Add the events in
 *					the Historic list
 *=============================================================================
 *  Input  : SND_tduRefEvt			evt	
 *			 long					indice
 *			 long					type_obj
 *			 long					asso
 *			 tdstBlockResourceMem*	res
 *
 *  Output : Void.
 *=============================================================================
 *  Creation date : 23/03/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vAddHistoric(SND_tduRefEvt evt,long indice,long type_obj,long asso,tdstBlockResourceMem* res)
{


	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	TRY
	{

		char info[80];

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

		
		if(pSuperVisApp->m_bSuperVisaterActive)
		{

		/*	CSingleLock sSuperVisLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sSuperVisLock.Lock( INFINITE );
*/
			//Allocate memomry for a new hisoric element. Will be free when the apps quit.
			EventsHistElement *evtHisto = new EventsHistElement;
			ResourceElement *supervisRes = new ResourceElement;

			//
			//We add the Event data in the Event History page
			//

			//Fill the new element with data
			GetLocalTime(&evtHisto->time);
			evtHisto->evt_pstPtr = evt.pstPtr;
			evtHisto->evt_Id = evt.pstPtr->Id;
			evtHisto->evt_eType = evt.pstPtr->eType;
			evtHisto->res_pstPtr = res;
			evtHisto->asso = asso;

			//Fill the info data
			dbgSND_fn_vGetInfoForObjectSound(indice, type_obj, info, sizeof(info) - 1);
			evtHisto->cInfo = info;


			//
			//We add the events name in the list
			//
			
			//Look for the size of the Events History Array
			long lArraySize = pSuperVisApp->m_apEventHistoArray.GetSize();

			if(lArraySize >= ARRAY_SIZE)
			{
				//Keep the array smaller than ARRAY_SIZE. remove the first array element.
				EventsHistElement *evtToDel = (EventsHistElement *)(pSuperVisApp->m_apEventHistoArray.GetAt(0));
				delete evtToDel;
				pSuperVisApp->m_apEventHistoArray.RemoveAt(0);

				//If we are not using the firstoccurArray we must decrease index of 1
				if(!pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_bFirstOccurence)
				{

					//We have to loop trhough the event list to decrease the index by one.
					int iEvtListCount = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_EventsList.GetItemCount();
					for (int j = 0; j < iEvtListCount; j++)
					{
						DWORD dwData = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_EventsList.GetItemData(j) - 1;
						if(dwData > 0)
							pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_EventsList.SetItemData(j, dwData);
						else
						{
							pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_EventsList.DeleteItem(j);
							//We decrease the list elements counts too...
							j--;
							iEvtListCount--;
						}
					}
				}

			}


			
			//Add Envent history element in the global pointer Array
			long lEventIndex = pSuperVisApp->m_apEventHistoArray.Add(evtHisto);


			 //Look if its the firs occurence of the event
			long lFirstOccurEventIndex = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.AddToFirstEvtOccurArray(evtHisto);


			//
			//Add events names in the new event Array element
			//
			CSingleLock sLock( pSuperVisApp->AddHistoSyncEvent, FALSE );
				

			//We add name only if we hane initiated SoundEditor automation mode
			if(pSuperVisApp->m_SuperVisThread->bAutomationActivated)
			{
			
				//Fill the "evtName" in the new  event history element
				pSuperVisApp->m_SuperVisThread->SuperVisSheet->PostMessage(WM_SETNAME_EVENT, (WPARAM)lEventIndex, NULL);

				sLock.Lock(INFINITE);
				sLock.Unlock();

				
				//Fill the "evtName" in the new  first occurrence event history element
				if(lFirstOccurEventIndex != -1)
				{
					//Unsignal the event for next event
					pSuperVisApp->AddHistoSyncEvent->ResetEvent();
					
					//Add the new  Envent history element in the history list control of the EventHistoryPage
					pSuperVisApp->m_SuperVisThread->SuperVisSheet->PostMessage(WM_SETNAME_FIRST_OCCUR_EVENT, (WPARAM)lFirstOccurEventIndex, NULL);

					sLock.Lock(INFINITE);
					sLock.Unlock();

				}
			}


		
			//
			//Displaying
			//
			
			//Are we paused?...
			if(!pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_bPauseProcess)
			{
				
				if(pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.m_bFirstOccurence)
				{
					//Add the new  Envent history element in the history list control of the EventHistoryPage
					if(lFirstOccurEventIndex != -1)
					{
		
						pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.FilterAndDisplayFirstOccurEvent(lFirstOccurEventIndex);
					}
				}
				else
				{
					//Add the new  Envent history element in the history list control of the EventHistoryPage
					pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_EventsHistoryPage.FilterAndDisplayEvent(lEventIndex);
				}

			}


			//
			//We add the ressources data in the mixer page
			//

			//Fill the new element with data, dont do anything if res == NULL.
			//Its a STOP_EVENT with no resource
			if(res != NULL)
			{

				GetLocalTime(&supervisRes->time);
				supervisRes->ulId = res->Id;
				supervisRes->tdeType = res->eType;
				supervisRes->ucVolume  = res->ucVolume;
				supervisRes->res  = res;
				supervisRes->cInfo  = info;
				supervisRes->evt = evt;

				//Look for the size of the Events History Array
				lArraySize = pSuperVisApp->m_apResources.GetSize();

				if(lArraySize >= ARRAY_SIZE)
				{
					//Keep the array smaller than ARRAY_SIZE. Remove the fist array element.
					ResourceElement *resToDel = (ResourceElement *)(pSuperVisApp->m_apResources.GetAt(0));
					delete resToDel;
					pSuperVisApp->m_apResources.RemoveAt(0);

					//If we are not using the firstoccurArray we must decrease index of 1
					if(!pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_bFirstOccurence)
					{
						//We have to loop trhough the ressources list to decrease the index by one.
						int iResListCount = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_ResList.GetItemCount();
						for (int l = 0; l < iResListCount; l++)
						{
							DWORD dwData = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_ResList.GetItemData(l) - 1;
							if(dwData > 0)
								pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_ResList.SetItemData(l, dwData);
							else
							{
								pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_ResList.DeleteItem(l);
								//We decrease the list elements counts too...
								l--;
								iResListCount--;
							}
						}
					}
				}
			
				

				//Add Resource element in the global pointer Array
				long lResIndex = pSuperVisApp->m_apResources.Add(supervisRes);

				 //Look if its the firs occurence of the resource
				long lFirstOccurResIndex = pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.AddToFirstResOccurArray(supervisRes);

			
				//
				//Add Res and bank names in the new res Array element
				//
				
				//We add name only if we hane initiated SoundEditor automation mode
				if(pSuperVisApp->m_SuperVisThread->bAutomationActivated)
				{
					pSuperVisApp->AddHistoSyncEvent->ResetEvent();
						
					//Fill the "resName" in the new  resource element
					pSuperVisApp->m_SuperVisThread->SuperVisSheet->PostMessage(WM_SETNAME_RES, (WPARAM)lResIndex, NULL);

					sLock.Lock(INFINITE);
					sLock.Unlock();

					
					//Fill the "resName" in the new first occurrence res element
					if(lFirstOccurResIndex != -1)
					{
						//Unsignal the event for next event
						pSuperVisApp->AddHistoSyncEvent->ResetEvent();
						
						//Add the new  Envent history element in the history list control of the EventHistoryPage
						pSuperVisApp->m_SuperVisThread->SuperVisSheet->PostMessage(WM_SETNAME_FIRST_OCCUR_RES, (WPARAM)lFirstOccurResIndex, NULL);

						sLock.Lock(INFINITE);
						sLock.Unlock();

					}

				}

				
				
				if(!pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_bPauseProcess)
				{
					
					if(pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.m_bFirstOccurence)
					{
						//Add the new  res element in the history list control of the MixerPage
						if(lFirstOccurResIndex != -1)
							pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.FilterAndDisplayFirstOccurRes(lFirstOccurResIndex);
					}
					else
					{
						//Add the new  res element in the history list control of the MixerPage
						pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_MixerPage.FilterAndDisplayRes(lResIndex);
					}
						
		
				}


			}


			//Release
			//sSuperVisLock.Unlock();

		}

	}
	END_TRY

}


/*
 *=============================================================================
 *  Description : Remove a volume Line.
 *					
 *=============================================================================
 *  Input  : long line
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vKillVolumeLine(long line)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			VolumeArrayElement  *pVol =  new VolumeArrayElement;

			long lSize  = pSuperVisApp->m_apVolumeLine.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVol = (VolumeArrayElement *)(pSuperVisApp->m_apVolumeLine.GetAt(i));
				if (pVol->lId == line)
				{
					//All element index above "i" will be shifted
					pSuperVisApp->m_apVolumeLine.RemoveAt(i);
					delete pVol;
					
					break;
				}
			}

			//Release
			sLock.Unlock();

		}

	}
	END_TRY
}

/*
 *=============================================================================
 *  Description : Add a volume Line.
 *					
 *=============================================================================
 *  Input  : long line
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vAddVolumeLine(long line)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{
			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			VolumeArrayElement  *pVol =  new VolumeArrayElement;

			pVol->lId = line;
			pVol->lVol = 127;


			//Add Envent history element in the global pointer Array
			long lMicroIndex = pSuperVisApp->m_apVolumeLine.Add(pVol);
		
			//Release
			sLock.Unlock();
		}

	}
	END_TRY

}

/*
 *=============================================================================
 *  Description : Set a volume Line.
 *					
 *=============================================================================
 *  Input  : long line
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vSetVolumeLine(long line,long vol)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			VolumeArrayElement  *pVol;

			long lSize  = pSuperVisApp->m_apVolumeLine.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVol = (VolumeArrayElement *)(pSuperVisApp->m_apVolumeLine.GetAt(i));
				if (pVol->lId == line)
				{
					pVol->lVol = vol;
					break;
				}
			}

			//Release
			sLock.Unlock();

		}

	}
	END_TRY

}



/*
 *=============================================================================
 *  Description : Obsolete
 *=============================================================================
 *  Input  : 
 *
 *  Output : 
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vLoadBank(int iId)
{
}


/*
 *=============================================================================
 *  Description : Obsolete
 *=============================================================================
 *  Input  : 
 *
 *  Output : 
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vUnLoadBank(int iId)
{
}



/*
 *=============================================================================
 *  Description : Add a Wav Voice to the WAv Voice property page
 *					
 *=============================================================================
 *  Input  :	long id
 *				tduRefRes res
 *				SampleParam* par
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vAddVoiceSample(long id,tduRefRes res,SampleParam* par)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			WavVoiceArrayElement  *pWavVoice;

			BOOL bVoiceFound = FALSE;

			long lSize  = pSuperVisApp->m_apWavVoices.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pWavVoice = (WavVoiceArrayElement *)(pSuperVisApp->m_apWavVoices.GetAt(i));
				if (pWavVoice->lId == id)
				{

					pWavVoice->res_pstPtr = res.pstPtr;
					pWavVoice->res_Id = res.pstPtr->Id;
					pWavVoice->ucVolume = par->ucVol;
					pWavVoice->ucPan = par->ucPan;
					pWavVoice->ucSpace = par->ucSpace;
					pWavVoice->dFreq = ((double)par->Freq)/(0x10000);

					//We have found the voice...quit
					bVoiceFound = TRUE;
					break;
				}
			}			
			

			//We havent found the Wav Voices in the Array, create a new element
			if(!bVoiceFound)
			{
				pWavVoice =  new WavVoiceArrayElement;

				pWavVoice->lId = id;
				pWavVoice->res_pstPtr = res.pstPtr;
				pWavVoice->res_Id = res.pstPtr->Id;
				pWavVoice->ucVolume = par->ucVol;
				pWavVoice->ucPan = par->ucPan;
				pWavVoice->ucSpace = par->ucSpace;
				pWavVoice->dFreq = ((double)par->Freq)/(0x10000);

				//Look for the size of the WavVoices Array
				long lArraySize = pSuperVisApp->m_apWavVoices.GetSize();

				if(lArraySize >= ARRAY_SIZE)
				{
					//Keep the array smaller than ARRAY_SIZE. remove the first array element.
					pSuperVisApp->m_apWavVoices.RemoveAt(0);

				}

				//Add Wav voice element in the global pointer Array
				long lWavVoiceIndex = pSuperVisApp->m_apWavVoices.Add(pWavVoice);
			

			}
		
			//Release
			sLock.Unlock();
		}

	}
	END_TRY


}

/*
 *=============================================================================
 *  Description : Set data for a WAV voice (pan, vol, freq and space)
 *					
 *=============================================================================
 *  Input  :	long id
 *				SampleParam* par
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */		
void SND_CALL dbgSND_fn_vSetParVoiceSample(long id,SampleParam* par)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{
			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			WavVoiceArrayElement  *pVoice;

			long lSize  = pSuperVisApp->m_apWavVoices.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVoice = (WavVoiceArrayElement *)(pSuperVisApp->m_apWavVoices.GetAt(i));
				if (pVoice->lId == id)
				{
					pVoice->ucVolume = par->ucVol;
					pVoice->ucPan = par->ucPan;
					pVoice->ucSpace = par->ucSpace;
					pVoice->dFreq = ((double)par->Freq)/(0x10000);
					break;
				}

			}

			//Release
			sLock.Unlock();

		}

	}
	END_TRY
}


/*
 *=============================================================================
 *  Description : Delete a WAV voice
 *					
 *=============================================================================
 *  Input  :	long id
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */			
void SND_CALL dbgSND_fn_vDelVoiceSample(long id)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			WavVoiceArrayElement  *pVoice;

			long lSize  = pSuperVisApp->m_apWavVoices.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVoice = (WavVoiceArrayElement *)(pSuperVisApp->m_apWavVoices.GetAt(i));
				if (pVoice->lId == id)
				{

					//All element index above "i" will be shifted
					pSuperVisApp->m_apWavVoices.RemoveAt(i);
					delete pVoice;
					break;
				}
			}

			//Release
			sLock.Unlock();
		}

	}
	END_TRY

}


/*
 *=============================================================================
 *  Description : Set the bPaused flag of a WAV voice.
 *					
 *=============================================================================
 *  Input  :	long id
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vPauseVoiceSample(long id)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

		
			WavVoiceArrayElement  *pVoice;

			long lSize  = pSuperVisApp->m_apWavVoices.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVoice = (WavVoiceArrayElement *)(pSuperVisApp->m_apWavVoices.GetAt(i));
				if (pVoice->lId == id)
				{

					pVoice->bPaused = TRUE;
					break;
				}
			}

			//Release
			sLock.Unlock();
		}

	}
	END_TRY
}

/*
 *=============================================================================
 *  Description : UnSet the bPaused flag of a WAV voice.
 *					
 *=============================================================================
 *  Input  :	long id
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vResumeVoiceSample(long id)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			WavVoiceArrayElement  *pVoice;

			long lSize  = pSuperVisApp->m_apWavVoices.GetSize();
			long i;

			for (i = 0; i < lSize; i++)
			{
				pVoice = (WavVoiceArrayElement *)(pSuperVisApp->m_apWavVoices.GetAt(i));
				if (pVoice->lId == id)
				{

					pVoice->bPaused = FALSE;
					break;
				}
			}

			//Release
			sLock.Unlock();
		}

	}
	END_TRY
}


/*
 *=============================================================================
 *  Description : Set the process time for Sample.
 *					
 *=============================================================================
 *  Input  :	float ratio
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vSetProcessTimeSample(float ratio)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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


		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			//Set the editBox in WavVoices Property page
			//pSuperVisApp->m_SuperVisThread->SuperVisSheet->m_WavVoicesPage.m_lProcessTime = (int)(1000.0*ratio);
			pSuperVisApp->m_lProcessTime = (int)(1000.0*ratio);


			//Release
			sLock.Unlock();

		}

	}
	END_TRY

}


/*
 *=============================================================================
 *  Description : Obsolete
 *=============================================================================
 *  Input  : 
 *
 *  Output : 
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
tdstBlockResourceMem* SND_CALL dbgSND_fn_pstGetSelectedResource(void)
{
	return NULL;
}



/*
 *=============================================================================
 *  Description : Obsolete
 *=============================================================================
 *  Input  : 
 *
 *  Output : 
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
SndBool SND_CALL dbgSND_fn_bDoesSupervisaterSelectResource(void)
{
	return FALSE;
}




/*
 *=============================================================================
 *  Description : Initialise a Virtual Voice Module.
 *					
 *=============================================================================
 *  Input  :	float ratio
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vInitListesSxdVirtual(long virtual_module,char* descrpition)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			VirtualVoiceModule  *pModule = new VirtualVoiceModule;

			pModule->lIdModule = virtual_module;
			pModule->cDescription = descrpition;
			
			long lModuleIndex = pSuperVisApp->m_apVirtualVoiceModule.Add(pModule);

			//Release
			sLock.Unlock();
			
		}
	
	}
	END_TRY

}


/*
 *=============================================================================
 *  Description : Add new virtual voices in the array
 *					
 *=============================================================================
 *  Input  :	float ratio
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 23/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vRajListesSxdVirtual2(SND_tdhVirtualModule p_virtual_module)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		
		//Voices structure from ACP
		virtual_voice_list* pVirtualVoiceList = &p_virtual_module->virtual_voices;
		audible_voice_list* pAudibleVoicesList = &p_virtual_module->audible_voices;
		dead_voice_list* pDeadVoiceList = &p_virtual_module->dead_voices;
		p_virtual_voice voice;

		BOOL bFound = FALSE;

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );
			
			VirtualVoiceModule  *pModule;

			long lModuleSize  = pSuperVisApp->m_apVirtualVoiceModule.GetSize();
			long lVoiceArraySize;
			int i, j, k;

			for (i = 0; i < lModuleSize; i++)
			{
				pModule = (VirtualVoiceModule *)(pSuperVisApp->m_apVirtualVoiceModule.GetAt(i));
				if (pModule->lIdModule == (long)p_virtual_module)
				{

					//1 - Eliminate obsolete Virtual Voices
					VirtualVoice  *pVoice;

					lVoiceArraySize  = pModule->apVirtualVoicesArray.GetSize();
					
					for (j = 0; j < lVoiceArraySize; j++)
					{
						pVoice = (VirtualVoice *)(pModule->apVirtualVoicesArray.GetAt(j));

						//Go through the list to find the voice
						SNDLST2_M_DynamicForEachElementOf(&pVirtualVoiceList->pList,voice,k)
						{
							if ((long)voice == pVoice->lId)
							{
								bFound=TRUE;
								break;
							}
						}
						
						//Not in the list anymore. Set the flag
						if (!bFound)
						{
							pVoice->bStillActive = FALSE;
						}

					}



					bFound = FALSE;

					//2 - :raj de anciennes lignes et ajoûts des nouvelles
					SNDLST2_M_DynamicForEachElementOf(&pVirtualVoiceList->pList,voice,j)
					{

						lVoiceArraySize  = pModule->apVirtualVoicesArray.GetSize();
					
						for (k = 0; k < lVoiceArraySize; k++)
						{
							pVoice = (VirtualVoice *)(pModule->apVirtualVoicesArray.GetAt(k));
							if ((pVoice->lId == (long)voice) && (pVoice->bStillActive))
							{
								bFound = TRUE;
								break;
							}
						}
					
						
						if (!bFound)
						{


							pVoice = new VirtualVoice;
							
							//Look for the size of the Objects Array
							long lArraySize = pModule->apVirtualVoicesArray.GetSize();

							if(lArraySize >= ARRAY_SIZE)
							{
								//Keep the array smaller than ARRAY_SIZE. remove the first array element.
								pModule->apVirtualVoicesArray.RemoveAt(0);

							}								
															
							pModule->apVirtualVoicesArray.Add(pVoice);

							pVoice->bDisplayed = FALSE;
							pVoice->bStillActive = TRUE;

						}

						pVoice->lId = (long)voice;
						pVoice->dNorme = M_RealToDoubleSnd(voice->rNorme);
						pVoice->bPaused = voice->bPaused;
						pVoice->lResId = voice->tduRes.pstPtr->Id;
						pVoice->lResRef = (long)voice->tduRes.pstPtr;
						pVoice->bLoop = voice->tduRes.pstPtr->uRes.stSample.bLoop;
						pVoice->lInstance = voice->lInstance;
						pVoice->lAudible = (long)voice->audible;
						pVoice->lVoice = voice->lVoice;


					}

				}

			}

			//Release Mutex Object
			sLock.Unlock();

		}


	}
	END_TRY

}



/*
 *=============================================================================
 *  Description : Engine ask for a refresh
 *=============================================================================
 *  Input  : 
 *
 *  Output : 
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vRefreshSupervisater(void)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			CSingleLock sLock( pSuperVisApp->SuperVisMutex, FALSE );
			//Wait for Mutex Object
			sLock.Lock( INFINITE );

			//Do refresh
			pSuperVisApp->m_SuperVisThread->SuperVisSheet->RefreshSuperVisater();

			//Release
			sLock.Unlock();
			
		}

	
	}
	END_TRY
}



/*
 *=============================================================================
 *  Description : Call dbgSND_fn_vKillEventToObject. Used for backward
 *				  compatibility I guess!
 *					
 *=============================================================================
 *  Input  : long indice
 *			 long asso
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 22/04/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */
void SND_CALL dbgSND_fn_vKillEventToObject(long indice,long asso)
{
	dbgSND_fn_vKillEventToObjectPrivate(indice,asso);
}


/*
 *=============================================================================
 *  Description : Initialise The path for the LCB file
 *					
 *=============================================================================
 *  Input  :	char* projectFilename
 *
 *  Output : void
 *=============================================================================
 *  Creation date : 13/05/99            Author : Pascal Lalancette            
 *=============================================================================
 *  Modification date :				    Author : 
 *  Modifications :
 *=============================================================================
 */	
void SND_CALL dbgSND_fn_vSetProjectTitleForSuperVisater(char* ProjectFilename)
{

	AFX_MANAGE_STATE(AfxGetStaticModuleState())

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

		if(pSuperVisApp->m_bSuperVisaterActive)
		{

			//Get the path for the Supervisater Automation initialisation
//			pSuperVisApp->m_cLCBPath = "NoProjectTitle";
			pSuperVisApp->m_cLCBPath = ProjectFilename;

			HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

			//We know the path, we can Init Automation
			pSuperVisApp->m_SuperVisThread->PostThreadMessage(WM_INIT_AUTOMATION,0,(LPARAM)hEvent);
			
			WaitForSingleObject(hEvent,INFINITE);	
			CloseHandle(hEvent);

			
		}

	
	}
	END_TRY

}


SndReal dbg_calcul_pseudo_d(SndReal a,SndReal b)
{
    SndReal aa,bb;
	aa=abs(a);bb=abs(b);

    if (aa<bb)
        return (bb+(aa>>1));
    else
        return (aa+(bb>>1));
}

SndReal dbgSND_fn_rPseudoNormeVectorSnd(SndVector *v)
{
    SndReal dx,dy,dz;

    dx=abs(v->x);
    dy=abs(v->y);
    dz=abs(v->z);

    return dbg_calcul_pseudo_d(dbg_calcul_pseudo_d(dx,dy),dz);
}

