//-----------------------------------------------------------------------------
// Options (not used at the mo)
var BTN_BACK 		= true;
var BTN_FORWARD 	= true;
var BTN_PRINT 		= true;
var BTN_HELP 		= true;
var BTN_CONTENTS 	= true;
var ANSWERS 		= true;

//-----------------------------------------------------------------------------
// Add some functionality that may be missing
if (Array.prototype.push && ([0].push(true)==true))
        Array.prototype.push = null;

if(!Array.prototype.push)
{
    function array_push()
    {
        for(i=0;i<arguments.length;i++)
        {
            this[this.length] = arguments[i];
        }
        return this.length;
    }
    Array.prototype.push = array_push;
}

if(!Array.prototype.pop)
{
    function array_pop()
    {
        lastElement = this[this.length-1];
        this.length = Math.max(this.length-1,0);
        return lastElement;
    }
    Array.prototype.pop = array_pop;
}


//-----------------------------------------------------------------------------
// Layout constants and initialisation

var BANNER_MAX_WIDTH = 900;
var BANNER_MIN_WIDTH = 640;
var TOOLBAR_HEIGHT = 69;
var CONTENT_WIDTH = 640;
var sMode = null;

// Setup and resizing
function init(mode)
{
	// Store mode for later
	sMode = mode;

	var oTopicSelector = document.getElementById("quicklinks");
	var oContentArea = document.getElementById('contentarea');
	var oToolbar = document.getElementById('toolbar');

	// mcs specific layout
	if(mode=='mcs')
	{
		oContentArea.style.overflowY='visible';
		oContentArea.style.lineHeight='24px';
		oToolbar.style.width=614;
	}

	// Toolbar resize
	if(mode!='mcs')
	{
		// Setup layout
		resize();

		// Register callback for window resize
		document.body.onresize = resize;
	}

	// Make sure topic selector is default
	oTopicSelector.selectedIndex=0;

	// Scroll pos stuff
	if(mode!='mcs')
	{
		getScrollData();
	}

	// Printing of non mcs layout version
	if(mode!='mcs')
	{
		window.onbeforeprint = beforeprint;
		window.onafterprint = afterprint;
	}

	// Preload rollover images for navigation
	if(mode!='mcs')
	{
		 imgNavBackH 	    = new Image();
		 imgNavBackH.src    = "/shared/embed/layout/back_h.png";
		 imgNavForwardH     = new Image();
		 imgNavForwardH.src = "/shared/embed/layout/forward_h.png";
		 imgNavContH 	    = new Image();
		 imgNavContH.src    = "/shared/embed/layout/cont_h.png";
		 imgNavPrintH 	    = new Image();
		 imgNavPrintH.src   = "/shared/embed/layout/print_h.png";
		 imgNavHelpH 	    = new Image();
		 imgNavHelpH.src    = "/shared/embed/layout/help_h.png";
	}

	// TODO: Set initial state of back and forward button

}

function resize()
{
	// Get references to the two main objects: banner and content
	var oBanner  = document.getElementById('toolbar');
	var oContent = document.getElementById('contentarea');

	// Get amount of space we have to work with
	var clientWidth  = document.body.clientWidth;
	var clientHeight = document.body.clientHeight;
	var nAvailableY = clientHeight - TOOLBAR_HEIGHT;  // Take into account the banner height
	var nAvailableX = clientWidth - CONTENT_WIDTH;    // Any horizontal space that isnt the content

	// We want to set content area height to maximum
	oContent.style.height = nAvailableY;

	// Keep within sensible dimensions on super high res
	if( clientWidth-10<BANNER_MIN_WIDTH )
	{
		oBanner.style.width = BANNER_MIN_WIDTH;
	} else if( clientWidth-10>BANNER_MAX_WIDTH ) {
		oBanner.style.width = BANNER_MAX_WIDTH;
	} else {
		oBanner.style.width = clientWidth-10;
	}

	// Centre content area
	oContent.style.left = nAvailableX/2;
}

//-------------------------------------------------------------------------
// Autoupdate topic selector based upon position
var aPositions = new Array();
function getScrollData()
{
	var aTopics = document.getElementsByTagName('a');

	var index=0;

	for(var i=0; i<aTopics.length; i++)
	{
		if( aTopics[i].name!="" && ( typeof aTopics[i].name != 'undefined' )   )
		{
			aPositions[index] = aTopics[i].offsetTop;
			index++;
		}
	}
}

function updateScrollPos(oContentArea)
{
	var current = oContentArea.scrollTop;
	var quicklinks = document.getElementById('quicklinks');

	for(var i=0; i<aPositions.length; i++)
	{
		if(aPositions[i] <= current && (aPositions[i+1] > current || (typeof aPositions[i+1]=='undefined')))
		{
			quicklinks.selectedIndex = i;
			break;
		}
	}
}

//-------------------------------------------------------------------------
// Hook up navigation

var navStack = new Array();
var navStackPosition = -1;

// Scroll to top of topic
function navigateTo( target )
{
	var current = document.location.href;
	var base = current.indexOf('#') ? current.substring(0,current.indexOf('#')) : current;

	// Internal or external (of which there should never be any)
	if( target.charAt(0)=='#' )
	{
		var link = document.getElementById( target.substring(1,target.length) );
		link.scrollIntoView(true);

		// If this is the first internal link, we want to store the top in the history
		if( navStackPosition==-1 )
		{
			navStack.push('#ccTop');
			navStackPosition++;
		}

		navStack.push(target);
		navStackPosition++;
		// TODO: Enable back button if it isnt already
	} else {
		document.location.href = target;
	}
}

function back()
{
	// If the internal navigation stack is empty, go into the browser history
	if( navStackPosition<=0 )
	{
		history.back();
	} else {
		// Do the navigation
		var target = navStack[--navStackPosition];
		var link = document.getElementById( target.substring(1,target.length) );
		link.scrollIntoView(true);
		// Change the selected topic in the topic selector (there is a better way to do this)
		var oTopicSelector = document.getElementById("quicklinks");
		for(var i=0; i<oTopicSelector.options.length; i++)
		{
			if(oTopicSelector.options[i].value==target)
			{
				oTopicSelector.selectedIndex=i;
				break;
			}
		}
		// Set backbutton state
		if(navStack.length==0 && history.length==0)
			setBackState(false);
	}
}

function forward()
{
	// If the internal navigation stack is empty, go into the browser history
	if( (navStackPosition+1)>=navStack.length )
	{
		// Do nothing, forward button should be disabled
	} else {
		// Do the navigation
		var target = navStack[++navStackPosition];
		var link = document.getElementById( target.substring(1,target.length) );
		link.scrollIntoView(true);
		// Change the selected topic in the topic selector (there is a better way to do this)
		var oTopicSelector = document.getElementById("quicklinks");
		for(var i=0; i<oTopicSelector.options.length; i++)
		{
			if(oTopicSelector.options[i].value==target)
			{
				oTopicSelector.selectedIndex=i;
				break;
			}
		}
		// Set forward button state
		if(navStack.length==0 && history.length==0)
			setBackState(false);
	}
}

function doprint()
{
	window.print();
}

//-----------------------------------------------------------------------------
// Button event handlers
function btn_mouseover()
{
	oTarget = window.event.srcElement;
	oTarget.baseClass = oTarget.className;
	oTarget.className += "_h btn_over";
}

function btn_mouseout()
{
	oTarget = window.event.srcElement;
	oTarget.className = oTarget.baseClass;
}

function btn_mousedwn()
{
	oTarget = window.event.srcElement;
	oTarget.className = oTarget.baseClass;
	oTarget.className += "_h btn_dwn";
}

function btn_mouseup( action )
{
	oTarget = window.event.srcElement;
	oTarget.className = oTarget.baseClass;
	oTarget.className += "_h btn_over";
	eval(action);
}

function setBackState( state )
{
	// Ability to disable back button
	// Not Essential as very unlikely history will be empty
}

function setForwardState( state )
{
	// Ability to disable back button
	// Not Essential as very unlikely history will be empty
}

//----------------------------------------------------
// Show printable version
function beforeprint()
{
	document.getElementById("toolbar").style.visibility="hidden";
	document.getElementById("contentarea").style.overflowY="visible";
}

function afterprint()
{
	document.getElementById("toolbar").style.visibility="visible";
	document.getElementById("contentarea").style.overflowY="scroll";
}

//----------------------------------------------------
// Show help
function help()
{
	window.open("help.html");
}

// ---------------------------------------------------
// Debug window
var debug=null;
var debugready=null;
function openDebug()
{
	debug = showModelessDialog("debug.html",window,"status:false;dialogWidth:400px;dialogHeight:400px");
	//while(!debug.document.ready)
	//{
	//	window.status=debug.document.ready;
	//}
	debugready=true;
}

function trace(msg)
{
	if(!debugready)
	{
		setTimeout("trace('"+msg+"');",100);
		return;
	}

	debug.document.body.innerHTML += "<br/>"+msg+"<br/>";
}

//--------------------------------------------------------------------------------------
// Old

	function ccInit()
	{
		// Force reset on any forms
		for(var i=0; i<document.forms.length; i++)
			document.forms[i].reset();
	}

	//-----------------------------------------------------------------------------
	// Browser sniffer

	function browsersniff()
	{
		// Get the version info
		var agt = navigator.userAgent.toLowerCase();
		var ver = parseInt(navigator.appVersion);
		var is_nav  = (agt.indexOf('mozilla')!=-1);
		var is_nav6up = (is_nav && (ver >= 5));
		var is_ie     = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
		var is_ie3    = (is_ie && (ver < 4));
		var is_ie4    = (is_ie && (ver == 4) && (agt.indexOf("msie 4")!=-1) );
		var is_ie5up  = (is_ie && !is_ie3 && !is_ie4);

		// Only two just now
		if( is_ie5up ) { return 'IE5'; } else if ( is_nav6up ) { return 'NS6'; }
	}

	//-----------------------------------------------------------------------------
	// The following code will run on document load, and set up the correct version
	// of the code for the current browser.

		ccCurrentBrowser = browsersniff();

		// Select the correct prototype
		if(ccCurrentBrowser=="IE5")
		{
			// IE wrapper prototype :-
			ccElement.prototype =
			{
				localGetElementById: function ( objId ) { if( document.all ) { return document.all[objId]; } else { return document.getElementById(objId); } },

				setLeft: function ( xPos ) { this.theObject.style.left = xPos+"px"; },

				setTop: function ( yPos ) { this.theObject.style.top = yPos+"px"; },

				getAbsTop: function ( )
				{
					// Should use offsettop + clienttop
					var yPos = this.theObject.offsetTop;
					parentEl = this.theObject.offsetParent;

					if(sMode=='mcs')
					{
						while (parentEl != null)
						{
							yPos += parentEl.offsetTop;
							parentEl  = parentEl.offsetParent;
						}
					} else {
						while (parentEl != null && parentEl.id != "contentarea")
						{
							yPos += parentEl.offsetTop;
							parentEl  = parentEl.offsetParent;
						}
					}

					return yPos;
				},

				getAbsLeft: function ( )
				{
					var xPos = this.theObject.offsetLeft;
					parentEl = this.theObject.offsetParent;


					if(sMode=='mcs')
					{
						while (parentEl != null)
						{
							xPos += parentEl.offsetLeft;
							parentEl  = parentEl.offsetParent;
						}
					} else {
						while (parentEl != null  && parentEl.id != "contentarea")
						{
							xPos += parentEl.offsetLeft;
							parentEl  = parentEl.offsetParent;
						}
					}

					return xPos;
				},

				getWidth: function() { return this.theObject.offsetWidth; },

				setPosition: function ( xPos, yPos )
				{
					this.theObject.style.posLeft = xPos;
					this.theObject.style.posTop  = yPos;
				},

				switchs: function ()
				{
					if(this.theObject.style.display=="none")
					{
						this.theObject.style.display = "block";
					} else {
						this.theObject.style.display = "none";
					}
				},

				display: function ( which )
				{
					if( which!="" )
					{
						this.theObject.style.display = which;
					} else {
						return this.theObject.style.display;
					}
				},

				show: function () { this.theObject.style.visibility="visible"; },

				hide: function () { this.theObject.style.visibility="hidden"; },

				getTop: function ( ) { return this.getAbsTop(); },

				isSelected: function() { return this.theObject.checked;	},

				setCorrect: function() { this.theObject.src = imgCorrect; },

				setIncorrect: function() { this.theObject.src = imgIncorrect; },

				cssName: function() { return this.theObject.className; }

			};


			// Global access object prototype
			ccCBA.prototype =
			{
				getElementById: function ( objId ) { if( document.all ) { return document.all[objId]; } else { return document.getElementById(objId); } },

				referenceLeft: function() { var reference = new ccElement( 'ccCBAreference' ); return reference.getAbsLeft(); },

				referenceRight: function(){ var reference = new ccElement('ccCBAreference'); return reference.getAbsLeft() + reference.theObject.clientWidth; },

				getTargetId: function ( event ) {	return window.event.srcElement.id; }
			};

			// Preload QImages
			var imgIncorrect = "/shared/embed/layout/incorrect.gif"; var imgIncorrectPre = new Image(); imgIncorrectPre.src = imgIncorrect;
			var imgCorrect = "/shared/embed/layout/correct.gif"; var imgCorrectPre = new Image();   imgCorrectPre.src = imgCorrect;

			var imgup  = new Image();  imgup.src = "/shared/embed/layout/btndwn.gif";
			var imgdwn = new Image(); imgdwn.src = "/shared/embed/layout/btnup.gif";

		} else if( ccCurrentBrowser=='NS6'){

			// MZ wrapper prototype :-
			ccElement.prototype =
			{
				localGetElementById: function ( objId ) { return document.getElementById( objId ); },

				setLeft: function ( xPos ) { this.theObject.left = xPos; },

				setTop: function ( yPos ) { this.theObject.top = yPos; },

				getTop: function ( ) { return parseInt(this.theObject.y); },

				getAbsTop: function ( )
				{
					var yPos = this.theObject.offsetTop;
					parentEl = this.theObject.offsetParent;
					while (parentEl != null)
					{
  							yPos += parentEl.offsetTop;
  						parentEl  = parentEl.offsetParent;
  					}
					return yPos;
				},

				getAbsLeft: function ( )
				{
					var xPos = this.theObject.offsetLeft;
					parentEl = this.theObject.offsetParent;
					while (parentEl != null)
					{
  							xPos += parentEl.offsetLeft;
  						parentEl  = parentEl.offsetParent;
  					}
					return xPos;
				},

				getWidth: function() { return this.theObject.offsetWidth; },

				setPosition: function ( xPos, yPos )
				{
					this.theObject.style.left = xPos+"px";
					this.theObject.style.top  = yPos+"px";
				},

				switchs: function ()
				{
					if(this.theObject.style.display=="none")
					{
						this.theObject.style.display = "block";
					} else {
						this.theObject.style.display = "none";
					}
				},

				display: function ( which )
				{
					if( which!="" )
					{
						this.theObject.style.display = which;
					} else {
						return this.theObject.style.display;
					}
				},

				show: function () { this.theObject.style.visibility="visible"; },

				hide: function () { this.theObject.style.visibility="hidden"; },

				isSelected: function() { return this.theObject.checked; },

				setCorrect: function() { this.theObject.src = imgCorrect; },

				setIncorrect: function() { this.theObject.src = imgIncorrect; },

				cssName: function() { return this.theObject.getAttribute("class"); }

			};

			// Global access object prototype
			ccCBA.prototype =
			{
				getElementById: function ( objId ) { return document.getElementById( objId ); },

				referenceLeft: function() {	var reference = new ccElement( 'ccCBAreference' ); return reference.getAbsLeft(); },

				referenceRight: function() { var reference = new ccElement('ccCBAreference'); return reference.getAbsLeft() + 590; },

				getTargetId: function ( event ) { return (event.target.nodeType == 3) ? event.target.parentNode.id : event.target.id; }
			};

			// Preload QImages
			var imgIncorrect = "/shared/embed/layout/incorrect.png"; var imgIncorrectPre = new Image(); imgIncorrectPre.src = imgIncorrect;
			var imgCorrect = "/shared/embed/layout/correct.png"; var imgCorrectPre = new Image();   imgCorrectPre.src = imgCorrect;

			var imgup  = new Image();  imgup.src = "/shared/embed/layout/btndwn.png";
			var imgdwn = new Image(); imgdwn.src = "/shared/embed/layout/btnup.png";

		} else {
			alert("This courseware is designed for IE5+/Netscape 6+. \nSome functionality may not be present in other browsers.");
		}

	//-------------------------------------------------------------------------
	// Constructors

		// Constructor for element wrapper
		function ccElement( objOrId )
		{
			if( (typeof objOrId)=="string" )
			{
				this.theObject = this.localGetElementById( objOrId );
			} else {
				this.theObject = objOrId;
			}
		}

		// Constructor for object providing global cross browser functions
		function ccCBA()
		{
		}

	//-----------------------------------------------------------------------------
	// Instantiate the cross browser object

		var CBA=null;
		CBA = new ccCBA();


	//-----------------------------------------------------------------------------
	// Q&A

		// Check multiple choice answers
		function check( qtype, qid, cid, range )
		{
			var i, ansimg, temp;
			var index=-1;

			// First hide all the answers if more than one
			if(range>1)
				hideAll( qid, range );

			// Find the input the user has selected
			for(var i=1; i<=range; i++)
			{
				temp = CBA.getElementById( qid+"a"+i );
				if( temp.checked )
				{
					index=i;
					break;
				}
			}

			// Check the user actually entered an answer
			if(index==-1)
			{
				alert("Please select an answer first.");
				return;
			}

			// Set the indicator
			ansimg = new ccElement( qid+"a"+index+"i" );

			if( (qid+"a"+index)==cid )
			{
				// Set the correct icon
				ansimg.setCorrect();
			} else {
				// Set the incorrect icon
				ansimg.setIncorrect();
			}
			ansimg.show();

		}

		// Check multiple choice answers
		function checkMR( qtype, qid, cid, range )
		{
			var i, ansimg, temp;

			var correct = new Array();
				correct = cid.split(";");
				correct = myunshift( correct, "dummy" ); //Question elements numbered from one, arrays from 0, makes the same.

			// First hide all the answers if more than one
			if(range>1)
				hideAll( qid, range );

			// For each answer, if the user has selected check if it is right
			for(var i=1; i<=range; i++)
			{
				// Get the indicator
				ansimg = new ccElement( qid+"a"+i+"i" );
				temp = CBA.getElementById( qid+"a"+i );
				if( temp.checked )
				{
					// The user has selected this answer, so see if it is correct
					if(correct[i]=="1")
					{
						// Set the correct icon
						ansimg.setCorrect();
					} else {
						// Set the incorrect icon
						ansimg.setIncorrect();
					}
				} else {
					// The user has selected this answer, so see if it is correct
					if(correct[i]=="0")
					{
						// Set the correct icon
						ansimg.setCorrect();
					} else {
						// Set the incorrect icon
						ansimg.setIncorrect();
					}
				}
					ansimg.show();
			}
		}

		// Check filltheblanks answers
		function checkFill( qtype, qid, cid, range )
		{
			var i, ansimg;

			var correct = new Array();
				correct = cid.split(";");
				correct = myunshift( correct, "dummy" ); //Question elements numbered from one, arrays from 0, makes the same.

			// First hide all the answers if more than one
			if(range>1)
				hideAll( qid, range );

			// For each sub answer, check against corrects
			for(var i=1; i<correct.length; i++)
			{
				ansimg = new ccElement( qid+"a"+i+"i" );

				// Is one of the sub answers correct
				temp = CBA.getElementById( qid+"a"+i );
				useranswer = temp.value;
				subanswers = correct[i].split('?');

				for( j=0; j<subanswers.length; j++ )
				{
					if( useranswer==subanswers[j] )
					{
						isCorrect=true;
						break;
					}
					isCorrect=false;
				}

				if( isCorrect )
				{
					// Set the correct icon
					ansimg.setCorrect();
				} else {
					// Set the incorrect icon
					ansimg.setIncorrect();
				}
				ansimg.show();
			}
		}

		// Check select the blanks and mathcing pairs answers
		function checkMatch( qtype, qid, cid, range )
		{
			var index=-1;

			var correct = new Array();
				correct = cid.split(";");
				correct = myunshift( correct, "ddummy" ); //Question elements numbered from one, arrays from 0, makes the same.

			// First hide all the answers
			hideAll( qid, range );

			// For each sub answer, check against corrects
			for(var i=1; i<=range; i++)
			{
				ansimg = new ccElement( qid+"a"+i+"i" );
				temp = CBA.getElementById( qid+"a"+i );
				if( temp.selectedIndex == parseInt(correct[i]) )
				{
					// Set the correct icon
					ansimg.setCorrect();
				} else {
					// Set the incorrect icon
					ansimg.setIncorrect();
				}
				ansimg.show();
			}
		}


		// Hide a list of question images
		function hideAll( qid, range )
		{
			var i,temp;
			for( i=1; i<=range; i++ )
			{
				temp = new ccElement( qid+"a"+i+"i" );  // +"cont" for netscape
				temp.hide();
			}
		}

		function myunshift( a, e )
		{
			var tmp = new Array( a.length + 1 );
			tmp[0] = e;
			for( var i=0; i<a.length; i++ )
				tmp[i+1] = a[i];
			return tmp;
		}

	// ------------------------------------------------------------------------
	// Show and Hide coach elements

		function showCoach( evt, coachId )
		{

			ansimg = new ccElement( CBA.getTargetId( evt ) );

			// Only show tip if question is in answered state or we are working with a glossary term
			if( (ansimg.theObject.style.visibility == "visible") || (ansimg.cssName()=="glossterm") )
			{
				// Choose specific or default comments
				if( coachId=="ccDefault" )
				{
					if( ansimg.theObject.src.indexOf(imgCorrect)!=-1 )
					{
						coachId = "ccDefaultCorrect";
					} else {
						coachId = "ccDefaultIncorrect";
					}
				}

				// Get reference to the popup object
				coach = new ccElement( coachId );
				coachWidth = coach.getWidth();

				// Get bounds of content area
				refL = CBA.referenceLeft();
				refR = CBA.referenceRight();

				// Get the target position
				yPos = ansimg.getAbsTop();
				xPos = ansimg.getAbsLeft();

				// If there isnt space for the popup, shift it left
				if( (refR - xPos) < coachWidth )
					xPos = refR-coachWidth;

				// Update the popup
				coach.setPosition( xPos, yPos+20 );
				coach.show();

			}

		}

		function hideCoach( coachId )
		{
			// Choose specific or default comments
			if( coachId=="ccDefault" )
			{
				coach = new ccElement( "ccDefaultCorrect" ); coach.hide();
				coach = new ccElement( "ccDefaultIncorrect" ); coach.hide();
			} else {
				coach = new ccElement( coachId ); coach.hide();
			}
		}

	// ------------------------------------------------------------------------
	// Worked Examples

		function switchstep( targetIDList )
		{
			// Parse the list into an array of ID's
			var IDList = targetIDList.split(';');

			// For each following step, either show first or hide all
			var first = new ccElement( IDList[1] );

			// If first shown
			if( first.display("") == "block" )
			{
				// Hide all in list
				for(i=1; i<IDList.length; i++)
				{
					temp = new ccElement( IDList[i] );
					temp.display("none");
				}
				// Change the buttons
				for(i=0; i<IDList.length-1; i++)
				{
					var btn = new ccElement( "btn"+IDList[i] );
					btn.theObject.src = imgup.src;
				}
			} else {
				// Show the step
				first.display("block");
				var btn = new ccElement("btn"+IDList[0]);
				btn.theObject.src = imgdwn.src;
			}

		}

	//-----------------------------------------------------------------------------
	// Other functionality

		function switchQuickLinks()
		{
			var qlinkdiv;
			qlinkdiv = new ccElement( 'ccQuicklinks' );

			if( qlinkdiv.display("") == "block" )
			{
				qlinkdiv.display("none");
			} else {
				qlinkdiv.display("block");
			}

		}

		function flashJump( which, where )
		{
			var movie = CBA.getElementById( which );
			    movie.GotoFrame( where );
		}

		function simOpen( URL, title )
		{
			document.crocopen( URL, title );
		}

//-----------------------------------------------------------------------------
// Add some functionality that may be missing [from IE]
if (Array.prototype.push && ([0].push(true)==true))
        Array.prototype.push = null;

if(!Array.prototype.push)
{
    function array_push()
    {
        for(i=0;i<arguments.length;i++)
        {
            this[this.length] = arguments[i];
        }
        return this.length;
    }
    Array.prototype.push = array_push;
}

if(!Array.prototype.pop)
{
    function array_pop()
    {
        lastElement = this[this.length-1];
        this.length = Math.max(this.length-1,0);
        return lastElement;
    }
    Array.prototype.pop = array_pop;
}

