/* TopStrap_auto.cpp - custom program file for project TopStrap_auto */

#include "stdafx.h"
#include "TopStrap_auto.h"

/* TODO: place references to your functions and global variables in the TopStrap_auto.h file */

// local function prototypes
// this function is called when a valid slotchange notification is extracted from the InfoNotify
BOOL SlotChange(UINT iDriver,UINT iSlot, LPCSTR szSlot);

//
//  FUNCTION: InfoNotify()
//
//  PURPOSE: Callback function from an infodriver, notifying event
//
//  COMMENTS: the pointer pex references the infodriver which is notifying
//			  iSlot and szSlot are provided for convenience
//			
void InfoNotify(extinfo* pex,UINT iSlot,LPCSTR szSlot)
{
	switch (pex->iStatus) {
	case CONNECTED: // this is the "normal" situation
		UpdateCounters();
		if (!SlotChange(pex->iDevice,iSlot,szSlot)) 
			pex->setslot(iSlot,szSlot);
		break;

	case DISCONNECTED:
		Debug("Infodriver %d has disconnected", pex->iDevice);
	    DestroyWindow(hWndMain);
		return;
				
	case TO_RXONLY:
		Debug("Infodriver %d received request to go RX Only",pex->iDevice);
		break;

	case TO_TXRX:
		Debug("Infodriver %d received request to go TXRX",pex->iDevice);
		break;

	default:
		Debug("iStatus=%d",pex->iStatus);
		
	}

}

//
//  FUNCTION: SlotChange()
//
//  PURPOSE: Function called when slot change is notified
//
//  COMMENTS: All we need here are the driver number, the slot, and the new contents
//		
//	RETURNS: TRUE for processed (don't update the slot),
//			 FALSE for ignored (so calling function can just update the slot 
//								like a normal infodriver)
//			

BOOL SlotChange(UINT iDevice,UINT iSlot, LPCSTR szSlot){
	// TODO: Add slot processing and return TRUE if processed

	int intSlotValue = atoi(szSlot);

	switch (iSlot) {
		case SLOT_FLOOR_OFF:
			Debug("SLOT_FLOOR_OFF value=%d", intSlotValue);
			if((intSlotValue == GPI_OFF) ||(intSlotValue == GPI_ON)){
				setFloorOff(intSlotValue);
				ei.setslot(iSlot,szSlot);
			}
			break;	
		case SLOT_REH:
			Debug("SLOT_REH value=%d", intSlotValue);
			if((intSlotValue == GPI_OFF) ||(intSlotValue == GPI_ON)){
				setReh(intSlotValue);
				ei.setslot(iSlot,szSlot);
			}
			break;	
		case SLOT_TX:
			Debug("SLOT_TX value=%d", intSlotValue);
			if((intSlotValue == GPI_OFF) ||(intSlotValue == GPI_ON)){
				setTX(intSlotValue);
				ei.setslot(iSlot,szSlot);
			}
			break;	
		case SLOT_FLASH_TX:
			Debug("SLOT_FLASH_TX value=%d", intSlotValue);
			if ( InTXMode()==FALSE ) { // only react  if red lights not on
				if(intSlotValue == GPI_ON) {
					setFlashingTX(intSlotValue);
					ei.setslot(iSlot,szSlot);
				}
			}
			break;	
		case SLOT_BARS_LINE:
			Debug("SLOT_BARS_LINE current state=%d", intSDIBarsLineState);
			if(!strcmp(szSlot, "BARS_LINE")){
				//check that video bypass is not on
				if(intSDIBypassState != GPI_ON && intSDIBypassState_B !=GPI_ON && intSDIBypassState_RES !=GPI_ON){
					if(intSDIBarsLineState == GPI_OFF){
						setBarsLine(GPI_ON);
					}
					else {
						setBarsLine(GPI_OFF);
					}
				}
			}
			break;	
		case SLOT_BARS_RES1:
			if(!strcmp(szSlot, "BARS_RES1")){
				//check that video bypass is not on
				if(intSDIBypassState != GPI_ON && intSDIBypassState_B !=GPI_ON && intSDIBypassState_RES !=GPI_ON){
					if(intSDIBarsRes1State == GPI_OFF){
						setBarsRes1(GPI_ON);
					}
					else {
						setBarsRes1(GPI_OFF);
					}
				}
			}
			break;
		case SLOT_VENT_OFF:
			if(!strcmp(szSlot, "VENT_OFF")){
				if(intVentOffState == GPI_FORCE_OFF)
				{
					setVentOff(GPI_FORCE_ON);
				}
				else
				{
					setVentOff(GPI_FORCE_OFF);
				}
			}
			break;
		case SLOT_TONE_VT1_6:
			if(!strcmp(szSlot, "TONE_VT")){
				if(intVTTone16State != GPI_FORCE_ON){
					setTone(iSlot, GPI_FORCE_ON);
				}
				else{
					setTone(iSlot, GPI_FORCE_OFF);
				}
			}
			break;	
		case SLOT_TONE_VT7_12:
			if(!strcmp(szSlot, "TONE_VT")){
				if(intVTTone712State != GPI_FORCE_ON){
					setTone(iSlot, GPI_FORCE_ON);
				}
				else{
					setTone(iSlot, GPI_FORCE_OFF);
				}
			}
			break;	
		case SLOT_TONE_M1:
			if(!strcmp(szSlot, "TONE")){
				if(intToneM1State != GPI_FORCE_ON){
					setTone(iSlot, GPI_FORCE_ON);
				}
				else{
					setTone(iSlot, GPI_FORCE_OFF);
				}
			}
			break;	
		case SLOT_TONE_RES1:
			if(!strcmp(szSlot, "TONE")){
				if(intToneRes1State != GPI_FORCE_ON){
					setTone(iSlot, GPI_FORCE_ON);
				}
				else{
					setTone(iSlot, GPI_FORCE_OFF);
				}
			}
			break;
		case SLOT_INT_PROG_CUT:
			if(!strcmp(szSlot, "PROG_OFF")){
				if(intINTProgCutState != GPI_FORCE_ON){
					progCut(iSlot, GPI_FORCE_ON);
				}
				else{
					progCut(iSlot, GPI_FORCE_OFF);
				}
			}
			break;	
		case SLOT_EXT_PROG_CUT:
			if(!strcmp(szSlot, "PROG_OFF")){
				if(intEXTProgCutState != GPI_FORCE_ON){
					progCut(iSlot, GPI_FORCE_ON);
				}
				else{
					progCut(iSlot, GPI_FORCE_OFF);
				}
			}
			break;			
		case SLOT_VIDEO_BYPASS_A:
			if(!strcmp(szSlot, "BYPASS")){
				if( intSDIBypassState == GPI_OFF){
					setVideoBypass(GPI_ON,SLOT_VIDEO_BYPASS_A);
				}
				else{
					setVideoBypass(GPI_OFF,SLOT_VIDEO_BYPASS_A);
				}
			}
			break;
		case SLOT_VIDEO_BYPASS_B:
			if(!strcmp(szSlot, "BYPASS")){
				if( intSDIBypassState_B == GPI_OFF){
					setVideoBypass(GPI_ON,SLOT_VIDEO_BYPASS_B);
				}
				else{
					setVideoBypass(GPI_OFF,SLOT_VIDEO_BYPASS_B);
				}
			}
			break;
		case SLOT_VIDEO_BYPASS_Res:
			if(!strcmp(szSlot, "BYPASS")){
				if( intSDIBypassState_RES == GPI_OFF){
					setVideoBypass(GPI_ON,SLOT_VIDEO_BYPASS_Res);
				}
				else{
					setVideoBypass(GPI_OFF,SLOT_VIDEO_BYPASS_Res);
				}
			}
			break;
//		case SLOT_AUDIO_BYPASS_SRCE1:
//			//Check that bypass1 is not active
//			if(intAESBypass1State == GPI_OFF){
//				setAudioBypassSource(1, atoi(szSlot));
//			}
//			break;
//		case SLOT_AUDIO_BYPASS_PVW1:
//			if(!strcmp(szSlot, "PREVIEW")){
//				if(intAESBypass1PreviewState == BYPASS_PREVIEW_PVW){
//					setAudioBypassPreview(1, BYPASS_PREVIEW_DESK);
//				}
//				else{
//					setAudioBypassPreview(1, BYPASS_PREVIEW_PVW);
//				}
//			}
//			break;
//		case SLOT_AUDIO_BYPASS_ACTION1:
//
//			switch(intAESBypass1State){
//				case GPI_UNKNOWN:
//					//Either M1 or Res1 are in tone to line - no action
//					//note this should not be called by the panel
//					break;
//				case GPI_OFF:
//					//check if either tone to M1 or tone to Res1 are on
//					if(intAESToneM1State != GPI_ON && intAESToneRes1State != GPI_ON){
//						setAudioBypassState(1, GPI_ON);
//					}
//					break;
//				case GPI_ON:
//					setAudioBypassState(1, GPI_OFF);
//				break;
//			}
//			break;
//		case SLOT_AUDIO_BYPASS_SRCE2:{
//				//Check that bypass2 is not active
//				if(intAESBypass2State == GPI_OFF){
//					setAudioBypassSource(2, atoi(szSlot));
//				}
//			}
//			break;
//		case SLOT_AUDIO_BYPASS_PVW2:
//			if(!strcmp(szSlot, "PREVIEW")){
//				if(intAESBypass2PreviewState == BYPASS_PREVIEW_PVW){
//					setAudioBypassPreview(2, BYPASS_PREVIEW_DESK);
//				}
//				else{
//					setAudioBypassPreview(2, BYPASS_PREVIEW_PVW);
//				}
//			}
//			break;
//		case SLOT_AUDIO_BYPASS_ACTION2:
//			switch(intAESBypass2State){
//				case GPI_UNKNOWN:
//					//Either M2 or Res2 are in tone to line - no action
//					//note this should not be called by the panel
//					break;
//				case GPI_OFF:
//					//check if either tone to M1 or tone to Res1 are on
//					if(intAESToneM2State != GPI_ON && intAESToneRes2State != GPI_ON){
//						setAudioBypassState(2, GPI_ON);
//					}
//					break;
//				case GPI_ON:
//					setAudioBypassState(2, GPI_OFF);
//				break;
//			}
//			break;
//		// exrta functionality version 1.2  NOTE this is now a MGN function rather than a Studer AES router ADP
//		case SLOT_INT_PROG_CUT:
//			Debug("SLOT_INT_PROG_CUT value=%d", intSlotValue);
//			// only allow if not in TXmode - flashing or on
//			if (InTXMode()==FALSE) { // only react  if red lights not on
//				if(strcmp(szSlot, "INT_PROG_OFF")==0){
//					if(intINTProgCutState != GPI_ON){
//						setIntProgCut(GPI_ON);
//					}
//					else{
//						setIntProgCut(GPI_OFF);
//					}
//				}
//			}
//			else
//				Debug( "SLOT_INT_PROG_CUT ignored as in TX mode " );
//			break;			
//		case SLOT_EXT_PROG_CUT:
//			Debug("SLOT_EXT_PROG_CUT value=%d", intSlotValue);
//			if(strcmp(szSlot, "EXT_PROG_OFF")==0){
//				if(intEXTProgCutState != GPI_ON){
//					setExtProgCut(GPI_ON);
//				}
//				else{
//					setExtProgCut(GPI_OFF);
//				}
//			}
//			break;

		default:
			Debug("Slot change function from device %d - slot %d has changed to '%s'",iDevice,iSlot,szSlot);
			return FALSE;
	}

	return TRUE;
}

//
//  FUNCTION: CSIClientNotify()
//
//  PURPOSE: Callback function for incoming CSI messages for client class
//
//  COMMENTS: the message is supplied in szMsg
LRESULT CSIClientNotify(extclient* pec,LPCSTR szMsg) {

	UINT i;

	bncs_string strValue = pec->getparam(PEC_PARAM_VALUE);
	char szValue[256] = "";
	strcpy(szValue, strValue);
	strValue.remove(strValue.length()-1,1);
	strValue.remove(0,1);
	int intSourceIndex = 0;
	int intSlot = atoi(pec->getparam(PEC_PARAM_MIN));
	int intDevice = atoi(pec->getparam(PEC_PARAM_DEV_ID));

Debug("CSIClientNotify dev=%s slot=%s index=%s value=%s", pec->getparam(PEC_PARAM_DEV_ID),
	  pec->getparam(PEC_PARAM_MIN), pec->getparam(PEC_PARAM_INDEX), pec->getparam(PEC_PARAM_VALUE));

switch (pec->getstate())
	{
	case REVTYPE_R:
		intSourceIndex = atoi(pec->getparam(PEC_PARAM_INDEX));
		if(intDevice == intDeviceSDI){
			if(intSlot == intSDI_DEST_CCA_LINE){
				Debug("CSIClientNotify - SDI CCA LINE[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
				revSDICCALine(intSourceIndex);
			}
			else if(intSlot == intSDI_DEST_CCA_RES1){
				Debug("CSIClientNotify - SDI CCA RES1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
				revSDICCARes1(intSourceIndex);
			}
			else if(intSlot == intSDI_DEST_BYPASS){
				Debug("CSIClientNotify - SDI CCA RES1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
				revSDIBypass(intSourceIndex);
			}
		}
//		if(intDevice == intDeviceHD){
//			if(intSlot == intHD_DEST_CCA_LINE){
//				Debug("CSIClientNotify - HD CCA LINE[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revHDCCALine(intSourceIndex);
//			}
//			else if(intSlot == intHD_DEST_CCA_RES1){
//				Debug("CSIClientNotify - HD CCA RES1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revHDCCARes1(intSourceIndex);
//			}
//			else if(intSlot == intHD_DEST_BYPASS){
//				Debug("CSIClientNotify - HD CCA RES1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revHDBypass(intSourceIndex);
//			}
//		}
//		else if(intDevice == intDeviceAES){
//			if(intSlot == intAES_DEST_CCA_M1){
//				Debug("CSIClientNotify - AES CCA M1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESCCAM1(intSourceIndex);
//			}
//			else if(intSlot == intAES_DEST_CCA_M2){
//				Debug("CSIClientNotify - AES CCA M2[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESCCAM2(intSourceIndex);
//			}
//			else if(intSlot == intAES_DEST_CCA_RES1){
//				Debug("CSIClientNotify - AES CCA RES1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESCCARES1(intSourceIndex);
//			}
//			else if(intSlot == intAES_DEST_CCA_RES2){
//				Debug("CSIClientNotify - AES CCA RES2[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESCCARES2(intSourceIndex);
//			}
//			else if(intSlot == intAES_DEST_BYPASS1){
//				Debug("CSIClientNotify - AES BYPASS1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESBYPASS1(intSourceIndex);
//			}
//			else if(intSlot == intAES_DEST_BYPASS1){
//				Debug("CSIClientNotify - AES BYPASS1[%d] = %d %s", intSlot, intSourceIndex, pec->getparam(PEC_PARAM_VALUE));
//				revAESBYPASS2(intSourceIndex);
//			}
//		}
//		else if(intDevice == intDeviceStuder){
//			if(intSlot == intSTUDER_DEST_HWY_BYPASS1){
//				Debug("CSIClientNotify - STUDER DEST HWY BYPASS1[%d] = %d %s", intSlot, intSourceIndex, szValue);
//				revSTUDERBYPASS1(intSourceIndex);
//			}
//			else if(intSlot == intSTUDER_DEST_HWY_BYPASS1){
//				Debug("CSIClientNotify - STUDER DEST HWY BYPASS2[%d] = %d %s", intSlot, intSourceIndex, szValue);
//				revSTUDERBYPASS2(intSourceIndex);
//			}
//			else if(intSlot == intSTUDER_DEST_INT_PROG_CUT){  // new ver 1.2
//				Debug("CSIClientNotify - intSTUDER_DEST_INT_PROG_CUT[%d] = %d %s", intSlot, intSourceIndex, szValue);
//				revINTPROGCUT(intSourceIndex);
//			}
//			else if(intSlot == intSTUDER_DEST_EXT_PROG_CUT){ // new ver 1.2
//				Debug("CSIClientNotify - intSTUDER_DEST_EXT_PROG_CUT[%d] = %d %s", intSlot, intSourceIndex, szValue);
//				revEXTPROGCUT(intSourceIndex);
//			}
//		}
		//Debug ("Revertive message %s",szMsg);
		break;
	case REVTYPE_I:
		//Debug ("Revertive message %s",szMsg);
		//for (i=0;i<pec->getparamcount();Debug("Param %d is %s",++i,pec->getparam(i)));
		if(atoi(pec->getparam(PEC_PARAM_DEV_ID))== intDeviceMGNOutputs){
			if(atoi(pec->getparam(PEC_PARAM_MIN)) == intMGN_OUTPUT_REH){
				Debug("CSIClientNotify - MGNOutputReh = %d", strValue.toInt());
				revMGNOutputReh( strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== intMGN_OUTPUT_TX){
				Debug("CSIClientNotify - MGNOutputTX = %d", strValue.toInt());
				revMGNOutputTX( strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== intMGN_OUTPUT_TX){
				Debug("CSIClientNotify - MGNOutputTX = %d", strValue.toInt());
				revMGNOutputTX( strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_VENT_OFF){
				Debug("CSIClientNotify - sltMGN_OUTPUT_VENT_OFF = %d", strValue.toInt());
				setVentOff(strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_VTTONE16){
				Debug("CSIClientNotify - sltMGN_OUTPUT_VTTone16State = %d", strValue.toInt());
				setTone(SLOT_TONE_VT1_6, strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_VTONE712){
				Debug("CSIClientNotify - sltMGN_OUTPUT_VTTone712State = %d", strValue.toInt());
				setTone(SLOT_TONE_VT7_12, strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_TONEM1){
				Debug("CSIClientNotify - sltMGN_OUTPUT_ToneM1State = %d", strValue.toInt());
				setTone(SLOT_TONE_M1, strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_TONERES1){
				Debug("CSIClientNotify - sltMGN_OUTPUT_ToneRes1State = %d", strValue.toInt());
				setTone(SLOT_TONE_RES1, strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_INT_CUT){
				Debug("CSIClientNotify - sltMGN_OUTPUT_INT_CUT = %d", strValue.toInt());
				progCut(SLOT_INT_PROG_CUT, strValue.toInt());
			}
			else if(atoi(pec->getparam(PEC_PARAM_MIN))== sltMGN_OUTPUT_EXT_CUT){
				Debug("CSIClientNotify - sltMGN_OUTPUT_EXT_CUT = %d", strValue.toInt());
				progCut(SLOT_EXT_PROG_CUT, strValue.toInt());
			}
		}

		break;
	case REVTYPE_G:
		Debug ("Revertive message %s",szMsg);
		for (i=0;i<pec->getparamcount();Debug("Param %d is %s",++i,pec->getparam(i)));
		//TODO: Add parsing function for network commands
		break;

	case DATABASECHANGE:
		Debug ("Database change message - %s",szMsg);
		for (i=0;i<pec->getparamcount();Debug("Param %d is %s",++i,pec->getparam(i)));
		//TODO: Add parsing function for database changes
		break;

	case STATUS:
		Debug("Status message is %s",szMsg);
		break;

	case DISCONNECTED:
		Debug("CSI has closed down");
		break;

	}

/* always return TRUE so CSI doesn't delete your client registration */
return TRUE;
}
