#include <windows.h>
#include <stdio.h>
#include <bncs_string.h>
#include <bncs_config.h>
#include "Lab_Mon.h"

#define MAIN_PANEL	1
#define MAIN_PANEL_NAME "Lab_Mon.bncs_ui"

#define LEVEL_ENABLED "WN_Tally_Red"
#define LEVEL_DISABLED "WN_Tally_Black"

#define BUTTON_TIMEOUT	1				// Timer used to enable momentray display of pressed source button
#define BUTTON_TIMEOUT_PERIOD 250		// Duration that highlight is present before cleardown

#define CAR_MON 362						// CAR Monitoring is fixed package 361

//Make our class visible to the outside world
EXPORT_BNCS_SCRIPT( Lab_Mon )

// ++++++++++++++++++++++++++++++++++++++++++++ //
// Constructor - equivalent to ApplCore STARTUP //
// ++++++++++++++++++++++++++++++++++++++++++++ //
Lab_Mon::Lab_Mon(bncs_client_callback *parent, const char *path) : bncs_script_helper(parent, path)
{
// Initalise variables
	package_name_id = 0;
	package_xpts_id = 0;
	video_id = 0;
	audio_id = 0;
	video_dest = 0;
	audio_dest = 0;

	video_enabled = true;
	audio_enabled = true;

	// Read the BNCS driver ID's
	getDev("CAR Package Names", &package_name_id);
	getDev("CAR Package XPTS", &package_xpts_id);
	getDev("CAR SDI Router", &video_id);
	getDev("CAR Audio Router", &audio_id);

	// Extract the audio and video monitoring crosspoints
	extract_xpts(CAR_MON, 1, &video_dest, &audio_dest);

	// Show our panel
	panelShow(MAIN_PANEL, MAIN_PANEL_NAME);

	// Ensure that the level enable rings are correct colours
	if (video_enabled)
		textPut("statesheet", LEVEL_ENABLED, MAIN_PANEL, "VideoEnable");
	else
		textPut("statesheet", LEVEL_DISABLED, MAIN_PANEL, "VideoEnable");

	if (audio_enabled)
		textPut("statesheet", LEVEL_ENABLED, MAIN_PANEL, "AudioEnable");
	else
		textPut("statesheet", LEVEL_DISABLED, MAIN_PANEL, "AudioEnable");

	// Register for revertives from video and audio routers
	routerRegister(video_id, video_dest, video_dest);
	routerRegister(audio_id, audio_dest, audio_dest);

	// Poll for initial state
	routerPoll(video_id, video_dest, video_dest);
	routerPoll(audio_id, audio_dest, audio_dest);
}

// +++++++++++++++++++++++++++++++++++++++++++++ //
// Destructor - equivalent to ApplCore CLOSEDOWN //
// +++++++++++++++++++++++++++++++++++++++++++++ //
Lab_Mon::~Lab_Mon()
{
	routerUnregister(video_id);
	routerUnregister(audio_id);
}

// ++++++++++++++++++++++++++++++++++++++++++++++ //
// All button pushes and notifications come here. //
// ++++++++++++++++++++++++++++++++++++++++++++++ //
void Lab_Mon::buttonCallback( buttonNotify *b )
{
	if(b->panel() == MAIN_PANEL)
	{
		if (b->id() == "Sources")		// Source button?
		{
			if (b->command() == ("index"))
			{
				if (b->value() > 0)
				{
					int vid_src = 0, aud_src = 0;
					// Extract the source crosspoints from the package
					extract_xpts(b->value(), 0, &vid_src, &aud_src);
					// Make crosspoints
					if (video_enabled && (vid_src != 0)) routerCrosspoint(video_id, vid_src, video_dest);
					if (audio_enabled && (aud_src != 0)) routerCrosspoint(audio_id, aud_src, audio_dest);
					// Start the timeout counter to canel the source button.
					timerStart(BUTTON_TIMEOUT, BUTTON_TIMEOUT_PERIOD);
				}
			}
			return;
		}

		if (b->id() == "WFM_Mon")
		{
			video_enabled = (video_enabled == true) ? false : true;		// Toggle the enabled flag.
			textPut("statesheet", video_enabled ? LEVEL_ENABLED : LEVEL_DISABLED, MAIN_PANEL, "VideoEnable");	// Update the display
			return;
		}

		if (b->id() == "Audio_Mon")
		{
			audio_enabled = (audio_enabled == true) ? false : true;		// Toggle the enabled flag.
			textPut("statesheet", audio_enabled ? LEVEL_ENABLED : LEVEL_DISABLED, MAIN_PANEL, "AudioEnable");	// Update the display
			return;
		}
	}
}

// +++++++++++++++++++++++++ //
// All revertives come here. //
// +++++++++++++++++++++++++ //
int Lab_Mon::revertiveCallback( revertiveNotify * r )
{
	if (r->device() == video_id)
	{
		if (r->index() == video_dest)
		{
			textPut("text", r->sInfo(), MAIN_PANEL, "video_source");
			return 0;
		}
	}

	if (r->device() == audio_id)
	{
		if (r->index() == audio_dest)
		{
			textPut("text", r->sInfo(), MAIN_PANEL, "audio_source");
			return 0;
		}
	}
	
	return 0;
}

// +++++++++++++++++++++++++++++++++++++++++ //
// All database name changes come back here. //
// +++++++++++++++++++++++++++++++++++++++++ //
void Lab_Mon::databaseCallback( revertiveNotify * r )
{
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++ //
// All parent notifications come here. For example when //
// this script is just one component of another dialog, //
// then our host might want to tell us things.          //
// ++++++++++++++++++++++++++++++++++++++++++++++++++++ //
bncs_string Lab_Mon::parentCallback( parentNotify *p )
{
	if( p->command() == "return" )
	{
		if( p->value() == "all" )
		{	// Persisting values for bncs_vis_ed
			bncs_stringlist sl="";
						
			return sl.toString( '\n' );
		}
	}

	// ***** 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 = "";
				
		return sl.toString( '\n' );
	}

	return "";
}

// +++++++++++++++++++++++ //
// Timer events come here. //
// +++++++++++++++++++++++ //
void Lab_Mon::timerCallback( int id )
{
	switch(id)
	{
	case BUTTON_TIMEOUT:
		timerStop(BUTTON_TIMEOUT);
		textPut("select=-1", MAIN_PANEL, "Sources");
		break;

	default:	// Unhandled timer event
		timerStop(id);
		break;
	}
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// Callbacks above - Methods below ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Lab_Mon::extract_xpts(int pkg_id, int database, int *viddest, int *auddest)
{
	// pkg is the page number to process, databases is 0 for sources, 1 for destinations
	// viddest and auddest are the addresses for the results.
	bncs_string xptlist, p1, p2;

	routerName(package_xpts_id, database, pkg_id, xptlist);	// Read comma delimited string
	xptlist.split(',', p1, p2);								// Divide into two parts
	if (p1 == "-") *viddest = 0;
	else *viddest = p1.toInt();
	if (p2 == "-") *auddest = 0;
	else *auddest = p2.toInt();
}

