//	$Id: common.js,v 1.121 2008/09/23 14:59:14 kondikov Exp $
var scriptpath = "script/";
var imagepath = "images/";
var statusrefreshperiod = 200;
var initialised = false;
var panels = new objectlist();
var communication = new btcommunication();
var media = new btmedia();
var slides = new btslidelist();
var timeline = new bttimeline();
var tabs = new bttabs();
timeline.setmediaobject(media);
var isIE = document.all;
var isNN =! document.all && document.getElementById;
var isN4 = document.layers;
var xmllastupdate = 0;
if (!browserdata) var browserdata = false;
var xmlrequestmaximum = 5;
var xmlrequestregister = Array();
var debugon = false;
window.onerror = null;

function writedebug(text) {
	if (!debugon) return;
	var debugbox = document.getElementById('debugbox');
	if (!debugbox) {
		var debugbox = document.createElement('div');
		debugbox.id = 'debugbox';
		debugbox.style.display = (debugon)?'block':'none';
		document.body.appendChild(debugbox);
	}
	if (debugbox) debugbox.innerHTML = debugbox.innerHTML + text + "<br>";
}

function cleardebug() {
	var debugbox = document.getElementById('debugbox');
	if (debugbox) debugbox.innerHTML = "";
}

function toggledebug() {
	debugon = !debugon;
	var debugbox = document.getElementById('debugbox');
	if (!debugbox) writedebug('Debug Started');
	if (debugbox) debugbox.style.display = (debugon)?'block':'none';
}

function xmlrequestgetslot() {
	var length = xmlrequestregister.length;
	for (var i = 0; i < length; i++) {
		var requestitem = xmlrequestregister[i];
		if (requestitem==null || requestitem.req.readyState==3) return i;
	}
	if (length < xmlrequestmaximum) return length;
	return null;
}

function doxmlrequest(url,returnfunction) {
	var slotindex = xmlrequestgetslot();
	if (slotindex==null) return false;
	var obj = new xmlrequest(slotindex,url,returnfunction);
	xmlrequestregister[slotindex] = obj;
	obj.send();
	return true;
}

function xmlresponsehandler(slotindex) {
	var obj = xmlrequestregister[slotindex];
	if (obj) {
		if (obj.processresponse()) {
			writedebug(slotindex + " - Cleared Request");
			xmlrequestregister[slotindex]=null;
		}
	}
}

function xmlrequesttimeout(slotindex) {
	if (xmlrequestregister[slotindex]) {
		writedebug(slotindex + " - Request timeout");
		xmlrequestregister[slotindex] = null;
	}
}

function xmlrequest(registerindex, submiturl, returnfunction) {
	this.registerindex = registerindex;
	this.submiturl = submiturl;
	this.returnfunction = returnfunction;
	this.req = null;
	this.timeout = 5000;
	this.timeouthandle = null;

	this.createrequest = function() {
		if (window.XMLHttpRequest) {
			try {
				this.req = new XMLHttpRequest();
			} catch(e) {
				this.req = null;
			}
		} else if (window.ActiveXObject) {
			try {
				this.req = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				try {
					this.req = new ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {
					this.req = null;
				}
			}
		}
	}

	this.send = function() {
		writedebug(this.registerindex + " - Registered request (" + this.submiturl + ")");
		this.createrequest();
		if (!this.req) return false;
		if (this.returnfunction) {
			this.req.onreadystatechange = new Function("xmlresponsehandler(" + this.registerindex + ")");
		}
		this.req.open("GET", this.submiturl, true);
		if (window.XMLHttpRequest) {
			this.req.send(null);
		} else {
			this.req.send();
		}
		this.timeouthandle = window.setTimeout('xmlrequesttimeout(' + this.registerindex + ')',this.timeout);
	}


	this.processresponse = function() {
		writedebug(this.registerindex + " - Processing Response");
		if (this.req.readyState == 4) { // Complete
			if (this.req.status == 200) { // OK response
				writedebug(this.registerindex + " - Response Received OK ");
				var response=null;
				//debugger
				if(this.req.responseXML){
					response	= this.req.responseXML.documentElement;
				} else {
					response	= this.req.responseText;
				}
				if (typeof this.returnfunction=='function') {
					this.returnfunction(response);
					writedebug(this.registerindex + " - Calling Return Function");
				} else {
					var statuscode = this.req.status;
					writedebug(this.returnfunction);
					response = this.req.responseText; //for debug
					try {
						eval(this.returnfunction);
					} catch(e) {
						writedebug("Failed return function - " + this.returnfunction);
						writedebug("Status code : " + statuscode);
						writedebug("Response : " + response);
					}
				}
			} else {
				writedebug(this.registerindex + " - Problem :" + this.req.statusText + "(" + this.req.status + ")");
				window.clearTimeout(this.timeouthandle);
			}
			return true;
		}
		writedebug(this.registerindex + " - Ready State : " + this.req.readyState);
		return false;
	}
}


function objectlist() {
	this.objects = Array();

	this.register = function(object) {
		var uid = this.objects.length;
		this.objects[this.objects.length]=object;
		return uid;
	}

	this.getobject = function(objclass,alias) {
		for (var i = 0; i < this.objects.length; i++) {
			var obj = this.objects[i];
			if ((obj.className==objclass) && (obj.alias==alias)) return obj;
		}
		return false;
	}

	this.getbyuid = function(uid) {
		var obj = this.objects[uid];
		if (obj) return obj;
		return false;
	}

	this.call = function(uid,call) {
		var obj = this.objects[uid];
		if (obj) {
			eval("obj." + call);
		} else {
			alert("Attempted call to unregistered Object");
		}
	}
}

function callpanel(uid,call) {
	if (panels) panels.call(uid,call);
}

function getAbsX(elt) {
	return (elt.x) ? elt.x : getAbsPos(elt,"Left");
}

function getAbsY(elt) {
	return (elt.y) ? elt.y : getAbsPos(elt,"Top");
}

function getAbsPos(elt,which) {
	iPos = 0;
	while (elt != null) {
		iPos += elt["offset" + which];
		elt = elt.offsetParent;
	}
	return iPos;
}

function imagelist() {
	this.imagearray = Array();

	this.addimage = function(alias,filename) {
		var img = new msimage(imagepath + filename);
		argv = arguments;
		argc = argv.length;
		for (var i = 2; i < argc; i++) {
			img.addstate(argv[i]);
		}
		this.imagearray[alias] = img;
	}

	this.getimage = function(alias,state) {
		if (!this.imagearray[alias]) return false;
		return this.imagearray[alias].getimage(state);
	}

	this.replaceimage = function(id,state) {
		var oldimage = document.getElementById(id);
		var newimage = this.getimage(id,state);
		if (oldimage && newimage) oldimage.src = newimage.src;
	}
}

function msimage(filename) {
	this.filename = filename;
	this.state = Array();

	this.addstate = function(statename) {
		var img = new Image();
		img.src = filename.replace("?",statename);
		this.state[statename] = img;
	}

	this.getimage = function(statename) {
		//window.status = this.state[statename]?"found":"no";
		return this.state[statename];
	}
}

function btuser() {
	this.id = null;
	this.email = null;
	this.firstname = null;
	this.lastname = null;
}

function btcommunication() {
	this.id = "unset";
	this.title = "Communication";
	this.presenter = "";
	this.description = "";
	this.companyname = "";
	this.status = "";
	this.playerid = "unset"
	this.playername = "unset";
	this.viewingid = "";
	this.updateurl = null;
	this.polltimeout = null;
	this.dialinnumber = "";
	this.customhtml = false;
	this.uid = panels.register(this);

	this.actioncall = function(action) {
		return "callpanel(" + this.uid + ",'" + action + "')";
	}

	this.drawinfopanel = function() {
		var out = "<div id=\"infobox\">";
		if (this.customhtml!=false) {
			out += this.customhtml;
		} else {
			if (this.dialinnumber!="") out += "<div class=\"dialinnumber\">" + this.dialinnumber + "</div>";
			out += "<div class=\"title\">" + this.title + "</div>";
			if (this.presentername!="") out += "<div class=\"presentername\">" + this.presenter + "</div>";
			if (this.companyname!="") out += "<div class=\"companyname\">" + this.companyname + "</div>";
			if (this.description!="") out += "<div class=\"description\">" + this.description + "</div>";
		}
		out += "</div>";
		document.write(out);
	}

	this.setcustomhtml = function(html) {
		this.customhtml = html;
	}

	this.setupdateurl = function(url) {
		this.updateurl = url;
	}

	this.stoppolling = function() {
		if (this.polltimeout) cleartimeout(this.polltimeout);
	}

	this.pollforupdates = function() {
		if (!this.updateurl) return;
		doxmlrequest(this.updateurl + '?' + Math.random(),processplayerstatus);
		this.polltimeout = setTimeout(this.actioncall('pollforupdates()'),5000);
	}
}

function processplayerstatus(update) {
	writedebug("Processing Player Update");
	//if (!update) return;
	var result = update.getElementsByTagName('update')[0];
	var currentupdate = result.getAttribute('lastupdate');
	if (xmllastupdate < currentupdate) {
		xmllastupdate = currentupdate;
		writedebug("Update Id :" + currentupdate);
		if (media && (media.live && media.mediatype=='STREAMLESS')) {
			if (result.getElementsByTagName('currentslide') && result.getElementsByTagName('currentslide')[0]) {
				var currentslide = result.getElementsByTagName('currentslide')[0].firstChild.nodeValue;
				if (currentslide && slides) slides.show(currentslide);
			}
			if (result.getElementsByTagName('redirect') && result.getElementsByTagName('redirect')[0]) {
				var redirect = result.getElementsByTagName('redirect')[0].firstChild.nodeValue;
				if (redirect) pageload(redirect);
			}
		}
		if (!result.getElementsByTagName('votes')) return;
		if (!result.getElementsByTagName('votes')[0]) return;
		var votes = result.getElementsByTagName('votes')[0].getElementsByTagName('vote');
		if (votes) {
			for (var voteno = votes.length-1; voteno >= 0; voteno--) {
				var resultsarray = Array();
				var vote = votes[voteno];
				var votealias = vote.getAttribute('alias');
				var votestatus = vote.getAttribute('status');
				writedebug("Vote update :" + votealias);
				var voteresults = vote.getElementsByTagName('results')[0].getElementsByTagName('result');
				for (var resultno = 0; resultno < voteresults.length; resultno++) {
					var voteresult = voteresults[resultno].firstChild.nodeValue;
					resultsarray[resultsarray.length] = voteresult;
					writedebug("Result :" + voteresult);
				}
				votesupdate(votealias,votestatus,resultsarray);
			}
		}
	}
}

function votesupdate(votealias,votestatus,resultsarray) {
	var voteobject = panels.getobject('btvote',votealias);
	if (voteobject) {
		voteobject.updateresults(resultsarray);
		voteobject.setstatus(votestatus=='active');
	}
}

function btmedia() {
	this.mediatype = "WIMP";
	this.streamurl = "";
	this.width = 320;
	this.height = 240;
	this.duration = false;
	this.playerobject = null;
	this.videowindow = true;
	this.live = false;
	this.statustext = Array("0","Stopped","Paused","Playing","Fast Forward","Rewind","Buffering","Waiting...","Stopped","Processing","Stopped","Seeking");
	this.totaltimeplayed = 0;
	this.currentplaystate = false;
	this.uid = panels.register(this);
	this.recordtimeurl = "../mod/update_time.php";
	this.timerobj = window.setInterval("callpanel(" + this.uid + ",'updatetime()')", statusrefreshperiod);
	this.callid = false;


	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.getwidth = function() {
		return this.width;
	}

	this.draw = function() {
		if (!this.videowindow) {
			this.width = 0;
			this.height = 0;
		}
		switch (this.mediatype) {

			case "WIMP" :
				this.playerobject = new btwimpplayer(this.width,this.height);
				this.playerobject.setstreamurl(this.streamurl);
				this.playerobject.showcontrols = false;
				this.playerobject.live = this.live;
				this.playerobject.draw();
				writecontrol(this);
			break;

			case "REAL" :
				this.playerobject = new btrealplayer(this.width,this.height);
				this.playerobject.setstreamurl(this.streamurl);
				this.playerobject.showcontrols = false;
				this.playerobject.live = this.live;
				this.playerobject.draw();
				writecontrol(this);
			break;

			case "FLASH" :
				this.playerobject = new btflashplayer(this.width,this.height);
				this.playerobject.setstreamurl(this.streamurl);
				this.playerobject.showcontrols = false;
				this.playerobject.live = this.live;
				this.playerobject.draw();
				writecontrol(this);
			break;

			case "QUICKTIME" :
				this.playerobject = new btqtplayer(this.width,this.height);
				this.playerobject.setstreamurl(this.streamurl);
				this.playerobject.showcontrols = false;
				this.playerobject.live = this.live;
				this.playerobject.draw();
				writecontrol(this);
			break;

			case "STREAMLESS" :
				this.playerobject = new btstreamlessplayer(this.width,this.height);
				this.playerobject.setstreamurl(this.streamurl);
				this.playerobject.showcontrols = false;
				this.playerobject.live = this.live;
				this.playerobject.setDuration(this.duration);
				this.playerobject.setcallid(this.callid);
				this.playerobject.draw();
				writecontrol(this);
			break;

			default :
				alert("Player type " + playertype + " not Supported");
			break;
		}
	}

	this.checkcapability = function(name) {
		return (this.playerobject) ? this.playerobject.checkcapability(name) : false;
	}

	this.setcurrentposition = function(seconds) {
		if (this.playerobject) this.playerobject.setCurrentPosition(seconds);
	}

	this.setduration = function(seconds) {
		this.duration = seconds;
	}

	this.jumpandplay = function(seconds) {
		this.setcurrentposition(seconds);
		this.play();
	}

	this.fastreverse = function() {
		if (this.playerobject) this.playerobject.fastreverse();
	}

	this.fastforward = function() {
		if (this.playerobject) this.playerobject.fastforward();
	}

	this.toggleplaypause = function() {
		if (this.playerobject) {
			if (this.playerobject.getPlayState()==3) {
				this.playerobject.pause();
			} else {
				this.playerobject.play();
			}
		}
	}

	this.setmute = function(state) {
		if (this.playerobject) this.playerobject.setMute((state==true));
	}

	this.togglemute = function() {
		if (this.playerobject) this.playerobject.setMute(!this.playerobject.getMute());
	}

	this.getmutestatus = function() {
		return (this.playerobject) ? this.playerobject.getMute() : false;
	}

	this.play = function() {
		return (this.playerobject)?this.playerobject.play():false;
	}

	this.pause = function() {
		return (this.playerobject)?this.playerobject.pause():false;
	}

	this.stop = function() {
		return (this.playerobject)?this.playerobject.stop():false;
	}

	this.getplaystate = function() {
		window.status = (this.playerobject) ? this.playerobject.getPlayState() : 'xxxx';
		return (this.playerobject) ? this.playerobject.getPlayState() : false;
	}

	this.isplaying = function() {
		return (this.getplaystate()==3);
	}

	this.getcurrentstatus = function() {
		var playstate = this.playerobject.getPlayState();
		if (isNaN(playstate)) return "";
		return statustext[playstate]?statustext[playstate]:"";
	}

	this.getcurrentposition = function() {
		return (this.playerobject)?this.playerobject.getCurrentPosition():0;
	}

	this.setcurrentposition = function(time) {
		return (this.playerobject)?this.playerobject.setCurrentPosition(time):false;
	}

	this.getduration = function(time) {
		return (this.playerobject)?this.playerobject.getDuration():false;
	}

	this.getvolume = function() {
		return (this.playerobject)?this.playerobject.getVolume():false;
	}

	this.setvolume = function(volume) {
		return (this.playerobject)?this.playerobject.setVolume(volume):false;
	}

	this.getsecondsplayedbyfraction = function(frac) {
		return Math.round(this.getduration()*frac);
	}

	this.updatetime = function() {
		var lastplaystate = this.currentplaystate;

		if ((this.currentplaystate = this.getplaystate())!=lastplaystate) {
			if (window.updatestatusobjects) updatestatusobjects(this.currentplaystate);
		}
		var currentpos = this.getcurrentposition();

		if (window.updatetimeobjects) updatetimeobjects(currentpos);

		window.status = (this.isplaying())?'PLAYYYYYING':'NOT';
		if (this.isplaying()) {
			this.totaltimeplayed += (statusrefreshperiod/1000);
			timeline.processevents(currentpos);
		}
	}

	this.recordplayedtime = function() {
		if (this.totaltimeplayed>0) {
			var totaltimeplayed = Math.floor(this.totaltimeplayed);
			var url = this.recordtimeurl + "?viewID=" + communication.viewingid + "&t=" + totaltimeplayed + "&" + Math.random();
			var imgobj = new Image;
			imgobj.src = url;
			writedebug("Set time played :" + totaltimeplayed);
		}
	}
}

function drawimage(imagename,width,height) {
	return "<img width=\"" + width + "\" height=\"" + height + "\" src=\"" + imagepath + imagename + "\"/>";
}

function drawimagebutton(id,text,onclickevent) {
	return "<div id=\"" + id + "\" class=\"imagebutton\" onclick=\"" + onclickevent + ";\"><div class=\"l\"></div><div class=\"m\">" + text + "</div><div class=\"r\"></div></div>";
}

function drawroundedframe(id,text) {
	var onclickevent = (arguments.length>=3)?"onclick=\"" + arguments[2] + ";\"":"";
	var style = (arguments.length==3)?"style=\"cursor:pointer;\"":"";
	var cssclass = (arguments.length==4)?"roundedframe"+arguments[5]:"roundedframe";
	var out = "<div class=\""+cssclass+"\" " + onclickevent + " " + style + ">";
	out += "<table class=\"frametable\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
	out += "<tr><td height=\"4\" width=\"4\" class=\"tl\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"tm\" height=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td width=\"4\" height=\"4\" class=\"tr\">" + drawimage('spacer.gif',1,1) + "</td></tr>";
	out += "<tr><td class=\"sl\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"mid\"><div class=\"main\" width=\"100%\">" + text + "</div></td><td class=\"sr\">" + drawimage('spacer.gif',4,4) + "</td></tr>";
	out += "<tr height=\"4\"><td class=\"bl\" height=\"4\" width=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"bm\" height=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td width=\"4\" height=\"4\" class=\"br\">" + drawimage('spacer.gif',4,4) + "</td></tr>";
	out += "</table>";
	out += "</div>";
	return out;
}

function drawroundedframeDark(id,text) {
	var onclickevent = (arguments.length>=3)?"onclick=\"" + arguments[2] + ";\"":"";
	var style = (arguments.length==3)?"style=\"cursor:pointer;\"":"";
	var cssclass = (arguments.length==4)?"roundedframeDark"+arguments[5]:"roundedframeDark";
	var out = "<div class=\""+cssclass+"\" " + onclickevent + " " + style + " id='downloadCert'>";
	out += "<table class=\"frametableDark\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
	out += "<tr><td height=\"4\" width=\"4\" class=\"tl\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"tm\" height=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td width=\"4\" height=\"4\" class=\"tr\">" + drawimage('spacer.gif',1,1) + "</td></tr>";
	out += "<tr><td class=\"sl\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"mid\"><div class=\"main\" width=\"100%\">" + text + "</div></td><td class=\"sr\">" + drawimage('spacer.gif',4,4) + "</td></tr>";
	out += "<tr height=\"4\"><td class=\"bl\" height=\"4\" width=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td class=\"bm\" height=\"4\">" + drawimage('spacer.gif',4,4) + "</td><td width=\"4\" height=\"4\" class=\"br\">" + drawimage('spacer.gif',4,4) + "</td></tr>";
	out += "</table>";
	out += "</div>";
	return out;
}

function bttimelineevent(time,action,params) {
	this.time = time;
	this.action = action;
	this.params = params;
}

function bttimeline() {
	this.eventlist = new Array();
	this.lasteventidx = null;
	this.mediaobject = null;

	this.addevent = function(time,action,params) {
		this.eventlist[this.eventlist.length] = new bttimelineevent(time,action,params);
	}

	this.debug = function() {
	}

	this.processevents = function(currenttime) {
		for (var idx=(this.eventlist.length - 1); idx>=0; idx--) {
			//window.status = idx + ":" + this.eventlist[idx].time + ":" + currenttime;
			if (currenttime>=this.eventlist[idx].time) {
				this.executeevent(idx);
				break;
			}
		}
		return false;
	}

	this.executeevent = function(idx) {
		if (this.lasteventidx !=idx) {
			this.lasteventidx = idx;
			eval(this.eventlist[idx].action);
		}
	}

	this.jumptoindex = function(idx) {
		if (this.eventlist[idx]) {
			if (this.mediaobject) {
				this.mediaobject.setcurrentposition(this.eventlist[idx].time);
			}
		}
	}

	this.setmediaobject = function(object) {
		this.mediaobject = object;
	}
}


function bttab(alias,title,contentobj,parentobj) {
	this.alias = alias;
	this.title = title;
	this.contentobject = contentobj;
	this.parentobject = parentobj;
	this.isactive = false;
	this.ishighlited = false;
	this.contentobject.parentobject = this;
	this.className = 'bttab';
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement('title');
		if (titleobj) titleobj.value = this.title;
	}

	this.drawtab = function() {
		document.write("<li id=\"" + this.getelementid('tab') + "\" onclick=\"callpanel(" + this.uid + ",'clickedtab()');\"><a href=\"#\">" + this.title + "</a></li>");
	}

	this.drawpanel = function() {
		document.write("<div class=\"" + this.contentobject.className + "\" style=\"display:" + (this.isactive?'block':'none') + ";\" id=\"" + this.getelementid('panel') + "\">");
		document.write(this.contentobject.render());
		document.write("</div>");
	}

	this.refreshpanel = function() {
		var newcontent = this.contentobject.refresh();
		if (newcontent) {
			var panelObj = this.getelement('panel');
			if (panelObj) panelObj.innerHTML = newcontent;
		}
	}

	this.clickedtab = function() {
		this.parentobject.clicktab(this);
	}

	this.active = function(on) {
		var tabObj = this.getelement('tab');
		if (tabObj) tabObj.className = (on)?"selected":"";
		this.displaypanel(on);
		this.isactive = on;
		this.ishighlited = false;
	}

	this.highlite = function(on) {
		if (this.isactive) return;
		var tabObj = this.getelement('tab');
		if (tabObj) tabObj.className = (on) ? "highlite" : "";
		this.ishighlighted = on;
	}

	this.refreshtab = function() {
		if (this.ishighlighted) {
			this.highlite(true);
		} else {
			this.active(this.isactive);
		}
	}

	this.displaypanel = function(show) {
		var panelObj = this.getelement('panel');
		if (panelObj) displayobject(panelObj,show);
	}

	this.contentchanged = function(highlite) {
		this.highlite(highlite);
		this.refreshpanel();
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}


function bttabs() {
	this.tablist = new Array();
	this.activetab = null;
	this.showtabs = true;
	this.className = 'bttabs';
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.addtab = function(alias,title,contentobj) {
		newtab = new bttab(alias,title,contentobj,this);
		if (this.activetab==null) {
			this.activetab = newtab;
			newtab.active(true);
		}
		this.tablist[this.tablist.length] = newtab;
	}

	this.clicktab = function(obj) {
		if (this.activetab == obj) return;
		this.activetab.active(false);
		this.activetab = obj;
		this.activetab.active(true);
	}

	this.highlite = function(alias,on) {
		var tab = this.findtab(alias);
		if (tab!=null) {
			tab.highlite(on);
		}
	}

	this.show = function(alias) {
		var tab = this.findtab(alias);
		if (tab!=null) {
			this.clicktab(tab);
		}
	}

	this.findtab = function(alias) {
		for (var idx = 0; idx < this.tablist.length; idx++) {
			if (this.tablist[idx].alias==alias) return this.tablist[idx];
		}
		return null;
	}

	this.findtabindex = function(tabobj) {
		for (var idx = 0; idx < this.tablist.length; idx++) {
			if (this.tablist[idx]==tabobj) return idx;
		}
		return null;
	}

	this.nexttab = function() {
		var currenttabidx = this.findtabindex(this.activetab);
		if (currenttabidx!=null) {
			currenttabidx++;
			if (currenttabidx>=this.tablist.length) currenttabidx = 0;
			this.clicktab(this.tablist[currenttabidx]);
		}
	}

	this.drawtabs = function() {
		document.write("<ul class=\"tabs\">");
		for (var idx = 0; idx < this.tablist.length; idx++) {
			tab = this.tablist[idx];
			tab.drawtab();
		}
		document.write("</ul>");
	}

	this.drawpanel = function() {
		document.write("<div class=\"tabbody\">");
		for (var idx = 0; idx < this.tablist.length; idx++) {
			tab = this.tablist[idx];
			tab.drawpanel();
		}
		document.write("</div>");
	}

	this.refreshtabs = function() {
		for (var idx = 0; idx < this.tablist.length; idx++) {
			tab = this.tablist[idx];
			tab.refreshtab();
		}
	}

	this.draw = function() {
		document.write("<div id=\"" + this.getelementid('tabpanel') + "\" class=\"tabpanel\">");
		if (this.showtabs) this.drawtabs();
		this.drawpanel();
		document.write("</div>");
		this.refreshtabs();
	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function btslide(alias,imagesrc,title,time) {
	this.alias = alias;
	this.title = title;
	this.imagesrc = imagesrc;
	this.image = null;
	this.index = null;
	this.className = "btslide";
	this.time = time;
	this.uid = panels.register(this);
	this.eventobj = (this.time!=null)?timeline.addevent(time,"slides.show('" + this.alias + "')"):null;

	this.preload = function() {
		if (!this.image) {
			this.image = new Image();
			this.image.src = imagesrc;
		}
		return true;
	}
}

function btslidelist() {
	this.title = "slides";
	this.slidelist = new Array();
	this.activeslide = null;
	this.showselector = true;
	this.slidepath = "";
	this.width = 640;
	this.height = 480;
	this.className = "btslidelist";
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.addslide = function(alias,imagesrc,title,time) {
		var newslide = new btslide(alias,this.slidepath + imagesrc,title,time);
		newslide.index = this.slidelist.length;
		this.slidelist[this.slidelist.length] = newslide;
		if (!this.activeslide) this.activeslide = newslide;
	}

	this.hasslides = function() {
		return (this.slidelist.length>0);
	}

	this.render = function() {
		var out	= "<img id=\"" + this.getelementid("slidebox") + "\" class=\"slidebox\" src=\"" + this.activeslide.imagesrc + "\" width=\"" + this.width + "\" height=\"" + this.height + "\">";
		if (this.hasslides()) {
			out += this.renderselector();
		}
		return out;
	}

	this.refresh = function() {
		this.updateslidebox();
		this.updateslideselect();
		return false;
	}

	this.selectorchanged = function() {
		var selector = this.getelement("slideselect");
		if (selector) {
			idx = selector.options[selector.selectedIndex].value;
			slides.showbyindex(idx);
			if (timeline) {
				var slide = slides.getslidebyindex(idx);
				if (slide.time!=null) {
					media.setcurrentposition(slide.time);
				}
			}
		}
	}

	this.renderselector = function() {
		if (media && media.live) return "";
		var out= "<div class=\"slidelistpanel\" id=\"" + this.getelementid('slidelist') + "\">";
		out += "<select id=\"" + this.getelementid("slideselect") + "\" class=\"slideselector\" onchange=\"callpanel(" + this.uid + ",'selectorchanged()');\">";
			for (var i = 0; i < this.slidelist.length; i++) {
			slide = this.slidelist[i];
			out += "<option value=\"" + i + "\" " + (i==0?"selected":"") + ">" + (i+1) + ". " + slide.title + "</option>";
		}
		out += "</select>";
		out += "</div>";
		return out;
	}

	this.findslide = function(alias) {
		for (var idx = 0; idx < this.slidelist.length; idx++) {
			if (this.slidelist[idx].alias==alias) return this.slidelist[idx];
		}
		return null;
	}

	this.getslidebyindex = function(idx) {
		if (idx>=0 && idx<=this.slidelist.length) return this.slidelist[idx];
		return false;
	}

	this.updateslidebox = function() {
		var slideboxobj = this.getelement("slidebox");
		if (slideboxobj) {
			slideboxobj.src = this.activeslide.imagesrc;
		}
	}

	this.updateslideselect = function() {
		var slideselectobj = this.getelement("slideselect");
		if (slideselectobj) {
			slideselectobj.selectedIndex = this.activeslide.index;
		}
	}

	this.showbyindex = function(index) {
		if (index >= 0 && index < this.slidelist.length + 1) {
			var newslide = this.slidelist[index];
			if ((newslide!=null) && (newslide!=this.activeslide)) {
				this.activeslide = newslide;
				this.contentchanged();
			}
		}
	}

	this.preload = function() {
		for (var idx = 0; idx < this.slidelist.length; idx++) {
			this.slidelist[idx].preload();
		}
	}

	this.show = function(alias) {
		var newslide = this.findslide(alias);
		if ((newslide!=null) && (newslide!=this.activeslide)) {
			this.activeslide = newslide;
			this.contentchanged();
		}
		return newslide;
	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function btfeedback(alias) {
	this.alias = alias;
	this.title = "Your Feedback";
	this.className = "btfeedback";
	this.introtext = "Please give your feedback and then click submit";
	this.emailtext = "Please enter your email address";
	this.ratingtext = "Rating";
	this.responsetext = "Thank you for your feedback";
	this.showrating = true;
	this.email = "";
	this.rating = 0;
	this.scorenames = Array("Unrated","Very Bad","Bad","Average","Good","Excellent");
	this.posturl = "../mod/post_feedback.php";
	this.useremail = "";
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.setintrotext = function(text) {
		this.introtext = text;
	}

	this.setresponsetext = function(text) {
		this.responsetext = text;
	}

	this.setshowrating = function(on) {
		this.showrating = on;
	}

	this.requestrating = function(on) {
		this.showrating = (on==true);
	}

	this.setratingtext = function(text) {
		this.ratingtext = text;
		if (rtobj = this.getelement("ratingtext")) {
			rtobj.innerHTML = this.ratingtext + " (" + this.scorenames[this.rating] + ")";
		}
	}

	this.setemailtext = function(text) {
		this.emailtext = text;
		if (rtobj = this.getelement("emailtext")) {
			rtobj.innerHTML = this.emailtext;
		}
	}

	this.setemail = function(text) {
		this.email = text;
		if (rtobj = this.getelement("email")) {
			rtobj.value = this.email;
		}
	}

	this.setrating = function(rating) {
		this.rating = rating;
		var ratingobj = this.getelement("rating");
		if (ratingobj) ratingobj.value = this.rating;
		if (this.showrating==true) {
			for (i = 1; i <= 5; i++) {
				var ridimobj = this.getelement("ratingstar" + i);
				if (ridimobj) {
					var ratingstate = (this.rating==null)?"non":((this.rating>=i)?"off":"non");
					ridimobj.src = imagepath + "rating" + ratingstate + ".gif";
				}
			}
			this.setratingtext(this.ratingtext);
		}
	}

	this.setcomments = function(text) {
		var introtextobj = this.getelement("comments");
		if (introtextobj) introtextobj.value = text;
	}

	this.getcomments = function() {
		var commenttextobj = this.getelement("comments");
		return (commenttextobj)?commenttextobj.value:"";
	}

	this.getemail = function() {
		var emailtextobj = this.getelement("email");
		return (emailtextobj)?emailtextobj.value:"";
	}

	this.clickedsubmit = function() {
		var commentsobj = this.getelement('comments');
		if (commentsobj.value=="") {
			alert("Please provide your comments");
			commentsobj.focus();
			return;
		}
		alert(this.responsetext);
		var formobj = this.getelement('form');
		if (formobj) formobj.submit();
		this.setcomments("");
		this.setrating(0);
	}

	this.render = function() {
		var out= "<div class=\"feedbackpanel\" id=\"" + this.getelementid('feedback') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		out += "<form id=\"" + this.getelementid('form') + "\" method=\"get\" action=\"" + this.posturl + "\" target=\"" + this.getelementid('hiddenframe') + "\">";
		out += "<input name=\"communication_id\" type=\"hidden\" id=\"" + this.getelementid("communicationid") + "\" value=\"" + communication.id + "\" />";
		out += "<input name=\"email\" type=\"hidden\" id=\"" + this.getelementid("adminemail") + "\" value=\"" + this.email + "\" />"
		out += "<input name=\"fbrating\" type=\"hidden\" id=\"" + this.getelementid("rating") + "\" value=\"" + this.rating + "\" />";
		out += "<div id=\"" + this.getelementid("introtext") + "\" class=\"helptext\">" + this.introtext + "</div>";
		out += "<textarea name=\"feedback_message\" class=\"message\" id=\"" + this.getelementid("comments") + "\"></textarea>";
		out += "<br/><br/>";
		out += "<div id=\"" + this.getelementid("emailtext") + "\" class=\"helptext\">" + this.emailtext + "</div>";
		out += "<input class=\"sltext\" name=\"feedback_email\" type=\"text\" id=\"" + this.getelementid("useremail") + "\" value=\"" + this.useremail + "\">";
		out += "<br/><br/>";
		if (this.showrating==true) {
			out += "<div id=\"" + this.getelementid("ratingtext") + "\" class=\"helptext\">" + this.ratingtext + " (" + this.scorenames[0] + ")</div>";
			for (i = 1; i <= 5; i++) {
				var ratingstate = (this.rating==null)?"non":((this.rating>i)?"off":"non");
				out += "<img width=\"30\" height=\"30\" id=\"" + this.getelementid("ratingstar" + i) + "\" alt=\"" + this.scorenames[i] + "\" onclick=\"callpanel(" + this.uid + ",'setrating(" + i + ")');\" src=\"" + imagepath + "rating" + ratingstate + ".gif\">";
			}
			out += "<br/><br/>";
		}
		out += drawimagebutton(this.getelementid('submit'),"Send Feedback","callpanel(" + this.uid + ",'clickedsubmit()')");
		out += "</form>";
		out += "<iframe id=\"" + this.getelementid('hiddenframe') + "\" name=\"" + this.getelementid('hiddenframe') + "\" class=\"debugpostframe\"></iframe>";
		out += "</div>";
		return out;
	}

	this.refresh = function() {

	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}


function btfile(assetid,link,title,description) {
	this.assetid = assetid;
	this.link = link;
	this.title = title;
	this.description = (description==false)?"":description;
	this.openinwindow = false;
	this.windowwidth = 0;
	this.windowheight = 0;
	this.posturl = "../mod/update_stats.php";
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.actioncall = function(action) {
		return "callpanel(" + this.uid + ",'" + action + "')";
	}

	this.clickedfile = function() {
		var url = this.posturl + "?communication_id=" + communication.id;
		url += "&asset_id=" + this.assetid;
		url += "&name=" + this.title;
		url += "&description=" + this.description;
		url += "&player_id=" + communication.playerid;
		url += "&player_name=" + communication.playername;
		url += "&type=Download";
		var imgobj = new Image;
		imgobj.src = url;
	}

	this.render = function() {
		var text = "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"options\">";
		text +="<tr>";
		text +="<td>";
		text +="<div class=\"title\"><a class=\"file\" href=\"" + this.link + "\" onclick=\"" + this.actioncall('clickedfile()') + "\" target=\"_blank\">" + this.title + "</a></div>";
		if (this.description) text +="<div class=\"description\">" + this.description + "</div>";
		text +="</td><td width=\"25\" valign=\"top\" align=\"right\"><a class=\"file\" onclick=\"" + this.actioncall('clickedfile()') + "\" href=\"" + this.link + "\" target=\"_blank\"><img class=\"icon\" src=\"" + imagepath + "spacer.gif\"></a></td>";
		text +="</tr>";
		text +="</table>";
		return drawroundedframe(this.getelementid('file'),text);
	}

	this.refresh = function() {

	}
}

function btdownloads() {
	this.className = "btdownloads";
	this.filelist = new Array();
	this.title = "Downloads";
	this.description = "Please click a file to download";
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.addfile = function(assetid,link,title,description) {
		var newfile = new btfile(assetid,link,title,description);
		this.filelist[this.filelist.length] = newfile;
		return newfile;
	}

	this.render = function() {
		var out = "<div class=\"downloadspanel\" id=\"" + this.getelementid('downloads') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		out += (this.description!="")?"<div class=\"description\">" + this.description + "</div>":"";
		for (var idx = 0; idx < this.filelist.length; idx++) {
			out += this.filelist[idx].render();
		}
		out += "</div>";
		return out;
	}

	this.draw = function() {
		document.write(this.render);
	}

	this.refresh = function() {

	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function btchapter(time,description) {
	this.time = time;
	this.description = description;
	this.parent = null;
	this.className = "btchapter";
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.actioncall = function(action) {
		return "callpanel(" + this.uid + ",'" + action + "')";
	}

	this.clickedchapter = function() {
		if (media) {
			media.jumpandplay(this.time);
		}
	}

	this.render = function() {
		var text = "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"options\">";
		text +="<tr>";
		text +="<td>" + this.description + "</td><td width=\"25\" valign=\"top\" align=\"right\"><img class=\"icon\" src=\"" + imagepath + "spacer.gif\"></td>";
		text +="</tr>";
		text += "</table>";
		return drawroundedframe(this.getelementid(''),text,this.actioncall('clickedchapter()'));
	}

	this.refresh = function() {

	}
}


function btchapters() {
	this.className = "btchapters";
	this.chapterlist = new Array();
	this.title = "Chapters";
	this.parent = null;
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.addchapter = function(time,description) {
		var newchapter = new btchapter(time,description);
		newchapter.parent = this;
		this.chapterlist[this.chapterlist.length] = newchapter;
	}

	this.render = function() {
		var out = "<div class=\"chapterspanel\" id=\"" + this.getelementid('chapters') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		out += "<div class=\"chapters\">";
		for (var idx = 0; idx < this.chapterlist.length; idx++) {
			out += this.chapterlist[idx].render();
		}
		out += "</div>";
		out += "</div>";
		return out;
	}

	this.draw = function() {
		document.write(this.render);
	}

	this.refresh = function() {

	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}


function btformfieldtextbox(name,title,value) {
	this.name = name;
	this.title = title;
	this.required = false;
	this.value = value;
	this.validation = false;
	this.uid = panels.register(this);
	this.className = "btformfieldtextbox";
	
	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.getvalue = function(name) {
		var formelement = this.getelement(name) ;
		return formelement.value ;
	}

	this.getpostvalue = function() {
		return this.name+"="+this.value;
	}

	this.onkeypress = function(event) {
		this.isvalid();
	}

	this.isvalid = function() {
		var formelement = this.getelement(this.name);
		if (formelement) this.value = formelement.value;
		if (this.value=="" && this.required) {
 			this.highlitefield('invalid');
			return false;
		}
 		this.highlitefield('');
		return true;
	}

	this.highlitefield = function(highlitename) {
		var fieldcontainer = this.getelement('fieldcontainer');
		if (fieldcontainer) {
			fieldcontainer.className = "formfield "+highlitename;
		}
	}

	this.render = function() {
		var id = this.getelementid(this.name);
		var out = "<div class=\"formfield\" id=\""+this.getelementid('fieldcontainer')+"\">";
		out += this.title+((this.required)?" (Required)":"")+"<br>";
		out += "<input id=\"" + id + "\" class=\"textfield\" value=\""+this.value+"\" name=\"" + this.name + "\" type=\"text\" onblur=\"return callpanel(" + this.uid + ",'onkeypress()')\">";
		out += "</div>";
		return out;
	}
}

function btformfieldemail(name,title,value) {
	this.name = name;
	this.title = title;
	this.required = false;
	this.value = value;
	this.uid = panels.register(this);
	this.className = "btformfieldemail";
	
	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.getvalue = function(name) {
		var formelement = this.getelement(name) ;
		return formelement.value ;
	}

	this.getpostvalue = function() {
		return this.name+"="+this.value;
	}

	this.onkeypress = function(event) {
		this.isvalid();
	}

	this.isvalid = function() {
		var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		var formelement = this.getelement(this.name);
		if (formelement) this.value = formelement.value;
		var valid = (filter.test(this.value));
		if (valid) {
			this.highlitefield('');
			return true;
		} else {
			this.highlitefield('invalid');
			return false;
		}
	}

	this.highlitefield = function(highlitename) {
		var fieldcontainer = this.getelement('fieldcontainer');
		if (fieldcontainer) {
			fieldcontainer.className = "formfield "+highlitename;
		}
	}

	this.render = function() {
		var id = this.getelementid(this.name);
		var out = "<div class=\"formfield\" id=\""+this.getelementid('fieldcontainer')+"\">";
		out += this.title+((this.required)?" (Required)":"")+"<br>";
		out += "<input id=\"" + id + "\" class=\"textfield\" value=\""+this.value+"\" name=\"" + this.name + "\" type=\"text\" onblur=\"return callpanel(" + this.uid + ",'onkeypress()')\">";
		out += "</div>";
		return out;
	}
}

function btformfieldcheckbox(name,title,value) {
	this.name = name;
	this.title = title;
	this.required = false;
	this.value = (value==true);
	this.uid = panels.register(this);
	this.className = "btformfieldcheckbox";
	
	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.getvalue = function(name) {
		var formelement = this.getelement(name) ;
		return formelement.value ;
	}

	this.getpostvalue = function() {
		return this.name+"="+this.value;
	}

	this.onclick = function(event) {
		var formelement = this.getelement(this.name);
		this.value = formelement.value;
	}

	this.isvalid = function() {
		return(true);
	}

	this.render = function() {
		var id = this.getelementid(this.name);
		var out = "<div class=\"formfield\">";
		out += "<input class=\"checkbox\" border=\"0\" id=\"" + id + "\" name=\"" + this.name + "\" type=\"checkbox\" "+(this.value?"checked":"")+" onclick=\"return callpanel(" + this.uid + ",'onclick()')\"/>"; 
		out += this.title;
		out += "</div>";
		return out;
	}
}


function btregistrationform(alias) {
	this.alias = alias;
	this.title = null;
	this.formfields = Array();
	this.uid = panels.register(this);
	this.className = "btregistrationform";
	this.mode = "FORM";
	this.posturl = "../mod/post_test.php?action=testregister";

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.setposturl = function(url) {
		this.posturl = url;
	}

	this.post = function() {
	}

	this.getpostvalues = function() {
		var postdata = "";
		for (var i=0; i<this.formfields.length; i++) {
			postdata += this.formfields[i].getpostvalue();
			if (i<(this.formfields.length-1)) postdata +="&";
		}
		return postdata;
	}

	this.submit = function() {
		if (this.isvalid()) {
			if (this.parent) {
				this.parent.registrationok();
			}
		}
	}

	this.getvalue = function() {

	}

	this.isvalid = function() {
		for (var i = 0; i < this.formfields.length; i++) {
			if (!this.formfields[i].isvalid()) {
				alert('Please check your have correctly entered \''+this.formfields[i].title+'\' and try again');
				return false;
			}
		}
		return true;
	}

	this.setmode = function(mode) {
		this.mode = mode;
	}

	this.addfield = function(type,name,title,value,required) {
		try {
  			var fieldobj = eval('new btformfield'+type+'(name,title,value)');
		} catch(e) {
			alert('Attempting to add invalid field type : '+type);
  			return false;
		}
		if (fieldobj) {
			fieldobj.required = required;
			this.formfields[this.formfields.length] = fieldobj;
		}
		return fieldobj;
	}

	this.render = function() {
		var out = "<div class=\"registrationarea\" id=\"" + this.getelementid('registrationarea') + "\">";
		switch (this.mode) {
			case "SUBMIT" :
				var boxcontent = "<img class=\"sendingicon\" valign=\"absmiddle\" src=\"" + imagepath + "spacer.gif\"> Processing your details...";
                		out += drawroundedframe(this.getelementid('certdownloadbox'),boxcontent);
			break;

			case "NORETRIES" :
				var boxcontent = "Sorry.<br>You have already taken this test. (No more retries allowed.)";
                		out += drawroundedframe(this.getelementid('certdownloadbox'),boxcontent);
			break;

			case "PASS" :
				var boxcontent = "You have already passed this test.";
                		out += drawroundedframe(this.getelementid('certdownloadbox'),boxcontent);
			break;
		
			case "FORM" :
			default : 
				out += "<div class=\"formpanel\" id=\"" + this.getelementid('formpanel') + "\">";
				out += "<div class=\"instructions\">Please complete the following registration form and click Submit</div>";
				out += "<form>";
				for (var i = 0; i < this.formfields.length; i++) {
					out += this.formfields[i].render();
				}
				out += "</form>" ;
				out += "</div>"  ;
				out += drawimagebutton(this.getelementid('submit'),"Submit","callpanel(" + this.uid + ",'submit()')");
				out += "</div>"  ;
			break;
		}
		return out;
	}
}

function bttestquestion(alias,questiontext,correctansweridx,selectmultiple)	{
	this.parentobject = null;
	this.alias = alias;
	this.questiontext = questiontext;
	this.className = "bttestquestion";
	this.selectmultiple = selectmultiple;
	this.correctansweridx = correctansweridx;
	this.useranswer = null;
	this.options = new Array();
	this.selectedoptions = new Array();
	this.attempts = 0;
	this.iscorrect = false;
	this.markquestion = false;
	this.uid = panels.register(this);

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.setparent = function(parentobj) {
		this.parentobject = parentobj;
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.addoption = function(text) {
		this.options[this.options.length] = text;
		this.selectedoptions[this.selectedoptions.length] = false;
	}

	this.deselectall = function() {
		for (var idx = 0; idx < this.selectedoptions.length; idx++) {
			this.selectedoptions[idx] = false;
		}
	}

	this.isselected = function(idx) {
		return this.selectedoptions[idx];
	}

	this.selectoption = function(idx) {
		this.selectedoptions[idx] = true;
	}

	this.deselectoption = function(idx) {
		this.selectedoptions[idx] = false;
	}

	this.getinputvalue = function() {
		var input = "";
		for (var idx = 0; idx < this.selectedoptions.length; idx++) {
			if (this.selectedoptions[idx]) input += idx + ",";
		}
		return (input.substring(0,input.length - 1));
	}

	this.getuseranswer = function() {
		var answer='';
		for (var key in this.useranswer) answer+=this.options[this.useranswer[key]] + " , ";
		answer = answer.substring(0,answer.length-2);
		return answer;
	}

	this.getcorrectanswer = function() {
		var correct='';
		for (var key in this.correctansweridx) correct+=this.options[this.correctansweridx[key]] + " , ";
		correct = correct.substring(0,correct.length-2);
		return correct;
	}

	this.getuseransweridx = function() {
		return this.useranswer.toString();
	}

	this.checkboxes = function() {
		for (var idx = 0; idx < this.selectedoptions.length; idx++) {
			var checkboxobj = this.getelement('checkbox' + idx);
			if (checkboxobj) checkboxobj.checked = this.isselected(idx);
		}
	}

	this.clickanswer = function(idx) {
		if (this.selectmultiple) {
			this.selectedoptions[idx] = !this.isselected(idx);
		} else {
			this.deselectall();
			this.selectedoptions[idx] = true;
		}
		this.checkboxes();
	}

	this.tryagain = function() {
		this.markquestion = false;
		this.contentchanged();
	}

	this.nextquestion = function() {
		this.parentobject.getnextquestion();
	}

	this.submit = function() {
		var option = new Array() ;
		for ( var idx = 0 ; idx < this.selectedoptions.length ; idx++ ) {
			if ( this.selectedoptions[idx] == true ) {
				option.push(idx) ;
			}
		}

		if ( option.length == 0 ) {
			alert( "Please choose from the selection" ) ;
			return false ;
		}

		this.attempts++;
		this.useranswer = option;
		if(this.selectmultiple){
			if(option.toString() == this.correctansweridx.toString())
				this.iscorrect = true;
		}else{
			for(var key in this.correctansweridx)
				if(this.correctansweridx[key]==option[0]){
					this.iscorrect = true;
					break;
				}
		}
		this.parentobject.answeredquestion(this.iscorrect);
		return true;
	}

	this.checkIndex = function(idx){
		for(var key in this.correctansweridx)
			if(this.correctansweridx[key]==idx)
				return true;
		return false;
	}
	
	this.renderbutton = function(idx) {
		var text = "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"options\">";
		text +="<tr>";
		text +="<td>" + this.getoptionletter(idx) + ") " + this.options[idx] + "</td><td width=\"25\"><input type=\"checkbox\" border=\"0\" id=\"" + this.getelementid('checkbox' + idx) + "\" name=\"Q01\" value=\"" + idx + "\" " + (this.isselected[idx]?"checked":"") + "></td>";
		text +="</tr>";
		text += "</table>";
		return drawroundedframe('123',text,"callpanel(" + this.uid + ",'clickanswer(" + idx + ")');");
	}

	this.renderanswer = function(idx,mark) {
		var text = "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"options\">";
		text +="<tr>";
		text +="<td>" + this.getoptionletter(idx) + ") " + this.options[idx] + "</td><td width=\"25\">";
		if (mark) {
			text += (this.checkIndex(idx))?"<img class=\"tickimage\" src=\"" + imagepath + "spacer.gif\">":"<img class=\"crossimage\" src=\"" + imagepath + "spacer.gif\">";
		}
		text +="</td>";
		text +="</tr>";
		text += "</table>";
		return drawroundedframe('123',text,"callpanel(" + this.uid + ",'clickanswer(" + idx + ")');");
	}

	this.renderquestion = function() {
		var out = "<div class=\"questionarea\" id=\"" + this.getelementid('questionarea') + "\">";
		var out = "<div>";
		var out = "<div>";
		var attempttext = (this.attempts>0)?" (You have "+(this.parentobject.attempts-(this.attempts+1))+" more attempts)":"";
		out += "<div class=\"question\" id=\"" + this.getelementid('question') + "\">";
		out += "<div class=\"questionnumber\">Question " + this.parentobject.currentquestionnumber() + " of " + this.parentobject.gettotalquestions() + attempttext +"</div>";
		out += '<div style="height: 50px; overflow: auto;">'
		out += this.questiontext;
		out += "</div>";
		out += "</div>";
		out += "<div class=\"helptext\" id=\"" + this.getelementid('helptext') + "\">";
		if (this.selectmultiple) {
			out += "Please select the correct answers below";
		} else {
			out += "Please select one option from below";
		}
		out += "</div><div class=\"questionoptions\"><form>";
		for (var idx = 0; idx < this.options.length; idx++) {
			out += this.renderbutton(idx);
		}
		out += "</form>";
		out += "</div>";
		out += "</div>";
		out += drawimagebutton(this.getelementid('submit'),"Next","callpanel(" + this.uid + ",'submit()')");
		return out ;
	}

	this.markquestion = function() {
		this.markquestion=true;
	}

	this.rendermark = function() {
		var out = "<div class=\"questionarea\" id=\"" + this.getelementid('questionarea') + "\">";
		var out = "<div>";
		var attempttext = (this.attempts>0)?" (Attempt "+(this.attempts)+" of "+this.parentobject.attempts+")":"";
		out += "<div class=\"question\" id=\"" + this.getelementid('question') + "\">";
		out += "<div class=\"questionnumber\">Question " + this.parentobject.currentquestionnumber() + " of " + this.parentobject.gettotalquestions() + attempttext + "</div>";
		out += this.questiontext;
		out += "</div>";
		out += "<div class=\"helptext\" id=\"" + this.getelementid('helptext') + "\">";
		out += (this.iscorrect)?"Well Done, you answered correctly":"You answered incorrectly.";
		out += "</div>";
		out += "<div class=\"questionoptions\"><form>";
		for (var idx = 0; idx < this.options.length; idx++) {
			var mark=false;
			for(var key in this.useranswer) if(this.useranswer[key]==idx) mark=true;
			out += this.renderanswer(idx,mark);
		}
		out += "</form>";
		
		if (!this.iscorrect && this.attempts<this.parentobject.attempts) {
			out += drawimagebutton(this.getelementid('tryagain'),"Try Again","callpanel(" + this.uid + ",'tryagain()')");
		} else {
			out += drawimagebutton(this.getelementid('nextquestion'),"Next","callpanel(" + this.uid + ",'nextquestion()')");
		}
		out += "</div>";
		out += "</div>";
		return out;	
	}

	this.render = function() {
		if (this.markquestion==true) {
			return this.rendermark();
		}
		return this.renderquestion();
	}

	this.getoptionletter = function(letternum) {
		return String.fromCharCode(65 + letternum);
	}
	
	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function bttest(alias, title) {
	this.alias = alias;
	this.title = title;
	this.description = null;
	this.onchange = null;
	this.className = "bttest";
	this.questionlist = new Array();
	this.registrationform = new btregistrationform(alias);
	this.registrationform.parent = this;
	this.registrationcomplete = false;
	this.registrationchecked = false;
	this.testcomplete = false;
	this.currentquestion = null;
	this.passmessage = "You passed";
	this.failmessage = "Sorry. You didn't pass";
	this.registered = false;
	this.viewanswers = 0;
	this.passmark = null;
	this.posturl = "../mod/post_test.php";
	this.attemptposturl = "../mod/test_verify.php";
	this.uid = panels.register(this);
	this.result = '' ;
	this.attempts = 1;
	this.tests = 1;
	this.currenttests=1;
	this.gettimeout = null ;
	this.certtype = 'pdf';

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.setdescription = function(text) {
		this.description = text;
		var descriptionobj = this.getelement("description");
		if (descriptionobj) descriptionobj.value = this.description;
	}

	this.setpassmessage = function(message) {
		this.passmessage = message;
	}

	this.setfailmessage = function(message) {
		this.failmessage = message;
	}

	this.setpassmark = function(mark) {
		this.passmark = mark;
	}
	this.settests=function(attempts){
		this.tests = attempts;
	}
	this.setattempts = function(attempts) {
		this.attempts = attempts;
	}

	this.setviewanswers = function(view) {
		this.viewanswers = view;
	}
	
	this.setcerttype = function(type){
		this.certtype = type;
	}
	
	this.getpanelcall = function(call) {
		return "callpanel(" + this.uid + ",call)";
	}

	this.currentquestionnumber = function() {
		for (var idx = 0; idx < this.questionlist.length; idx++) {
			if (this.currentquestion==this.questionlist[idx]) return (idx + 1);
		}
		return -1;
	}

	this.gettotalquestions = function() {
		return this.questionlist.length;
	}

	this.addquestion = function(alias,questiontext,correctansweridx,mutually) {
		mutually = parseInt(mutually); 
		if(mutually) var selectmultiple=false;
		else var selectmultiple=true;
		for (var key in correctansweridx){correctansweridx[key] = ((correctansweridx[key] >> (arguments.length-4))-(arguments.length-4));}
		var question = new bttestquestion(alias,questiontext,correctansweridx,selectmultiple);
		for (i = 4; i < arguments.length; i++) {
			question.addoption(arguments[i]);
		}
		question.setparent(this);
		this.questionlist[this.questionlist.length] = question;
		if (this.currentquestion == null) this.currentquestion = question;
	}

	this.addregistrationfield = function(type,name,title,value,required) {
		this.registrationform.addfield(type,name,title,value,required);
	}

	this.registrationok = function() {
		this.registrationform.setmode('SUBMIT');
		this.contentchanged();
		writedebug("Test Registration OK");
		this.checkattempts();
	}

	this.answeredquestion = function(correct) {
		if (this.viewanswers==1 || (!correct && (this.currentquestion.attempts<this.attempts))) {
			this.currentquestion.markquestion=true;
			this.contentchanged();
			return;
		}
		this.getnextquestion();
	}

	this.refresh = function() {
		return this.render();
	}

	this.submitreturn = function(statuscode,response) {
		writedebug("bttest.submitreturn("+statuscode+","+response+")");
		//alert(response);
		var passed = (this.calculatescore()>=this.passmark);
		var certdownloadobj = this.getelement('certdownload');
		if (certdownloadobj) {
			if (passed) {
				if(this.certtype == 'pdf')
					var certtext = "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td align=\"left\"><a href=\"http://www.adobe.com/products/acrobat/readstep2.html\" target=\"_blank\"><img class=\"pdfimage\" src=\"" + imagepath + "spacer.gif\" valign=\"absmiddle\"></a></td><td>Your certificate can be downloaded <a href=\""+response+"\" target=\"_blank\">here</a></td><td align=\"right\"><a href=\""+response+"\" target=\"_blank\"><img class=\"certificateimage\" src=\"" + imagepath + "spacer.gif\" valign=\"absmiddle\"></a></td></tr></table>";
				else
					var certtext = "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td>Your certificate can be viewed and printed <a href=\""+response+"\" target=\"_blank\">here</a></td><td align=\"right\"><a href=\""+response+"\" target=\"_blank\"><img class=\"certificateimage\" src=\"" + imagepath + "spacer.gif\" valign=\"absmiddle\"></a></td></tr></table>";
				certdownloadobj.innerHTML = certtext;
			} else {
				document.getElementById('downloadCert').style.display = 'none';
			}
		}
	}

	this.submit = function() {
		var formdata = this.posturl+"?"+this.registrationform.getpostvalues();
		for (var idx = 0; idx < this.questionlist.length; idx++) {
			formdata+=("&q"+(idx)+"="+this.questionlist[idx].getuseransweridx());
		}	
		formdata+="&testid="+this.alias;
                formdata+='&communication_id=' + communication.id;
		writedebug("Test Submitting Form data : "+formdata);
		//alert(formdata);
		setTimeout("doxmlrequest(\""+formdata+"\",\"panels.getbyuid("+this.uid+").submitreturn(statuscode,response);\")",4000);
	}

	this.checkattemptsreturn = function(statuscode,response) {
		writedebug("bttest.submitreturn("+statuscode+","+response+")");
		writedebug("Test Registration OK");
		if (response=="OK" || response=="0") this.registrationcomplete = true;
		this.registrationform.setmode(response);
		this.registrationcheck = response;
		this.contentchanged();
	}

	this.checkattempts = function() {
		var formdata = this.attemptposturl+"?"+this.registrationform.getpostvalues();
		formdata+="&testid="+this.alias;
                formdata+='&communication_id=' + communication.id;
		writedebug("Testing Attempts : "+formdata);
		//alert(formdata);
		setTimeout("doxmlrequest(\""+formdata+"\",\"panels.getbyuid("+this.uid+").checkattemptsreturn(statuscode,response);\")",1000);
	}

	this.getquestionindex = function(questionobj) {
		for (var idx = 0; idx < this.questionlist.length; idx++) {
			if (this.questionlist[idx]==questionobj) return idx;
		}
		return null;
	}

	this.movequestion = function(amount) {
		var questioncount = this.questionlist.length;
		var currentquestionidx = this.getquestionindex(this.currentquestion);
		var newquestionindex = currentquestionidx + amount;
		if (newquestionindex < 0) newquestionindex = 0;
		if (newquestionindex >= questioncount) newquestionindex = questioncount - 1;
		this.currentquestion = this.questionlist[newquestionindex];
		this.contentchanged();
	}

	this.calculatescore = function() {
		var score = 0;
		for (var idx = 0; idx < this.questionlist.length; idx++) {
			if (this.questionlist[idx].iscorrect) score++;	
                }
		return score;
	}

	this.getnextquestion = function() {
		var questioncount = this.questionlist.length;
		var currentquestionidx = this.getquestionindex(this.currentquestion) + 1;
		if (questioncount != currentquestionidx) {
			this.movequestion(1);
                } else {
			this.testcomplete = true;
			this.submit();
                        this.contentchanged();
                }
	}

	this.renderresults = function() {
		var score = this.calculatescore();
		var passed = (score>=this.passmark);
		var out = "";
		var boxcontent = "<div id=\"passmessage\">";
		if (passed) {
			boxcontent += this.passmessage;
		} else {
			boxcontent += this.failmessage;
		}
		boxcontent += " You scored "+score+" out of "+this.questionlist.length+".";
		boxcontent += "</div>";
		out += drawroundedframe(this.getelementid('certdownloadbox'),boxcontent);
		boxcontent = "<div id=\""+this.getelementid('certdownload')+"\"><img class=\"sendingicon\" valign=\"absmiddle\" src=\"" + imagepath + "spacer.gif\"> Submitting your test results...</div>";
		out += drawroundedframeDark(this.getelementid('certdownloadbox'),boxcontent);
		out += "<br>";		
		if (this.viewanswers==2) {
			out += "<div class=\"answerscontainer\">";
			out += "<div class=\"answers\">";
			out += "<table class=\"resulttable\">";
			var odd = true;
			out += "<tr class=\"header\">";
			out += "<td>&nbsp;</td><td colspan=\"2\">How you Answered...</td>";
			out += "</tr>";
			for(var idx = 0; idx < this.questionlist.length; idx++) {
				out += "<tr class=\""+(odd?"odd":"even")+"\">";
                        	out += "<td class=\"resultquestionno\">"+(idx+1)+".</td><td class=\"resultquestion\">"+this.questionlist[idx].questiontext+"<br>";
				out += "<div class=\"resultanswer\">"+this.questionlist[idx].getuseranswer()+" "+((this.questionlist[idx].iscorrect)?"":"<span class=\"correctanswer\">(Correct Answer : "+this.questionlist[idx].getcorrectanswer()+")</span>")+"</div></td>";
				out += "<td class=\"resultanswer\">";
				out += "<img class=\""+((this.questionlist[idx].iscorrect)?'tickimage':'crossimage')+"\" src=\"" + imagepath + "spacer.gif\"></td>";
				out += "</tr>";
				odd = (odd==true)?false:true;
                	}
			out += "</table>";
			out += "</div>";
			out += "</div>";
		}
		if(!passed && (this.currenttests<this.tests || this.tests==0)) out+=drawimagebutton(this.getelementid('tryagain'),"Try Again","callpanel(" + this.uid + ",'tryagain()');");
		return out;
	}
    
	this.tryagain = function(){
		this.currenttests++;
		this.testcomplete = false;
		for(var key in this.questionlist){
			this.questionlist[key].redermark;
			this.questionlist[key].selectedoptions = new Array();
			this.questionlist[key].attempts = 0;
			this.questionlist[key].iscorrect = false;
		}
		this.currentquestion = this.questionlist[0];
		this.contentchanged();
	}
	
	this.render = function() {
		var out = "<div class=\"testpanel\" id=\"" + this.getelementid('test') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		var questioncount = this.questionlist.length ;
		var currentquestionidx = this.getquestionindex( this.currentquestion )+1 ;
		if (!this.registrationcomplete) {
			if (this.description) out += "<div class=\"description\" id=\"" + this.getelementid('description') + "\">" + this.description + "</div>";
			out += this.registrationform.render();
		} else if (!this.testcomplete) {
			if (questioncount==0) {
				out += drawroundedframe(this.getelementid('ta'),"This test has no questions configured.<p>Please return when  questions have been added.");
			} else {
				out += this.currentquestion.render();
			}
		} else {
			out += this.renderresults();
		}
		out += "<iframe id=\"" + this.getelementid("hiddenframe") + "\" class=\"debugpostframe\"></iframe>";
		out += "</div>";
		return out;
	}
	
	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function btvote(enabled,alias,text) {
	this.enabled = enabled;
	this.alias = alias;
	this.text = text;
	this.title = "";
	this.response = null;
	this.options = new Array();
	this.parent = null;
	this.resultsonly = false;
	this.className = "btvote";
	this.onchange = null;
	this.privatevote = false;
	this.responsemessage = "Thank you. Your vote has been submitted.";
	this.results = null;
	this.currentlevels = null;
	this.submitted = false;
	this.selectedoption = -1;
	this.uid = panels.register(this);
	this.displayresults = false;
	this.posturl = "../mod/post_vote.php";
	this.closed = false;

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.closevote = function() {
		this.closed = true;
	}

	this.addoption = function(text) {
		this.options[this.options.length] = text;
	}

	this.refresh = function() {
		return this.render();
	}

	this.clickanswer = function(idx) {
		var radiobutton = this.getelement('radio' + idx);
		radiobutton.checked = true;
		this.selectedoption = idx;
	}

	this.submit = function() {
		if (this.selectedoption < 0) {
			alert("You must choose an option");
			return false;
		}
		if (!this.submitted) {
			if (this.results) this.results[this.selectedoption]++;
			var submitform = this.getelement("hiddenframe");
			if (submitform) {
				var submiturl = this.posturl + "?voteID=" + this.alias + "&answerID=" + this.selectedoption + "&action=vote" +
								'&communication_id=' + communication.id +
								'&player_id=' + communication.playerid +
								'&player_name=' + escape(communication.playername);
				writedebug("submitting vote - " + submiturl);
				submitform.src = submiturl;
				this.submitted = true;
				//this.showresults(true);
				this.contentchanged();
			}
		}
		return false;
	}

	this.showresults = function(on) {
		var questionobj = this.getelement('question');
		var resultobj = this.getelement('result');
		var responseobj = this.getelement('responsemessage');
		if (questionobj) questionobj.style.display = (on?'none':'block');
		if (resultobj) resultobj.style.display = (!on?'none':'block');
		if (responseobj) responseobj.style.display = 'block';
	}

	this.renderform = function() {
		var out = "<div id=\"" + this.getelementid("question") + "\" style=\"display:" + ((this.resultsonly && !this.submitted) ? "none" : "block") + ";\">";
		out += "<div class=\"helptext\">Please choose an option below and click 'Submit'.</div>";
		for (var idx = 0; idx < this.options.length; idx++) {
			var text = "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"options\">";
			text +="<tr>";
			//text +="<td>" + this.options[idx] + "</td><td width=\"25\"><input type=\"radio\" id=\"" + this.getelementid('radio' + idx) + "\" name=\"" + this.getelementid('radio') + "\" value=\"" + idx + "\" " + ((this.selectedoption==idx)?"checked=\"true\"":"checked=\"false\"") + "></td>";
			text +="<td>" + this.options[idx] + "</td><td width=\"25\"><input type=\"radio\" id=\"" + this.getelementid('radio' + idx) + "\" name=\"" + this.getelementid('radio') + "\" style=\"border:0px;\" value=\"" + idx + "\" " + ((this.selectedoption==idx)?"checked=\"true\"":"") + "></td>";
			text +="</tr>";
			text += "</table>";
			out += drawroundedframe('123',text,"callpanel(" + this.uid + ",'clickanswer(" + idx + ")');");
		}
		out += drawimagebutton(this.getelementid('submitvote'),"Submit Vote","callpanel(" + this.uid + ",'submit()')");
		out += "<iframe id=\"" + this.getelementid("hiddenframe") + "\" class=\"debugpostframe\"></iframe>";
		out += "</div>";
		return out;
	}

	this.renderresults = function() {
		var out = "<div id=\"" + this.getelementid("result") + "\" class=\"voteresultpanel\">";
		if (!this.resultsonly) out += "<div id=\"" + this.getelementid("responsemessage") + "\" class=\"responsemessage\">" + this.responsemessage + "</div>";
		if (!this.privatevote) {
			out += "<div id=\"" + this.getelementid("graph") + "\" class=\"votegraph\" style=\"display:" + (this.results?"block":"none") + ";\">";
			for (var idx = 0; idx < this.options.length; idx++) {
				if (this.results) {
					total = this.countresults();
					percentage = (total>0)?(Math.round((100/total)*this.results[idx])):0;
				} else {
					percentage = 1;
				}
				out +="<div class=\"voteresult\">" + this.options[idx] + " (<span id=\"" + this.getelementid("percent" + idx) + "\">" + percentage + "</span>%)</div>";
				out +="<div class=\"votebar\" id=\"" + this.getelementid("graphbar" + idx) + "\" style=\"width:" + percentage + "%;\"></div>";
			}
			out += "</div>";
		}
		out += "</div>";
		if(this.privatevote && !this.displayresults && !media.live){
			setTimeout("callpanel(" + this.parent.uid + ",'next()')",1500)
		}
		return out;
	}

	this.render = function() {
		var out = "<div class=\"votequestion\">" + this.text + "</div>";
		if (!this.submitted && !this.resultsonly) {
			out += this.renderform();
		} else {
			out += this.renderresults();
		}
		return out;
	}

	this.countresults = function() {
		var total = 0;
		for (var idx = 0; idx < this.results.length; idx++) total += parseInt(this.results[idx]);
		return total;
	}

	this.setresponsemessage = function(text) {
		if (text!='') this.responsemessage = text;
		var responsemessageobj = this.getelement("responsemessage");
		if (responsemessageobj) responsemessageobj.innerHTML = this.responsemessage;
	}

	this.updategraph = function() {
		var total = this.countresults();
		if (!this.results) return false;
		for (var idx = 0; idx < this.options.length; idx++) {
			var percentage = (total>0)?(Math.round((100/total)*this.results[idx])):0;
			var votebarobj = this.getelement("graphbar" + idx);
			if (votebarobj) votebarobj.style.width = percentage + "%";
			var votepercentobj = this.getelement("percent" + idx);
			if (votepercentobj) votepercentobj.innerHTML = percentage;
		}
	}

	this.smoothupdate = function(stepsleft) {
		var total = this.countresults();
		if (!this.results) return false;
		for (var idx = 0; idx < this.options.length; idx++) {
			var percentage = (total>0)?(Math.round((100/total)*this.results[idx])):0;
			var votebarobj = this.getelement("graphbar" + idx);
			if (votebarobj) votebarobj.style.width = percentage + "%";
			var votepercentobj = this.getelement("percent" + idx);
			if (votepercentobj) votepercentobj.innerHTML = percentage;
		}
	}

	this.setstatus = function(active) {
		var hilight = (!this.enabled && active);
		this.enabled = active;
		if (this.parent) {
			if (this.enabled) {
				if (this.parent.activevote == null) this.parent.show(this.alias);
			} else {
				if (this.parent.activevote == this) this.parent.hide();
			}
			if (hilight && this.parent.parentobject) this.parent.parentobject.contentchanged(true);
		}
	}

	this.updateresults = function(resultarray) {
		while (parseInt(resultarray.length) < parseInt(this.options.length)) {
			resultarray[resultarray.length] = 0;
		}
		this.results = resultarray;
		if (this.privatevote) return;
		if (!this.submitted) return;
		var graphobj = this.getelement("graph");
		if (graphobj) {
			graphobj.style.display = 'block';
			if (this.getelement("result")) {
				this.updategraph();
			}
		}
	}

	this.getquestionno = function(letternum) {
		return String.fromCharCode(65 + letternum);
	}

	this.contentchanged = function() {
		if (this.parent) this.parent.contentchanged(true);
	}
}


function btvotes() {
	this.onchange = null;
	this.title = "vote";
	this.votelist = new Array();
	this.activevote = null;
	this.className = "btvotes";
	this.optnumformat = 0;
	this.parent = null;
	this.novotemessage = "There is no active vote at this time.";
	this.uid = panels.register(this);
	this.updateurl = false;
	this.updateperiod = 5000;
	this.updatetimeout = null;

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.setupdateurl = function(updateurl) {
		this.updateurl = updateurl;
		if (this.updateurl) this.updatepoll();
	}

	this.updatepoll = function() {
		if (this.updateurl && this.updateperiod>0) {
			refreshscript(this.getelementid("pollscript"),this.updateurl + "?" + Math.random());
			this.updatetimeout = setTimeout("callpanel(" + this.uid + ",'updatepoll()')",this.updateperiod);
			return;
		}
		clearTimeout(this.updatetimeout);
		this.updatetimeout = null;
	}

	this.addvote = function(enabled,alias,votetext,privatevote,resultsonly) {
		if (this.voteexists(alias)) return false;
		var vote = new btvote(enabled,alias,votetext);
		vote.privatevote = privatevote;
		vote.resultsonly = resultsonly;
		for (var i = 5; i < arguments.length; i++) {
			vote.addoption(arguments[i]);
		}
		vote.parent = this;
		this.votelist[this.votelist.length] = vote;
		if (enabled && this.activevote == null) this.activevote = vote;
		this.contentchanged();
		return vote;
	}

	this.closevote = function(alias) {
		var voteobj = this.findvote(alias);
		if (voteobj) {
			voteobj.setclosed();
		}
	}

	this.updateresults = function(alias,responsetext) {
		var voteobj = this.findvote(alias);
		if (voteobj) {
			voteobj.setresponsemessage(responsetext);
			var resultarray = new Array();
			for (var i = 2; i < arguments.length; i++) {
				var resultvalue = parseInt(arguments[i]);
				resultvalue=(isNaN(resultvalue))?0:resultvalue;
				resultarray[resultarray.length]=resultvalue;

			}
			if (resultarray.length>0) voteobj.updateresults(resultarray);
		}
	}

	this.remove = function(alias) {
		var newvotelist = new Array();
		var found = false;
		for (var idx = 0; idx < this.votelist.length; idx++) {
			if (this.votelist[idx].alias!=alias) {
				newvotelist[newvotelist.length] = this.votelist[idx];
			} else {
				found = this.votelist[idx];
			}
		}
		if (found) {
			if (found==this.activevote) this.activevote = newvotelist[0];
			this.votelist = newvotelist;
			this.contentchanged();
		}
	}

	this.findvote = function(alias) {
		for (var idx = 0; idx < this.votelist.length; idx++) {
			if (this.votelist[idx].alias==alias) return this.votelist[idx];
		}
		return null;
	}

	this.getvoteindex = function(voteobj) {
		for (var idx = 0; idx < this.votelist.length; idx++) {
			if (this.votelist[idx]==voteobj) return idx;
		}
		return null;
	}

	this.voteexists = function(alias) {
		for (var idx = 0; idx < this.votelist.length; idx++) {
			if (this.votelist[idx].alias==alias) return true;
		}
		return false;
	}

	this.show = function(alias) {
		vote = this.findvote(alias);
		if (vote) {
			this.activevote = vote;
			this.contentchanged();
		}
	}

	this.hide = function() {
		this.activevote = null;
		this.contentchanged();
	}

	this.refresh = function() {
		var voteareaobj = this.getelement("votearea");
		if (voteareaobj) return this.render();
		this.updatenavigation();
		return false;
	}

	this.movevote = function(amount) {
		var votecount = this.votelist.length;
		var currentvoteidx = this.getvoteindex(this.activevote);
		var newvoteindex = currentvoteidx + amount;
		if (newvoteindex < 0) newvoteindex = 0;
		if (newvoteindex >= votecount) newvoteindex = votecount - 1;
		this.activevote = this.votelist[newvoteindex];
		this.contentchanged();
	}

	this.updatenavigation = function() {
		var votecount = this.votelist.length;
		var currentvoteidx = this.getvoteindex(this.activevote);
		var navigationobj = this.getelement("navigation");
		var navpreviousobj = this.getelement("navprevious");
		var navnextobj = this.getelement("navnext");
		var navtextobj = this.getelement("navtext");
		if (navigationobj) navigationobj.style.display=((votecount<=1)?'none':'block');
		//if (navnextobj) navnextobj.style.display = (currentvoteidx >= (votecount - 1)) ? 'hidden' : 'visible';
		//if (navpreviousobj) navpreviousobj.style.visibility = (currentvoteidx == 0) ? 'hidden' : 'visible';
		if (navtextobj) navtextobj.innerHTML="&nbsp;" + (currentvoteidx + 1) + " of " + votecount + "&nbsp;";
	}

	this.getcurrentvotenumber = function() {
		return this.getvoteindex(this.activevote) + 1;
	}

	this.next = function() {
		this.movevote(1);
	}

	this.previous = function() {
		this.movevote(-1);
	}

	this.render = function() {
		var out = "<div class=\"votespanel\" id=\"" + this.getelementid('votes') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		out += "<div id=\"" + this.getelementid("votearea") + "\" class=\"vote\">";
		if (this.activevote && this.activevote.enabled) {
			out += this.activevote.render();
		} else {
			out += this.novotemessage;
		}
		out += "</div>";
		out += "<div id=\"" + this.getelementid("navigation") + "\" class=\"navigation\" style=\"display:" + ((this.votelist.length>1)?"block":"none") + ";\">";
		out += "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">";
		out += "<tr>";
		out += "<td><img id=\"" + this.getelementid("navprevious") + "\" align=\"absmiddle\" src=\"" + imagepath + "/previoussmall.gif\" width=\"21\" height=\"21\" border=\"0\" onclick=\"callpanel(" + this.uid + ",'previous()');\"></td>";
			out += "<td><span id=\"" + this.getelementid("navtext") + "\">&nbsp;" + this.getcurrentvotenumber() + " of " + this.votelist.length + "&nbsp;</span></td>";
			out += "<td><img id=\"" + this.getelementid("navnext") + "\" align=\"absmiddle\" src=\"" + imagepath + "/nextsmall.gif\" width=\"21\" height=\"21\" border=\"0\" onclick=\"callpanel(" + this.uid + ",'next()');\"></td>";
		out += "</tr>";
		out += "</table>";
		out += "</div>";
		out += "</div>";
		return out;
	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(false);
	}
}

function btquestions(assetid) {
	this.assetid = assetid;
	this.onchange = null;
	this.className = "btquestions";
	this.uid = panels.register(this);
	this.title = "Your Questions";
	this.introtext = "Please type your Question and then click submit";
	this.nametext = "Please type your Name";
	this.username = "";
	this.responsetext = "Thankyou for your question.";
	this.questiontext = "";
	this.posturl = "../mod/post_question.php";
	this.email = "";

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.getquestiontext = function() {
		var questiontextobj = document.getElementById("qu" + this.uid + "questiontext");
		return (questiontextobj)?questiontextobj.value:"";
	}

	this.getusername = function() {
		var usernameobj = document.getElementById("qu" + this.uid + "username");
		return (usernameobj)?usernameobj.value:"";
	}

	this.setusername = function(username) {
		this.username = username;
		var usernameobj = this.getelement("username");
		if (usernameobj) usernameobj.value = this.username;
	}

	this.setquestiontext = function(text) {
		this.questiontext = text;
		var questiontextobj = this.getelement("questiontext");
		if (questiontextobj) questiontextobj.value = this.questiontext;
	}

	this.setintrotext = function(text) {
		this.introtext = text;
	}

	this.setresponsetext = function(text) {
		this.responsetext = text;
	}

	this.setemail = function(text) {
		this.email = text;
		if (rtobj = this.getelement("email")) {
			rtobj.value = this.email;
		}
	}

	this.submit = function() {
		var formobj = this.getelement('form');
		var qt = this.getelement('questiontext');
		if(qt.value.length > 1700){
			alert('Your question is too long and may not be sent!');			
			return;
		}
		if (formobj) {
			formobj.submit();
			writedebug("Question form submitted");
		}
		alert(this.responsetext);
		this.setquestiontext("");
	}

	this.render = function() {
		var out= "<div class=\"questionspanel\" id=\"" + this.getelementid('questions') + "\">";
		out += (this.title!="")?"<h1>" + this.title + "</h1>":"";
		out += "<form id=\"" + this.getelementid("form") + "\" method=\"get\" action=\"" + this.posturl + "\" target=\"" + this.getelementid("hiddenframe") + "\">";
		out += "<input name=\"email\" type=\"hidden\" id=\"" + this.getelementid("admineamil") + "\" value=\"" + this.email + "\" />";
		out += "<input name=\"status\" type=\"hidden\" id=\"" + this.getelementid("commstatus") + "\" value=\"" + communication.status + "\" />";
		out += "<input name=\"communication_id\" type=\"hidden\" id=\"qu" + this.uid + "commid\" value=\"" + communication.id + "\" />";
		out += "<div class=\"helptext\" id=\"" + this.getelementid("introtext") + "\">" + this.introtext + "</div>";
		out += "<textarea name=\"question\" id=\"" + this.getelementid("questiontext") + "\">" + this.questiontext + "</textarea>";
		out += "<br/><br/>";
		out += "<div class=\"helptext\">" + this.nametext + "</div>";
		out += "<input class=\"sltext\" name=\"username\" type=\"text\" id=\"" + this.getelementid("username") + "\" value=\"" + this.username + "\">";
		out += "<br/><br/>";
		out += drawimagebutton(this.getelementid('submit'),"Submit","callpanel(" + this.uid + ",'submit()')");
		out += "</form>";
		out += "<iframe id=\"" + this.getelementid("hiddenframe") + "\" name=\"" + this.getelementid("hiddenframe") + "\" class=\"debugpostframe\"></iframe>";
		out += "</div>";
		return out;
	}

	this.refresh = function() {

	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}

	this.getElementUID = function(id) {
		return this.className + this.uid + id;
	}
}

function bttext() {
	this.onchange = null;
	this.content = null;
	this.className = "bttext";
	this.uid = panels.register(this);
	this.panelid = "text" + this.uid;

	this.getelementid = function(name) {
		return this.className + this.uid + name;
	}

	this.getelement = function(name) {
		return document.getElementById(this.getelementid(name));
	}

	this.settitle = function(text) {
		this.title = text;
		var titleobj = this.getelement("title");
		if (titleobj) titleobj.value = this.title;
	}

	this.setcontent = function(content) {
		this.content = content;
	}

	this.render = function() {
		return "<div id =\"" + this.panelid + "\" class=\"textpanel\">" + this.content + "</div>";
	}

	this.refresh = function() {

	}

	this.contentchanged = function() {
		if (this.parentobject) this.parentobject.contentchanged(true);
	}
}

function setStyle(obj, property, value) {
	if (!obj) return;
	if (!obj.style) return;
	var styleObj = obj.style;
	//if (!styleObj[property]) return;
	//if (styleObj) styleObj[property] = value;
	try {
		eval("obj.style." + property + "=value");
	}
	catch(e) {
	}
}

function formatms(timeseconds) {
	var totalseconds = Math.floor(timeseconds);
	if (timeseconds >0) {
		hours = ((totalseconds/3600)>1) ? Math.floor(totalseconds/3600) + ":" : "";
		minutes = padstring(Math.floor((totalseconds%3600)/60));
		seconds = padstring(Math.floor(totalseconds%60));
		return hours + minutes + ":" + seconds;
	}
	return "00:00";
}

function padstring(instring) {
	if (instring.slice) {
		return ('00' + instring).slice(-2);
	} else {
		instring = '' + instring;
		while (instring.length < 2) {
			instring = '0' + instring;
		}
		return instring;
	}
}

function goURL(daURL) {
	if (window.location.replace) {
		window.location.replace(daURL);
	} else {
		window.location = daURL;
	}
}

function openFeatureWindow(theURL,winName,features) { //v2.0
	window.open(theURL,winName);
	document.MM_returnValue = false;
}

function openPopWinOnce(windowname, theURL, winwidth, winheight) {
	if (!getcookie(windowname + "pop")) {
		var winleft = (screen.width - winwidth) / 2;
		var wintop = (screen.height - winheight) / 2;
		features = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,left=' + winleft + ',top=' + wintop + ',width=' + winwidth + ',height=' + winheight;
		window.open(theURL,windowname,features);
		setcookie(windowname + "pop","1",1);
	}
}

function getexpirydate(nodays) {
	var UTCstring;
	Today = new Date();
	nomilli = Date.parse(Today);
	Today.setTime(nomilli + nodays*24*60*60*1000);
	UTCstring = Today.toUTCString();
	return UTCstring;
}

function setcookie(name,value,duration) {
	document.cookie = name + "=" + escape(value) + ";EXPIRES=" + getexpirydate(duration);
}

function getcookie(name) {
	var oCookies = document.cookie;
	var index = oCookies.indexOf(name + "=");
	if (index == -1) return null;
	index = oCookies.indexOf("=", index) + 1;
	var endstr = oCookies.indexOf(";", index);
	if (endstr == -1) endstr = oCookies.length; // last character
	return unescape(oCookies.substring(index, endstr));
}

function resetform(formname) {
	formObj = document.getElementById("form" + formname);
	if (formObj) formObj.reset();
}

function refreshscript(scriptid,filepath) {
	var scriptTag = document.getElementById(scriptid);
	if (scriptTag) {
		scriptTag.src = filepath;
		return;
	}
	var head = document.getElementsByTagName('head').item(0)
	script = document.createElement('script');
	script.src = filepath;
	script.type = 'text/javascript';
	script.id = scriptid;
	head.appendChild(script);
}

function writepanelcontent(panelid,htmlcontent) {
	panelObj = document.getElementById(panelid);
	if (panelObj) {
		panelObj.innerHTML = htmlcontent;
	}
}

function setInnerHTML(id,html) {
	var obj = document.getElementById(id);
	if (obj) obj.innerHTML = html;
}

function displayobject(obj,show) {
	if (obj) {
		obj.style.display=(show)?'block':'none';
	}
}

function setslidebyindex(index) {
	if (slides) {
		if (slides.showbyindex) slides.showbyindex(index);
	}
}

function pagerefresh() {
	window.location.href = unescape(window.location.pathname);
}

function loadpage(url) {
	window.location.href = url;
}



function handlescriptcommand(sType,sParam) {
	if (!media.live) return;
	req = new String(sParam);
	pos = req.indexOf(" ");
	com = req.substring(0, pos);
	com = com.toLowerCase();
	arg = req.substring(pos + 1, req.length);
	writedebug("Script command : " + sType + " - " + sParam + " - " + arg);
	switch (com) {
		case "slide" :
			slides.show(arg);
		break;

		case "vote" :
			resultsarray = arg.split(',');
			votealias = resultsarray.shift();
			votestatus = resultsarray.shift();
			votesupdate(votealias,votestatus,resultsarray);
		break;

		case "slideindex" :
			setslidebyindex(parseInt(arg,10));
		break;

		case "tabshow" :
			if (tabs) tabs.show(arg);
		break;

		case "tabhighlight" :
			if (tabs) tabs.highlite(arg,true);
		break;

		case "tabhighlightoff" :
			if (tabs) tabs.highlite(arg,false);
		break;

		case "closewindow" :
			self.close();
		break;

		case "refresh" :
			pagerefresh();
		break;

		case "url" :
			pageload(arg);
		break;

		default:
			writedebug("Ignored (" + sType + ") : " + " " + sParam);
		break;
	}
}
var redirected = false ;
function pageload(url,timeout) {
	if (!redirected) {
		if (!timeout) timeout=3000;
		setTimeout('location.href="' + url + '"',timeout);
		redirected = true;
	}
}

function loadheader() {
	return;
	switch(media.mediatype) {
		case "WIMP" :
			document.writeln("<scr"+"ipt type=\"text/javascript\" src=\"" + scriptpath + "/mswimp.js\"></scr"+"ipt>");
		break;

		case "QUICKTIME" :
			document.writeln("<scr"+"ipt type=\"text/javascript\" src=\"" + scriptpath + "/quicktime.js\"></scr"+"ipt>");
		break;

		case "REAL" :
			document.writeln("<scr"+"ipt type=\"text/javascript\" src=\"" + scriptpath + "/real.js\"></scr"+"ipt>");
		break;

		case "STREAMLESS" :
			document.writeln("<scr"+"ipt type=\"text/javascript\" src=\"" + scriptpath + "/streamless.js\"></scr"+"ipt>");
		break;

		default :
			alert("Unsupported Media Format");
		break;
	}
	document.title = (communication)?communication.title:"BrightTALK Communication";
}

var tu_timeout = 0;
function sendtimeupdates() {
	media.recordplayedtime();
	if(typeof tu_timeout == "undefined" || tu_timeout==0)
		tu_timeout = 60000;
	setTimeout("sendtimeupdates()", tu_timeout);
}

function checkctrlkeys(e) {
	var keyevent = (window.event)?window.event:e;
	if (keyevent.shiftKey	&& keyevent.ctrlKey) {
		var keycode = (window.event) ? keyevent.keyCode : keyevent.which - 64;
		switch (keycode) {
			case 20 : if (tabs) tabs.nexttab(); break;
			case 24 : if (window.runtestcode) runtestcode(); break;
			case 25 : toggledebug(); break;
		}
	}
}

function initialise() {
	if (browserdata) {
		var d = new Date();
		var imgobj = new Image;
		imgobj.src = ("../mod/update_time.php?viewID=" + communication.viewingid + "&" + browserdata + "&t=" + d.getTime());
	}
	communication.pollforupdates();
	sendtimeupdates();
	slides.preload();
	document.onkeypress = checkctrlkeys;
	initialised = true;
}

window.onload = initialise;
window.onbeforeunload = media.recordplayedtime;

