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

#define PNL_MAIN 1

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

// constructor - equivalent to ApplCore STARTUP
MultiviewerOverride::MultiviewerOverride( bncs_client_callback * parent, const char * path ) : bncs_script_helper( parent, path )
{
	m_tx=false;
	
	// show a panel from file p1.bncs_ui and we'll know it as our panel 1
	panelShow( 1, "p1.bncs_ui" );

	//get values from automatics.xml
	controlledDevice = getConfigEntry("automatics.router_values.Bredon_MVW", "value");
	deviceInfoDriver = getConfigEntry("automatics.router_values.Bredon_info", "value");
	maxDest = getConfigEntry("automatics.router_values.Bredon_MVW.MAX_DEST", "value");

	textPut("text", controlledDevice, PNL_MAIN, "ControlledDevice");

	// you may need this call to set the size of this component 
	//  if it's used in a popup window 
//	setSize( 1024,668 );		// set the size explicitly
//	setSize( 1 );				// set the size to the same as the specified panel

	// connect to our infodriver host
	m_info = new ccInfodriver( this );

	// don't really hard code yer device number....
	m_info->connect( deviceInfoDriver );
	
	// connect to multiviewer and poll it
	routerRegister(controlledDevice, 1, maxDest, false);
	routerPoll(controlledDevice, 1, maxDest);
}

// destructor - equivalent to ApplCore CLOSEDOWN
MultiviewerOverride::~MultiviewerOverride()
{
	delete m_info;
	routerUnregister(controlledDevice);
}

// all button pushes and notifications come here
void MultiviewerOverride::buttonCallback( buttonNotify *b )
{

}

// all revertives come here
int MultiviewerOverride::revertiveCallback( revertiveNotify * r )
{
	if (r->device() == controlledDevice)
	{
		if ((r->info() != r->index())&&(m_tx==true))
		//all sources should be routed straight through, src1 to dest1, src2 to dest2 and etc
		//if they have been route away, force them back
		//this is to stop monitoring in the classroom being messed up
		{
			int s = r->index();
			routerCrosspoint(controlledDevice, s, s);
		}

	}
	return 0;
}

// all database name changes come back here
void MultiviewerOverride::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 MultiviewerOverride::parentCallback( parentNotify *p )
{
	if( p->command() == "return" )
	{
		bncs_stringlist sl;
		
		sl << "myParam=" + m_myParam;
		
		return sl.toString( '\n' );
	}
	else if( p->command() == "myParam" )
	{
		m_myParam = p->value();
	}
	return "";
}

// timer events come here
void MultiviewerOverride::timerCallback( int id )
{
}



/** Request from client to change a slot
\param[in] device The device number
\param[in] index The slot number
\param[in] slot The requested contents to use
\note This command does not automatically update the contents of the slot
*/
void MultiviewerOverride::cciSlotRequest( int device, int index, const string & slot )
{
	// convert incoming STL string to local bncs_string so all our favourite string-wrangling 
	// calls will work (STL string doesn't have many)
	bncs_string s( slot );

	// just use the string s as usual
	textPut( "text", "Request to set slot to:|" + s, 1, 4 );
}

/** Direct message from a client requesting workstation specific information on this device
\param[in] workstation The workstation requesting the information
\param[in] device The device number
\param[in] message The message string from the client
\param[in] reference An arbitary message reference that should be returned with the reply to this command
\sa ccInfodriver::clientMessage();
\note Implementation of this messaging mechanism is patchy so beware....
*/
void MultiviewerOverride::cciClientMessage( int workstation, int device, const string & message, const string & clientHandle, const string & reference )
{
}

/** Notification of redundancy state
\param[in] state The current state
*/
void MultiviewerOverride::cciRedundancyState( enum cc::redundancyState state )
{
	switch( state )
	{
		case cc::tx:
			// set our internal flag to know whether this automatic is active and we should
			// be sending client commands to the network
			m_tx=true;
			break;
		case cc::rx:
			m_tx=false;
			break;
	}
}

/** Connected event */
void MultiviewerOverride::cciConnected( int )
{
	textPut( "text", "Connected to Infodriver", 1, 4 );
}

/** Disconnected event */
void MultiviewerOverride::cciDisconnected( int )
{
	textPut( "text", "Connected to Infodriver", 1, 4 );
}

int MultiviewerOverride::getConfigEntry(bncs_string sKey, bncs_string sAttr)
//helper code to query automatics.xml
{
	bncs_string sRet = "";
	int iRet = -1;
	bncs_config c(sKey);

	if (c.isValid())
		sRet = c.attr(sAttr);
	iRet = sRet.toInt();
	return iRet;
}