#include <windows.h>
#include <stdio.h>
#include <bncs_string.h>
#include <bncs_config.h>
#include "pseudo.h"

#define MAIN1024	1
#define MAIN1024_NAME "panel1024.bncs_ui"

#define TIMER_SETUP	1

#define PSEUDOMATRIX 3
#define GPIDRIVER 1
#define INFODRIVER 2

// Make our class visible to the outside world
EXPORT_BNCS_SCRIPT(pseudo)

// Constructor - equivalent to ApplCore STARTUP
pseudo::pseudo( bncs_client_callback * parent, const char * path ) : bncs_script_helper( parent, path )
{
	matrix_id = PSEUDOMATRIX;
	gpi_id = GPIDRIVER;
	info_id = INFODRIVER;
	tally_off = "#000000";
	tally_on = "#E00000";

	// Load the names of the channel pictures from database 6 of driver 1
	for (int i=1; i <= MATRIXSIZE; i++)
	{
		routerName(matrix_id, 6, i, imgs[i]);
	}
	// Add an image for a return value of 0 (parked)
	imgs[0] = "chanimg/parked.jpg";
	debug(imgs[1]);

	// Define the ON colours of the GPI lights
	lamps[0] = "#000000";
	lamps[1] = "#ff0000";
	lamps[2] = "#00ff00";
	lamps[3] = "#2020ff";
	lamps[4] = "#c0c000";
	lamps[5] = "#cb54c9";
	lamps[6] = "#ffc783";
	lamps[7] = "#d1d810";
	lamps[8] = "#1fa69d";
	lamps[9] = "#ffffdc";
	lamps[10] = "#ffaaff";
	lamps[11] = "#aaffbc";
	lamps[12] = "#3a30ff";
	lamps[13] = "#ffff7f";
	lamps[14] = "#ffffdc";
	lamps[15] = "#ffffdc";
	lamps[16] = "#e6e9ff";

	// Define the text colours to contrast well with the lamp ON colours above
	txt[0] = "#ffffff";
	txt[1] = "#ffffff";
	txt[2] = "#000000";
	txt[3] = "#ffffff";
	txt[4] = "#ffffff";
	txt[5] = "#ffffff";
	txt[6] = "#000000";
	txt[7] = "#000000";
	txt[8] = "#ffffff";
	txt[9] = "#000000";
	txt[10] = "#000000";
	txt[11] = "#000000";
	txt[12] = "#ffffff";
	txt[13] = "#000000";
	txt[14] = "#000000";
	txt[15] = "#000000";
	txt[16] = "#000000";

	// Show a main panel
	panelShow(MAIN1024, MAIN1024_NAME);

	// Register for revertives
	routerRegister(matrix_id, 1, MATRIXSIZE);
	gpiRegister(gpi_id, 1, 16);
	infoRegister(info_id, 1, 40);

	// Poll for initial state
	routerPoll(matrix_id, 1, MATRIXSIZE);
	gpiPoll(gpi_id, 1, 16);
	infoPoll(info_id, 1, 40);
}

// destructor - equivalent to ApplCore CLOSEDOWN
pseudo::~pseudo()
{
	routerUnregister(matrix_id);
	gpiUnregister(gpi_id);
	infoUnregister(info_id);
}

// all button pushes and notifications come here
void pseudo::buttonCallback( buttonNotify *b )
{
	if( b->panel() == 1 )
	{
		// Not expecting any buttons!
	}
}

// all revertives come here
int pseudo::revertiveCallback( revertiveNotify * r )
{
	// Test for Matrix crosspoint report
	if (r->device() == matrix_id)
	{
		textPut("pixmap", imgs[r->info()], MAIN1024, bncs_string("Mon_") + bncs_string(r->index()));
		return 0;
	}

	// Check for GPI state change report
	if ((r->device() == gpi_id) && (r->index() <= 16))
	{
		if (r->info() == 0)
		{
			textPut("colour.background", lamps[0], MAIN1024, bncs_string("GPI_%1").arg(r->index()));
			textPut("colour.text", txt[0], MAIN1024, bncs_string("GPI_%1").arg(r->index()));
		}
		else
		{
			textPut("colour.background", lamps[r->index()], MAIN1024, bncs_string("GPI_%1").arg(r->index()));
			textPut("colour.text", txt[r->index()], MAIN1024, bncs_string("GPI_%1").arg(r->index()));
		}

		return 0;
	}

	// Check for the Infodriver slots that do the text and tally lights
	if (r->device() == info_id)
	{
		if ((r->index() >= 1) && (r->index() <= 12))
		{
			// New text to display
			textPut("text", r->sInfo(), MAIN1024, bncs_string("UMD_%1").arg(r->index()));	// Store the text
			return 0;
		}

		if ((r->index() >= 21) && (r->index() <= 32))
		{
			// New Tally state. 0 = both off, 1 = left tally on, 2=right tally on, 3=both tally on
			switch (r->sInfo().toInt())
			{
			case 0:
				textPut("colour.background", tally_off, MAIN1024, bncs_string("UMDL_%1").arg(r->index() - 20));
				textPut("colour.background", tally_off, MAIN1024, bncs_string("UMDR_%1").arg(r->index() - 20));
				break;
			case 1:
				textPut("colour.background", tally_on, MAIN1024, bncs_string("UMDL_%1").arg(r->index() - 20));
				textPut("colour.background", tally_off, MAIN1024, bncs_string("UMDR_%1").arg(r->index() - 20));
				break;
			case 2:
				textPut("colour.background", tally_off, MAIN1024, bncs_string("UMDL_%1").arg(r->index() - 20));
				textPut("colour.background", tally_on, MAIN1024, bncs_string("UMDR_%1").arg(r->index() - 20));
				break;
			case 3:
				textPut("colour.background", tally_on, MAIN1024, bncs_string("UMDL_%1").arg(r->index() - 20));
				textPut("colour.background", tally_on, MAIN1024, bncs_string("UMDR_%1").arg(r->index() - 20));
				break;
			default:
				break;
			}

			return 0;
		}
		
	}
	return 0;
}

// all database name changes come back here
void pseudo::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 pseudo::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 pseudo::timerCallback( int id )
{
	switch( id )
	{
	case TIMER_SETUP:
		timerStop(id);
		break;

	default:	// Unhandled timer event
		timerStop(id);
		break;
	}
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// Callbacks above - Methods below ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////


