#include <windows.h>
#include <stdio.h>
#include <bncs_string.h>
#include <bncs_config.h>
#include "CameraAssign.h"

#define MAIN_PANEL	1
#define MAIN_PANEL_NAME	"CCU_Allocate.bncs_ui"
#define STATE_DESELECT	"WNSourceDeselected"
#define STATE_SELECT	"WNSourceSelected"
#define CONFIRM_HI		"WN_TakeHigh"
#define CONFIRM_LO		"WN_TakeLow"
#define ALLOC_NONE 0
#define ALLOC_STA 1
#define ALLOC_RESERVED 2
#define ALLOC_STC 3

#define FIRSTCCU	1
#define NUMCCU		10
#define TIMER_CONFIRM	1
#define INIT_TIMER_COUNT 15

// this nasty little macro to make our class visible to the outside world
EXPORT_BNCS_SCRIPT( CameraAssign )

// constructor - equivalent to ApplCore STARTUP
CameraAssign::CameraAssign( bncs_client_callback * parent, const char * path ) : bncs_script_helper( parent, path )
{
	current_value = "";
	allocating = false;
	deallocate_active = false;
	allocate_A_active = false;
	allocate_C_active = false;
	confirm_active = false;
	timer_active = false;

	// show a panel from file p1.bncs_ui and we'll know it as our panel PNL_MAIN
	panelShow(MAIN_PANEL, MAIN_PANEL_NAME);

}

// destructor - equivalent to ApplCore CLOSEDOWN
CameraAssign::~CameraAssign()
{
}

// all button pushes and notifications come here
void CameraAssign::buttonCallback( buttonNotify *b )
{
	if(b->panel() == MAIN_PANEL)
	{
		// Check for the Cancel button
		if (b->id() == "Cancel")
		{
			// If we are in allocate mode, need to disable the allocate value buttons, and enable the CCU selection buttons
			// If we are not in allocate mode, Cancel button should not be active
			ClearAction();		// Clear down allocation buttons and re-enable the CCU selectors
			return;
		}

		// Check for the Allocate to Studio C button
		if (b->id() == "Allocate_A")
		{
			new_mode = ALLOC_STA;
			textPut("statesheet", STATE_SELECT, MAIN_PANEL, "Allocate_A"); // Remove the highlight from CCU ID button 
			controlEnable(MAIN_PANEL, "Confirm");
			if (allocate_C_active)
			{
				textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_C");
				allocate_C_active = false;
			}
			allocate_A_active = true;

			return;
		}

		// Check for the Allocate to Studio C button
		if (b->id() == "Allocate_C")
		{
			new_mode = ALLOC_STC;
			textPut("statesheet", STATE_SELECT, MAIN_PANEL, "Allocate_C"); // Highlight that Allocation to C mode is active
			if (allocate_A_active)
			{
				textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_A");
				allocate_A_active = false;
			}
			allocate_C_active = true;
			EnableConfirm();

			return;
		}

		// Check for the Deallocate button
		if (b->id() == "Deallocate")
		{
			new_mode = ALLOC_NONE;
			textPut("statesheet", STATE_SELECT, MAIN_PANEL, "Deallocate"); // Highlight the Deallocate button
			EnableConfirm();
			deallocate_active = true;

			return;
		}

		// Check for the Confirm Button
		if (b->id() == "Confirm")
		{
			// Action the new mode by storing the data in the mimic control
			textPut("value",bncs_string(new_mode) , MAIN_PANEL, bncs_string(edit_ccu));

			ClearAction();		// Clear down allocation buttons and re-enable the CCU selectors

			return;
		}

		// Is this a CCU button?
		if (b->id().startsWith("CCU_"))		
		{
			if (!allocating)
			{
				edit_ccu = b->id().firstInt();					// Extract the CCU number from button ID
				for (int i = FIRSTCCU; i <= NUMCCU; i++)
					controlDisable(MAIN_PANEL, bncs_string("CCU_") + bncs_string(i));	// Disable all the selection buttons
				
				controlEnable(MAIN_PANEL, b->id());										// then re-enable the pressed button
				textPut("statesheet", STATE_SELECT, MAIN_PANEL, b->id());				// Highlight the CCU button
				allocating = true;														// Record that we are doing allocation operations

				textGet("value", MAIN_PANEL, bncs_string(edit_ccu), current_value);		// Fetch current CCU allocation from CCU status mimic label

				if (current_value.firstInt() != ALLOC_NONE)		// Allocated CCUs must first be deallocated
				{
					// this ccu is already routed somewhere. Only deallocation or CANCEL is valid. Enable those butons
					controlEnable(MAIN_PANEL, "Deallocate");
					controlEnable(MAIN_PANEL, "Cancel");
				}
				else
				{
					// CCU is not allocated. Enable selectors for Studio A and Studio C, and Cancel
					controlEnable(MAIN_PANEL, "Allocate_A");
					controlEnable(MAIN_PANEL, "Allocate_C");
					controlEnable(MAIN_PANEL, "Cancel");
				}
			}
			return;
		}	// End of if (b->id().startsWith("CCU_"))		


	}	// End of if(b->panel() == MAIN_PANEL)
}	// End of button callback function.

// all revertives come here
int CameraAssign::revertiveCallback( revertiveNotify * r )
{
/*
	switch( r->device() )
	{
		case 123:
 			textPut( "text", r->sInfo(), 1, 3 );
			break;
	}
*/

	return 0;
}

// all database name changes come back here
void CameraAssign::databaseCallback( revertiveNotify * r )
{
}


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
// All parent notifications come here i.e. when this script is just one    //
// component of another dialog then our host might want to tell us things. //
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
bncs_string CameraAssign::parentCallback( parentNotify *p )
{
	if( p->command() == "return" )
	{
		if( p->value() == "all" )
		{	// Persisting values for bncs_vis_ed
			bncs_stringlist sl;
			
			sl << bncs_string( "myParam=%1" ).arg( m_myParam );
			
			return sl.toString( '\n' );
		}

		else if( p->value() == "myParam" )
		{	// Specific value being asked for by a textGet
			return( bncs_string( "%1=%2" ).arg( p->value() ).arg( m_myParam ) );
		}

	}
	else if( p->command() == "instance" && p->value() != m_instance )
	{	// Our instance is being set/changed
		m_instance = p->value();
		//Do something instance-change related here
	}

	else if( p->command() == "myParam" )
	{	// Persisted value or 'Command' being set here
		m_myParam = p->value();
	}

	// ***** CONNECTIONS EVENTS HELPER LIST *****
	else if( p->command() == "_events" )
	{	// Helper-list of everything in this component generated by hostNotify's
		bncs_stringlist sl;

		sl << "notify=*";		
		
		return sl.toString( '\n' );
	}

	// ***** CONNECTIONS COMMANDS HELPER LIST *****
	else if( p->command() == "_commands" )
	{	// Helper-list of any commands/parameters you might want to set at run-time
		bncs_stringlist sl;
		
		sl << "myParam=[value]";
		
		return sl.toString( '\n' );
	}

	return "";
}


// +++++++++++++++++++++++ //
// Timer events come here. //
// +++++++++++++++++++++++ //
void CameraAssign::timerCallback( int id )
{
	switch (id)
	{
	case TIMER_CONFIRM:
		timeoutCounter--;			// Decrement timeout count
		if ((timeoutCounter & 1) == 1)
			textPut("statesheet", CONFIRM_HI, MAIN_PANEL, "Confirm");
		else
			textPut("statesheet", CONFIRM_LO, MAIN_PANEL, "Confirm");

		if (timeoutCounter == 0)	// Manage end of timeout period
		{
			timerStop(TIMER_CONFIRM);
			timer_active = false;
			if (deallocate_active)
			{
				textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Deallocate");
				deallocate_active = false;
			}
			if (allocate_A_active)
			{
				textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_A");
				allocate_A_active = false;
			}
			if (allocate_C_active)
			{
				textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_C");
				allocate_C_active = false;
			}
			
			textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Confirm");
			controlDisable(MAIN_PANEL, "Confirm");
			confirm_active = false;
		}
		break;

	default:	// Unhandled timer event
		timerStop(id);
		break;
	}
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// Callbacks above - Methods below ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


void CameraAssign::ClearAction(void)
{
	if (allocating)
	{
		if (deallocate_active)
		{
			textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Deallocate");
			deallocate_active = false;
		}
		if (allocate_A_active)
		{
			textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_A");
			allocate_A_active = false;
		}
		if (allocate_C_active)
		{
			textPut("statesheet", STATE_DESELECT, MAIN_PANEL, "Allocate_C");
			allocate_C_active = false;
		}
		if (timer_active)
		{
			timerStop(TIMER_CONFIRM);
			timer_active = false;
		}
		controlDisable(MAIN_PANEL, "Confirm");			// Disable all allocation buttons
		controlDisable(MAIN_PANEL, "Cancel");
		controlDisable(MAIN_PANEL, "Deallocate");
		controlDisable(MAIN_PANEL, "Allocate_A");
		controlDisable(MAIN_PANEL, "Allocate_C");

		textPut("statesheet", STATE_DESELECT, MAIN_PANEL, bncs_string("CCU_") + bncs_string(edit_ccu)); // Remove the highlight from CCU ID button 
		for (int i = FIRSTCCU; i <= NUMCCU; i++)
			controlEnable(MAIN_PANEL, bncs_string("CCU_") + bncs_string(i));	// Enable all the CCU selection buttons 

		allocating = false;
	}
}

void CameraAssign::EnableConfirm(void)
{
	controlEnable(MAIN_PANEL, "Confirm");						// Enable the control
	textPut("statesheet", CONFIRM_HI, MAIN_PANEL, "Confirm");	// Put the Confirm button highlight active
	timerStart(TIMER_CONFIRM, 1000);
	timeoutCounter = INIT_TIMER_COUNT;
	timer_active = true;
}

