
// Copyright (c) 2003 Sonic Foundry, Inc. and Sonic Foundry 
// Media Systems, Inc. Neither this code nor any portion 
// thereof may be reproduced, altered, or otherwise changed, 
// distributed or copied, without the express written 
// permission of Sonic Foundry.  
// All rights reserved.

Function.prototype.Inherits = function(parent)
{
	this.prototype = new parent();
	this.prototype.constructor = this;
}

Object.prototype.Inherits = function(parent)
{
	if( arguments.length > 1 )
	{
		var args = Array.prototype.slice.call(arguments, 1);
		parent.apply(this, args);
	}
	else
	{
		parent.call(this);
	}
}

function AttachEvent(obj, eventName, handler) 
{
	if ( document.attachEvent ) 
	{
		obj.attachEvent(eventName, handler);	// MSIE only, event names always start with "on" (onload, onerror, etc)
	} 
	else if ( document.addEventListener ) 
	{
		if (eventName.substring(0, 2) == "on")
		{
			eventName == eventName.substring(2, eventName.length);
		}
		
		obj.addEventListener(eventName, handler, false);	// Mozilla only, parse leading "on" off of event names (load, error, etc)
	} 
	else 
	{
		eval(obj.id + "." + eventName + " = " + handler);
	}
}

function DetachEvent(obj, eventName, handler) 
{
	if ( document.removeEventListener ) 
	{
		obj.removeEventListener(eventName, handler, false);	// Mozilla only
	} 
	else if ( document.detachEvent ) 
	{
		obj.detachEvent(eventName, handler);	// MSIE only
	} 
	else 
	{
		eval(obj.id + "." + eventName + " = ''");
	}
}

// BEGINFILE SfDebug.js --------------------------------------------------------------------------->

function SfDebug(){}
	SfDebug.ErrAlert= -1;
	SfDebug.ErrMsgCritical=0;
	SfDebug.ErrMsgSubCritical=1;
	SfDebug.Information=2;
	SfDebug.Debugging=3;
	SfDebug.Verbose=4;
	SfDebug.DisableOutput=false;


	SfDebug.wndDebug = null;
	SfDebug.DebugLevel=SfDebug.ErrAlert; // change to this when moving to production!!!
	//SfDebug.DebugLevel=SfDebug.Information;
	//SfDebug.DebugLevel=SfDebug.Verbose;

	SfDebug.FindHome=function()
	{
		return self;
		var Mother;
		
		if (window.top && !window.top.closed)
		{
			Mother=window.top;
		}
		else
			Mother=window;
		
		while (Mother.opener)
		{
			if (Mother.opener.closed)
				return Mother;
				
			Mother=Mother.opener;
			
			if (Mother.top && !Mother.top.closed)
				Mother=Mother.top;
		}
		
		return Mother;
	}

	SfDebug.ShowWindow=function()
	{
		var Home=SfDebug.FindHome();
		
		if ( (!Home.SfDebug.wndDebug || Home.SfDebug.wndDebug.closed) )
		{
			SfDebug.wndDebug = Home.SfDebug.wndDebug = window.open(Util.GetDocumentBase()+ "/Popups/Debug/DebugFrame.htm","SfDebug","width=800,height=400,resizable,scrollbars");
		}
		else
		{
			SfDebug.wndDebug = Home.SfDebug.wndDebug;
		}
	}
		
	SfDebug.DPF=function(Level,strMsg)
	{
		var fDisplayDPF=false;
		
		if (Level==SfDebug.ErrAlert)
		{
			alert(strMsg);
		}
		else
		{
			if (Level<=SfDebug.DebugLevel)
				fDisplayDPF=true;

			if (fDisplayDPF)
			{
				SfDebug.ShowWindow();
			
				var Name;
				if (!window.name || window.name=="")
					Name="Unnamed Window";
				else
					Name=window.name;
					
				// might fail if the debug window hasn't completely loaded yet
				try {
					SfDebug.wndDebug.frames["FrameDebugOutput"].document.getElementById("OutputDiv").innerHTML += (Name+":"+strMsg+"<br>\r\n");
				} catch (e) {
					window.setTimeout("SfDebug.DPF('" + Level + "', '" + strMsg + "')", 1000);
					return;	
				}
			}
		}
	}

// ENDFILE SfDebug.js ----------------------------------------------------------------------------->
// BEGINFILE SfKernel.js -------------------------------------------------------------------------->

//var m_kernelDebugLevel = SfDebug.Information;
var m_kernelDebugLevel = SfDebug.Verbose;
var m_maxTimes = 100; // how many times to wait before bailing out (to prevent deadlocks)

// multiple on load handler.. allows multiple scripts to register on load handlers

function SfOnLoad(){}
	SfOnLoad.LoadHandlers = new Array();
	SfOnLoad.AddHandler = function (fn)
	{
		KernelDebug("AddHandler called, function: " + fn);
		
		var length = SfOnLoad.LoadHandlers.length;
		SfOnLoad.LoadHandlers[length] = new Object();
		SfOnLoad.LoadHandlers[length].ToExecute = fn;
		SfOnLoad.LoadHandlers[length].Dependencies = new Array();
		
		var i;
		for (i=1; i<arguments.length; ++i)
		{
			SfOnLoad.LoadHandlers[length].Dependencies[i-1] = arguments[i];
		}
	}

	SfOnLoad.RunHandlers=function()
	{
		KernelDebug("Running OnLoadHandlers");
		for (var i=0;i<SfOnLoad.LoadHandlers.length;i++)
		{
			var loadHandler = SfOnLoad.LoadHandlers[i];
			var input = new Array();
			input[0] = Number(-1);
			input[1] = loadHandler.ToExecute;
			var length = loadHandler.Dependencies.length;
			for (var j=0; j<length; ++j)
			{
				input[j+2] = loadHandler.Dependencies[j];
			}
			var executeString = SfOnLoad.ConvertRunOnDependencyToString(input);
			eval (executeString);
		}
		KernelDebug("Done running OnLoadHandlers");
	}


	SfOnLoad.RunOnDependency=function(numTimes, toExecute) //, dep1, dep2
	{
		KernelDebug("Running: " + SfOnLoad.ConvertRunOnDependencyToString(arguments));
		if (numTimes >= m_maxTimes)
		{
			SfDebug.DPF(SfDebug.ErrMsgCritical, "timed out waiting for dependencies: for function: " + toExecute); 
			return "";
		}
		
		// length of dependencies
		var length = arguments.length - 2;
		var areaManager = GetAreaManager();
		if (!areaManager)
		{
			KernelDebug("could not find areamanager");
			return;
		}
		var dependenciesSatisfied = true;
		for (var i=0; i<length; ++i)
		{
			var dependency = arguments[i+2];
			if (!areaManager.GetArea(dependency))
			{
				dependenciesSatisfied = false;  
				setTimeout(SfOnLoad.ConvertRunOnDependencyToString(arguments), 500);
				break;
			}
		}
		if (dependenciesSatisfied)
		{
			eval(toExecute);
		}

		return "";
	}

	// arguments[0] to this function is 
	// is the same as arguments withing the
	// function SfOnLoad.RunOnDependency
	SfOnLoad.ConvertRunOnDependencyToString = function()
	{
		var input = arguments[0]; // same as arguments for SfOnLoad.RunOnDependency

		var numTimes = Number(input[0]);
		var toExecute = input[1];
		var retVal = "SfOnLoad.RunOnDependency(" + (++numTimes) + ", '" + toExecute + "'";
		
		var length = input.length - 2;
		var i;
		for (i=0; i<length; ++i)
		{
			retVal += ", '" + input[i+2] + "'";
		}	
		retVal += ")";
		return retVal;
	}

	// Call the following with your function as the argument
	//SfOnLoad.AddHandler("onLoadHandler()");

function SfOnUnLoad(){}

	SfOnUnLoad.Handlers = new Array();
	SfOnUnLoad.AddHandler = function(toExecute)
	{
		var length = SfOnUnLoad.Handlers.length;
		SfOnUnLoad.Handlers[length] = toExecute;
	}
	SfOnUnLoad.RunHandlers = function()
	{
		var length = SfOnUnLoad.Handlers.length;
		var i;
		for (i=0; i<length; ++i)
		{
			eval(SfOnUnLoad.Handlers[i]);
		}	
	}

window.onunload = SfOnUnLoad.RunHandlers;
window.onload = SfOnLoad.RunHandlers;

// Safe Browser Event functions.. maps DOM2 to IE model
function SfBrowserEvent()
{
}

SfBrowserEvent.GetEvent=function(evt)
{
	if (evt)
	{
		return evt;
	}
	else
	{
		return window.event;
	}
}

SfBrowserEvent.EventNameFromDOM2 = function(eventName)
{
	switch(eventName)
	{
		case "mousemove":
		case "mouseup":
		case "mousedown":
		case "mouseover":
		case "mouseout":
			return "on"+eventName;
	}
	
	return eventName;
}

SfBrowserEvent.Attach = function(eventName, func)
{
	if (document.addEventListener)
	{
		document.addEventListener(eventName, func, true);
	}
	else if (document.attachEvent)
	{
		eventName = SfBrowserEvent.EventNameFromDOM2(eventName);
		document.attachEvent(eventName, func);
	}
	else
	{
		SfDebug.DPF(SfDebug.ErrMsgCritical, "Couldn't attach to " + eventName);
	}
}

SfBrowserEvent.Detach = function(eventName, func)
{
	if (document.removeEventListener)
	{
		document.removeEventListener(eventName, func, true);
	}
	else if (document.detachEvent)
	{
		eventName = SfBrowserEvent.EventNameFromDOM2(eventName);
		document.detachEvent(eventName, func);
	}
}

SfBrowserEvent.StopPropagation = function(evt)
{
	if (evt.stopPropagation)
	{
		evt.stopPropagation();
	}
	else
	{
		evt.cancelBubble=true;
	}
}

SfBrowserEvent.PreventDefault = function(evt)
{
	if (evt.preventDefault)
	{
		evt.preventDefault();
	}
	else
	{
		evt.returnValue = false;
	}
}


// Safe Browser DOM functions.. 
function SfStyleAttributeType(){}
SfStyleAttributeType.Float = "float";
SfStyleAttributeType.Width = "width";
SfStyleAttributeType.Position = "position";
SfStyleAttributeType.Top = "top";
SfStyleAttributeType.Left = "left";
SfStyleAttributeType.ZIndex = "zIndex";

function SfDOM(){}
	SfDOM.SetText = function(element, text)
	{
		var firstChild = element.childNodes[0];
		var newNode = document.createTextNode(text);
		if (firstChild)
		{
			element.replaceChild(newNode, firstChild);
		}
		else
		{
			element.appendChild(newNode);
		}
	}
	
	SfDOM.SetCssText=function(element, cssText) 
	{
		if ( MainHelper.PlayerDetect.SystemInfo.Browser.Type == BrowserType.InternetExplorer ) 
		{
			element.style.cssText = cssText;
		} 
		else 
		{
			element.setAttribute("style", cssText);
		}
	}

	SfDOM.SetStyleAttribute = function(element, attributeType, val)
	{
		switch (attributeType)
		{
			case SfStyleAttributeType.Float:
				SfDOM.SetStyleAttributeFloat(element, val);
				break;
			default:
				eval ("element.style." + attributeType + " = '" + val + "';");
				break;
		}
	}
	
	SfDOM.SetStyleAttributeFloat = function(element, val)
	{
		if (MainHelper.PlayerDetect.SystemInfo.Browser.Type == BrowserType.InternetExplorer)
		{
			element.style.styleFloat = val;
		}
		else
		{
			element.style.cssFloat = val;
		}
	}
	
	SfDOM.SetToolTip=function(element, tooltip)
	{
		element.setAttribute("title", tooltip);
		element.setAttribute("alt", tooltip);
	}

	SfDOM.FindElementFromID=function(Parent,id)
	{
		return Parent.getElementById(id);
		
		var children = Parent.childNodes;
		var element=null;
	 
		if (Parent.id==id)
		{
			return Parent;
		}
	   
		for( var i=0;i<children.length;i++)
		{
			element=SfDOM.FindElementFromID(children[i],id);
			if (element)
			{
				return element;
			}
		}
	    
		return element;

	}

	SfDOM.FindElementFromName = function(Parent, name)
	{
		return Parent.getElementsByName(name)[0];
		
		var children = Parent.childNodes;
		var element=null;
	 
		if (Parent.name==name)
		{
			return Parent;
		}
	   
		for( var i=0;i<children.length;i++)
		{
			element=SfDOM.FindElementFromName(children[i],name);
			if (element)
			{
				return element;
			}
		}
	    
		return element;

	}

function AreaNames(){}
AreaNames.Global = "Global";
AreaNames.CommandBarArea = "CommandBarArea";
AreaNames.CurrentSlideArea = "CurrentSlideArea";
AreaNames.SlideSorterArea = "SlideSorterArea";
AreaNames.PlayerArea = "PlayerArea";
AreaNames.FullSizeSlideArea = "FullSizeSlideArea";
AreaNames.PresentationCardArea = "PresentationCardArea";
AreaNames.PreviewSlideArea = "PreviewSlideArea";

function GetAreaManager()
{
	var areaManager = null;
	
	if (self.AreaManagerInstance)
	{
		// not in popups
		areaManager = self.AreaManagerInstance;
	}
	else
	{
		// in popup
		try
		{
			// we have to do a try because even checking for
			// it causes an exception
			areaManager = opener.AreaManagerInstance;
		}
		catch (ex)
		{
			areaManager = null;
		}
	}
	return areaManager;
}

function AreaManager()
{
	var Areas;
	this.Areas = new Array();
	
	this.AddArea = function(name, areaObject)
	{
		KernelDebug("Added area: " + name);
		this.Areas.length++;
		this.Areas[name] = areaObject;
	}
	
	this.RemoveArea = function(name)
	{
		var area = this.Areas[name];
		if (!area)
		{
			SfDebug.DPF(SfDebug.Information, "Area: " + name + " is not present");
			return;
		}
		this.Areas[name] = null;
	}
	
	this.ShowAreas = function()
	{
		SfDebug.DPF(SfDebug.Information, "ShowAreas called");
		for (var areaName in this.Areas)
		{
			SfDebug.DPF(SfDebug.Information, "AreaName: " + areaName + ", area: " + this.Areas[areaName]);
		}
		SfDebug.DPF(SfDebug.Information, "ShowAreas ended");
	}
	
	this.GetArea = function(name)
	{
		var area = this.Areas[name];
		if (!area)
		{
			SfDebug.DPF(SfDebug.Verbose, "Area: " + name + " not found in AreaManager");
		}
		return area;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////  
function SfTimedEvent() {}
	SfTimedEvent.nextID=0;
	SfTimedEvent.hashReflectInfo=new Array();

	SfTimedEvent.ReflectInfo = function(fnReflect,objArgs)
	{
		this.fn=fnReflect;
		this.obj=objArgs;
	}

	SfTimedEvent.setTimeOut=function(fnCallBack,time,objParams)
	{
		var ID="sftp"+SfTimedEvent.nextID;
	    
		SfTimedEvent.nextID++;
	    
		SfTimedEvent.nextID=SfTimedEvent.nextID%64;  // only allow 64 events queued up
	    
		SfTimedEvent.hashReflectInfo[ID]=new SfTimedEvent.ReflectInfo(fnCallBack,objParams);
	    
		setTimeout('SfTimedEvent.ReflectTimeOut("'+ID+'");',time);
	}

	SfTimedEvent.ReflectTimeOut=function(ID)
	{

		var rfi;
	    
		rfi=SfTimedEvent.hashReflectInfo[ID];
		SfTimedEvent.hashReflectInfo[ID]=null;
	       
		if (rfi)
		{
			var method = rfi.fn;
			if (!method)
			{
				return;
			}
			var args = rfi.obj;
			var invokee = args.invokee;
			if (args && invokee)
			{
				method.call(invokee, args);
			}
			else
			{
				method(args);
			}
		}
	}

////////////////////////////////////////////////////////////////////////////////////////// 

function SfRequestVariables(){}
SfRequestVariables.PresentationExperienceID = "peid"; //!! must be in sync with RequestVariableNames.PresentationExperienceID
SfRequestVariables.PresentationID = "pid";
SfRequestVariables.EventID = "eventid";
SfRequestVariables.MediaTicketId = "mediaid";
SfRequestVariables.MetaDataID = "metaDataID";
SfRequestVariables.PollID = "pollID";
SfRequestVariables.PollShowType = "pollShowType";
SfRequestVariables.ViewerMode = "mode";
SfRequestVariables.ViewerModeDefault = "Default";
SfRequestVariables.PlayerType = "playerType";
SfRequestVariables.SlideNumber = "slideNum";
SfRequestVariables.PlayFrom = "playFrom";
SfRequestVariables.ShouldResize = "shouldResize";
SfRequestVariables.EndVideo = "endVideo";
SfRequestVariables.IsLive = "isLive";
SfRequestVariables.UserTicketId = "ticketId";
SfRequestVariables.WindowLoc = "wndLoc";
SfRequestVariables.OverridePort25PluginInstall = "overridePort25PluginInstall";
/// Enums

function KernelDebug(str)
{
	SfDebug.DPF(m_kernelDebugLevel, "SfKernel: " + str);
}

//OptionsStuff
var OptionType =
{
	ThumbNailsPerPage : 0,
	ShowEvery: 1	
}


// ENDFILE SfKernel.js ------------------------------------------------------------------------------------>

// BEGINFILE SfEvent.js ----------------------------------------------------------------------------------->
//
// SfEvent
//
// An SfEvent is a multicast event
// When an Event is invoked via the Send or Post method
// all SfEventHandler Objects which have registered on this event will be called via
// their OnEvent handler.
//
// To add a new Event Handler call AddHandler() with the handler object
// you want to be called whenever an event is Sent or Posted
//
// To remove a handler call RemoveHandler()
//
// To invoke an event call Send(obj) where obj is the argument wrapper for the event
// this will immediately call all handlers
//
// To delay invoke an event call Post(obj) this will delay execution of the call chain
// until the next free javascript slice
//
//

var EventDebugLevel=SfDebug.Verbose;


function SfEventReflectObj(objEvent,objArgs)
{
	this.ev=objEvent;
	this.args=objArgs;
}

function SfEvent(type)
{
	// initialize the member variables for this instance

	var m_Handlers;
	var Type;
	
	
	this.Type=type;
	this.m_Handlers = new Array();
	
	this.toString = function()
	{
		return "[SfEvent: "+this.Type+"]";
	}
	
	this.GetActiveCount = function()
	{
		var ActiveCount=0;
		
		for (i=0; i < this.m_Handlers.length; i++) 
		{
			if (this.m_Handlers[i] != null)
			{
				ActiveCount++;
			}
		}
		
	  return ActiveCount;
	}
	
	this.AddHandler = function(Handler)
	{
		for (i=0; i < this.m_Handlers.length; i++) 
		{
			if (this.m_Handlers[i] == null)
			{
				this.m_Handlers[i]=Handler;
				SfDebug.DPF(EventDebugLevel,this.Type+" AddHandler "+Handler+" Count "+this.GetActiveCount());
				return;
			}
		}
		
	  this.m_Handlers = this.m_Handlers.concat(Handler);
	  
	  SfDebug.DPF(EventDebugLevel,this.Type+" AddHandler "+Handler+" Count "+this.GetActiveCount());
		
	}
	
	this.RemoveHandler = function(Handler)
	{
			
		var i;
		
		// note we only null this out and don't shrink this.. the reason being
		// that someone could remove themselves during the callback which can cause
		// all sorts of bad things if we shrink or reallocate the array
		
		for (i=0; i < this.m_Handlers.length; i++) 
		{
			if (this.m_Handlers[i] == Handler)
			{
				this.m_Handlers[i]=null;
				SfDebug.DPF(EventDebugLevel,this.Type+" RemoveHandler "+Handler+" Count "+this.GetActiveCount());
				return;
			}
		}
		
		SfDebug.DPF(EventDebugLevel,this.Type+" RemoveHandler FAIL "+Handler+" Count "+this.GetActiveCount());

	}

	this.Send = function(objArgs)
	{
		objArgs.Type = this.Type;
		
		if (window!=null)
		{
			objArgs.Source=window.name;
		}
			
		SfEvent.DoCallBacks(this,objArgs);
	}
	
	this.Post = function(objArgs)
	{
		objArgs.Type = this.Type;
		
		if (window!=null)
		{
			objArgs.Source=window.name;
		}
			
		rfo = new SfEventReflectObj(this, objArgs);
		
		SfTimedEvent.setTimeOut(this.ReflectedPost, 1, rfo);
	}
	
	this.ReflectedPost = function(rfo)
	{
		SfDebug.DPF(EventDebugLevel+1, "REFLECTED POST " + rfo.ev + " " + rfo.args);
		SfEvent.DoCallBacks(rfo.ev, rfo.args);
	}
}	
	SfEvent.DoCallBacks = function(objEvent, objArgs)
	{
 		var i;

	    SfDebug.DPF(EventDebugLevel+1,objEvent.Type+" Callback "+objEvent.GetActiveCount()+" Handlers for Event"+objArgs);
		
		for (i=0; i < objEvent.m_Handlers.length; i++) 
		{
			var handler = objEvent.m_Handlers[i];
			if (handler)
			{
				var container = handler.Container;
				var invokee = handler.Invokee;
				
				if (handler.Object)
				{
					handler.Method.call(handler.Object, objArgs);
				}
				else if (container)
				{
					eval(handler.Container + "." + handler.MethodName + "(objArgs)");
				}
				else if (invokee)
				{
					handler.OnEvent.call(invokee, objArgs);
				}
				else
				{
					handler.OnEvent(objArgs);
				}
			}
		}
		
		SfDebug.DPF(EventDebugLevel+1,"Callback completed on events");
	}




function SfEventHandler(name)
{
	// initialize the member variables for this instance
	var Name;
	
	//initialize class level variables
	this.Name = name;

	
	this.OnEvent = function(objArgs)
	{
		//default inplementation raises an alert, this method should be
		//subclassed to do something usefull
		alert('Handler.OnEvent was not implemented for Handler: ' +this+" "+objArgs); 
	}
	
	this.toString = function()
	{
		if (!this.Name)
			return "[Unnamed Handler]";
		else
			return "["+this.Name+"]";
	}

} //end SfEventHandler

function SfEventType(){}
SfEventType.Command = "evCommand";
SfEventType.Script = "evScript";
SfEventType.DataAvailable = "evDataAvailable";
SfEventType.SlideChanged = "evSlideChanged";
SfEventType.PlayerSetupComplete = "evPlayerSetupComplete";
SfEventType.PlayerStateChanged = "evPlayerStateChanged";
SfEventType.PlayerTimerUpdated = "evPlayerTimerUpdated";
SfEventType.PlayerPositionChanged = "evPlayerPositionChanged";
SfEventType.PlayerPlayStateChanged = "evPlayerPlayStateChanged";
SfEventType.SliderNotify = "evSliderNotify";
SfEventType.MediaLengthObtained = "evMediaLengthObtained";
SfEventType.VolumeInitialized = "evVolumeInitialized";
SfEventType.VolumeChanged = "evVolumeChanged";
SfEventType.PlayBegin = "evPlayBegin";

function SfEventArgs()
{
	// initialize the member variables for this instance
	var Source;
	var Type;

	this.toString = function()
	{
		return "[EVENT: "+this.Type+" SENDER: "+this.Source+"]";
	}
	
}//end SfEventArgs

function SfScriptCommandType(){}
SfScriptCommandType.EndPresentation =	"EndPresentation";
SfScriptCommandType.ShowSlide =			"ShowSlide";

ScriptEventArgs.prototype = new SfEventArgs();
ScriptEventArgs.prototype.constructor = ScriptEventArgs;
function ScriptEventArgs(command)
{
	// initialize the member variables for this instance

	var Command;
	
	if (arguments.length > 0)
	{
		this.Command = command;
	}
  
	this.toString = function()
	{
		return "[EVENT: "+this.Type+" SENDER: "+this.Source+" COMMAND: "+this.Command+"]";
	}

}//end ScriptEventArgs

function SfCommandType(){}
	SfCommandType.Unknown = "Unknown";
	SfCommandType.NavigateToSlide = "NavigateToSlide";
	SfCommandType.NavigateToChapter = "NavigateToChapter";
	SfCommandType.ShowTextSlideList = "ShowTextSlideList";
	SfCommandType.ShowInfo = "ShowInfo";
	SfCommandType.ShowExtraInfo = "ShowExtraInfo";
	SfCommandType.ShowChapterPoints = "ShowChapterPoints";
	SfCommandType.ShowSlideDescription = "ShowSlideDescription";
	// player commands
	SfCommandType.Play = "Play";
	SfCommandType.Pause = "Pause";
	SfCommandType.Stop = "Stop";
	SfCommandType.SetVolume = "SetVolume";
	SfCommandType.VolumeUp = "VolumeUp";
	SfCommandType.VolumeDown = "VolumeDown";
	SfCommandType.Mute = "Mute";
	SfCommandType.FullScreen = "FullScreen";

// extend SfEventArgs
CommandArgs.prototype = new SfEventArgs();
CommandArgs.prototype.constructor= CommandArgs;
function CommandArgs(command)
{
	// initialize the member variables for this instance

	var Command;
	
	if (arguments.length > 0)
	{
		this.Command = command;
	}
  
	this.toString = function()
	{
		return "[EVENT: "+this.Type+" SENDER: "+this.Source+" COMMAND: "+this.Command+"]";
	}

}//end CommandArgs

function SfSliderNotifyType(){}
SfSliderNotifyType.NewPosition = "NewPosition";
SfSliderNotifyType.DragPosition = "DragPosition";
SfSliderNotifyType.BeginDrag = "BeginDrag";
SfSliderNotifyType.EndDrag = "EndDrag";

// extend SfEventArgs
SliderArgs.prototype = new SfEventArgs();
SliderArgs.prototype.constructor= SliderArgs;
function SliderArgs(NotifyType)
{
	// initialize the member variables for this instance
	if (arguments.length > 0)
	{
		this.NotifyType = NotifyType;
	}
  
	this.toString = function()
	{
		return "[EVENT: "+this.Type+" SENDER: "+this.Source+" COMMAND: "+this.NotifyType+"]";
	}

}//end SliderArgs

// Volume stuff
function SfVolumeChangeType(){}
SfVolumeChangeType.VolumeUpDown = "VolumeUpDown";
SfVolumeChangeType.Muted = "Muted";
SfVolumeChangeType.UnMuted = "UnMuted";

VolumeChangedArgs.prototype = new SfEventArgs();
VolumeChangedArgs.prototype.constructor = VolumeChangedArgs;
function VolumeChangedArgs(volumeChangedType)
{
	this.ChangeType = volumeChangedType;
	this.VolumeIndex = 0;
	
	this.toString = function()
	{
		return "ChangeType: " + this.ChangeType + ", VolumeIndex: " + this.VolumeIndex;
	}
}
// end Volume Stuff

// ENDFILE SfEvent.js -------------------------------------------------------------------------------------->

// BEGINFILE PlayerDetect.js ------------------------------------------------------------------------------->

function PlayerType(){}
	PlayerType.WM64 = "WM64";
	PlayerType.WM64Lite = "WM64Lite";
	PlayerType.WM7 = "WM7";
	PlayerType.Port25 = "Port25";
	PlayerType.Unknown = "Unknown";


function PlayerDetect()
{
	this.PlayerType = null;
	
	this.SystemInfo = new SystemInfo();
	this.DefaultPlayerType = PlayerType.WM7;
	
	this.GetPlayerType = function()
	{
		if (this.PlayerType == null)
		{
			this.CreatePlayerType();
		}
		return this.PlayerType;
	}
	
	this.CreatePlayerType = function()
	{
		if (this.IsMac() || this.IsOpera() )
		{
			this.PlayerType = PlayerType.WM64Lite;
			return;
		}

		if (this.IsMozilla() == true)
		{
			this.SetMozillaPlayerType();
			return;
		}

		// Set Windows Player Type		
		if (this.HasWMP7())
		{
			this.PlayerType = PlayerType.WM7;
			return;
		}
		if (this.HasWMP64())
		{
			this.PlayerType = PlayerType.WM64;
			return;
		}
		
		SfDebug(SfDebug.ErrMsgCritical, 'defaulting to WM7 playertype');
		this.PlayerType = this.DefaultPlayerType;
	}
	
	this.SetMozillaPlayerType = function()
	{
		this.PlayerType = PlayerType.WM64Lite;
		
		if (IsPluginPresent() == true)
		{
			this.PlayerType = PlayerType.Port25;
			return;
		}

		function IsPluginPresent()
		{
			for	(var i=0; i<navigator.plugins.length; ++i)
			{
				var plugin = navigator.plugins[i];
				if (
					(plugin.name && plugin.name.indexOf("np-mswmp") > -1)
					||
					(plugin.description && plugin.description.indexOf("np-mswmp") > -1)
					)
				{
					return true;
				}
			}
			return false;
		}
	}
	
	this.IsMozilla = function()
	{
		return (this.SystemInfo.Browser.Type == BrowserType.Mozilla);
	}
	
	this.IsOpera = function()
	{
		return (this.SystemInfo.Browser.Type == BrowserType.Opera);
	}
	
	this.IsMac = function()
	{	
		return (this.SystemInfo.Browser.OSGeneric == OSTypeGeneric.Macintosh);
	}

	this.HasWMP7 = function()
	{	
		try
		{
			new ActiveXObject("WMPlayer.OCX.7");
			return true;
		}
		catch (ex)
		{
			return false;
		}
	}

	this.HasWMP64 = function()
	{	
		try
		{
			new ActiveXObject("MediaPlayer.MediaPlayer.1");
			return true;
		}
		catch (ex)
		{
			return false;
		}
	}
}

// ENDFILE PlayerDetect.js --------------------------------------------------------------------------------->

// BEGINFILE SystemInfo.js --------------------------------------------------------------------------------->

var BrowserType =
{
    Unknown:			0,
    InternetExplorer:	1,
    Mozilla:			2,
    AOL:				3,
    Opera:				4,
    WebTV:				5,
    OmniWeb:			6,  // apples osx browser
    Galeon:				7
}

var OSTypeGeneric=
{
	Unknown:	0,
	Windows:	1,
	Macintosh:	2,
	Unix:		3,
	OS2:		4
}

var OSTypeSpecific=
{
	Unknown:		0,
	Windows16:		1,
	Windows95:		2,
	Windows98:		3,
	WindowsME:		4,
	WindowsNT:		5,
	Windows2000:	6,
	WindowsXP:		7,
	OS2:			10,
	Sun:			11,
	Irix:			12,
	HPUX:			13,
	AIX:			14,
	DEC:			15,
	SCO:			16,
	VMS:			17,
	Linux:			18,
	Sinix:			19,
	Reliant:		20,
	FreeBSD:		21,
	OpenBSD:		22,
	NetBSD:			23,
	OtherBSD:		24,
	Unixware:		25,
	MPRAS:			26,
	x11:			27,
	Mac68k:			40,
	MacPPC:			41
}
	
function ScreenInfo()
{
	this.Width=640;
	this.Height=480;
	this.Depth=8;
	
	if (window.screen)
	{
		this.Width=window.screen.width;
		this.Height=window.screen.height;
		this.Depth=window.screen.colorDepth;
	}
}

function BrowserInfo(nav)
{
	this.Agent=nav.userAgent.toLowerCase();
	this.Platform="";
	if (nav.platform)
		this.Platform=nav.platform.toLowerCase();
	this.Application=nav.appName.toLowerCase();
	this.Version=nav.appVersion.toLowerCase();

	
	if (!BrowserInfo.prototype.ParseBrowserType)
	{
		BrowserInfo.prototype.ParseBrowserType=ParseBrowserType;
		BrowserInfo.prototype.ParseOS=ParseOS;
	}
	this.Type=BrowserType.Unknown;
	this.OSGeneric=OSTypeGeneric.Unknown;
	this.OSSpecific=OSTypeSpecific.Unknown;

	
	this.ParseBrowserType();
	this.ParseOS();
	

	this.VersionMajor=parseInt(this.Version);
	this.VersionMinor=parseFloat(this.Version);
	this.VersionMinor-=this.VersionMajor;
	this.VersionMinor=Math.round(this.VersionMinor*100);
	
	if (this.Type==BrowserType.InternetExplorer)
	{
		// all ie >4 report 4.0 need to fix this for ie
		var sub=this.Agent.slice(this.Agent.indexOf("msie ")+5);
		this.VersionMajor=parseInt(sub);
		this.VersionMinor=parseFloat(sub);
		this.VersionMinor-=this.VersionMajor;
		this.VersionMinor=Math.round(this.VersionMinor*100);
	}
	
	
	function ParseBrowserType()
	{
		if (this.Agent.indexOf("opera")>-1)
		{
			this.Type=BrowserType.Opera;
			return;
		}
			
		if (this.Agent.indexOf("msie")>-1)
		{
			this.Type=BrowserType.InternetExplorer;
			return;
		}
				
		if (this.Agent.indexOf("mozilla")>-1)
		{
			if (this.Agent.indexOf("compatible")<0)
			{
				this.Type=BrowserType.Mozilla;
				return;
			}
		}
		
		if (this.Agent.indexOf("aol")>-1)
		{
			this.Type=BrowserType.AOL;
			return;
		}
		
		if (this.Agent.indexOf("webtv")>-1)
		{
			this.Type=BrowserType.WebTV;
			return;
		}
		
		if (this.Agent.indexOf("omniweb")>-1)
		{
			this.Type=BrowserType.OmniWeb;
			return;
		}
		
		if (this.Agent.indexOf("galeon")>-1)
		{
			this.Type=BrowserType.Galeon;
			return;
		}
	}
	
	function ParseOS()
	{
	
		if (this.Agent.indexOf("win")>-1)
		{
			this.OSGeneric=OSTypeGeneric.Windows;
			
			
			if (this.Agent.indexOf("nt 5.1")>-1)
			{
				this.OSSpecific=OSTypeSpecific.WindowsXP;
				return;
			
			}
			
			if (this.Agent.indexOf("nt 5")>-1)
			{
				this.OSSpecific=OSTypeSpecific.Windows2000;
				return;
			
			}
			
			if (this.Agent.indexOf("nt")>-1)
			{
				this.OSSpecific=OSTypeSpecific.WindowsNT;
				return;
			
			}
						
			if (this.Agent.indexOf("win 9x 4.90")>-1)
			{
				this.OSSpecific=OSTypeSpecific.WindowsME;
				return;
			
			}			
			
			if (this.Agent.indexOf("98")>-1)
			{
				this.OSSpecific=OSTypeSpecific.Windows98;
				return;
			
			}			
			
			if (this.Agent.indexOf("95")>-1)
			{
				this.OSSpecific=OSTypeSpecific.Windows95;
				return;
			}
			
			if (this.Agent.indexOf("16")>-1)
			{
				this.OSSpecific=OSTypeSpecific.Windows16;
				return;
			}
			
			return;
		}
		
		if (this.Agent.indexOf("mac")>-1)
		{
			this.OSGeneric=OSTypeGeneric.Macintosh;
			
			if ((this.Agent.indexOf("68k")>-1) || (this.Agent.indexOf("68000")>-1))
			{
				this.OSSpecific=OSTypeSpecific.Mac68K;
				return;
			}
			
			if ((this.Agent.indexOf("ppc")>-1) || (this.Agent.indexOf("powerpc")>-1))
			{
				this.OSSpecific=OSTypeSpecific.MacPPC;
				return;
			}
			
			return;
		}
		
		if (this.Agent.indexOf("os/2")>-1)
		{
			this.OSGeneric=OSTypeGeneric.OS2;
			this.OSSpecific=OSTypeSpecific.OS2;
			return;
		}
		
	}

}


function SystemInfo()
{
	this.Screen= new ScreenInfo();
	this.Browser= new BrowserInfo(navigator);
	this.m_debugLevel = 4;
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "SystemInfo: " + msg);
	}
}

// ENDFILE SystemInfo.js ---------------------------------------------------------------------------------->

// BEGINFILE Windows.js ----------------------------------------------------------------------------------->

function WindowHelper(){}
	WindowHelper.IsOpen = function (wnd)
	{
		if (!wnd)
		{
			return false;
		}
		if (wnd == null)
		{
			return false;
		}
		if (wnd.closed == true)
		{
			return false;
		}
		return true;
	}

	WindowHelper.CreateNamedPopup=function(popupName, name, width, height, scrollbars, resizeable)
	{
		return this.CreatePopup(GetPopupURL(popupName), name, width, height, scrollbars, resizeable);
	}

	WindowHelper.CreatePopup=function(sUrl,sName,nWidth,nHeight,fScrollbars,fResizeable)
	{
		// extra offset for mac
		var offsetX = 0;
		var offsetY = 0;

		nWidth=Math.floor(nWidth) + offsetX;
		nHeight=Math.floor(nHeight) + offsetY;

		var sFeatures = "width=" + nWidth + ",height=" + nHeight;
	       
		if (fScrollbars)
		{
			sFeatures += ",scrollbars=yes";
		}
		else
		{
			sFeatures += ",scrollbars=no";
		}
	        
		if (fResizeable)
		{
			sFeatures += ",resizable=yes";
		}
		else
		{
			sFeatures += ",resizable=no";
		}
	        
		var popup = window.open(sUrl,sName,sFeatures);
		this.Center(popup, nWidth, nHeight);
	    
		return popup;
	}

	WindowHelper.Center=function(wnd,nWidth,nHeight)
	{
		var posX = Math.round((screen.availWidth-nWidth)/2);
		var posY=  Math.round((screen.availHeight-nHeight)/2);
		wnd.moveTo(posX,posY);
	}

	WindowHelper.PopupHelp=function(sUrl,nWidth,nHeight)
	{
		window.popuphelp = this.CreatePopup(sUrl,"__help",nWidth,nHeight,true,true);
		WindowHelper.Center(window.popuphelp,nWidth,nHeight);
		window.popuphelp.focus();
	}

	WindowHelper.MaximizeOrCenter = function(wnd, width, height)
	{
		if (WindowHelper.IsWidthOrHeightGreater(width, height))
		{
			WindowHelper.Maximize(wnd);
		}
		else
		{
			WindowHelper.Center(wnd, width, height);
		}
	}

	WindowHelper.Maximize = function(wnd)
	{
		wnd.resizeTo(screen.availWidth, screen.availHeight);
		wnd.moveTo(0, 0);
	}

	WindowHelper.IsWidthOrHeightGreater = function(width, height)
	{
		var screenWidth = screen.availWidth;
		var screenHeight = screen.availHeight;
		
		SfDebug.DPF(SfDebug.Verbose, 
			"WindowHelper: width: " + width + 
			", height: " + height + 
			", screenWidth: " + screenWidth + 
			", screenHeight: " + screenHeight);
			
		if (width > screenWidth || height > screenHeight)
		{
			return true;
			
		}
		else
		{
			return false;
		}
	}

function PopupNames(){}
	PopupNames.Viewer = "Viewer";
	PopupNames.FullSize = "FullSize";
	PopupNames.Help = "Help";
	PopupNames.ShowPolls = "ShowPolls";
	PopupNames.Forum = "Forum";
	PopupNames.Options = "Options";
	PopupNames.PresentationDetails = "PresentationDetails";
	PopupNames.PreviewSlide = "PreviewSlide";

function GetPopupURL(popupName)
{
	if (!MainHelper)
	{
		return GetStandAloneURL(popupName);
	}
	if (MainHelper.Presentation.IsStandAlone == false)
	{
		return GetWebURL(popupName);
	}
	else
	{
		return GetStandAloneURL(popupName)
	}
}

function GetWebURL(popupName)
{
	switch (popupName)
	{
		case PopupNames.Help:
			return MainHelper.ViewerAppBaseURL + "/Popups/help/Overviewfullversion.htm";
		case PopupNames.ShowPolls:
			return MainHelper.ViewerAppBaseURL + "/Popups/Polls/PollList.aspx?" + SfRequestVariables.PresentationID + "="  +  MainHelper.Presentation.PresentationID;
		case PopupNames.Forum:
			return MainHelper.ViewerAppBaseURL + "/Popups/Forum/AddForum.aspx?" + SfRequestVariables.PresentationID + "=" + MainHelper.Presentation.PresentationID;
		case PopupNames.Options:
			return MainHelper.ViewerAppBaseURL + "/Popups/Options/ShowOptions.aspx";
		case PopupNames.PresentationDetails:
			var url = MainHelper.ViewerAppBaseURL + "/ShowPresentationDetails.aspx?" + SfRequestVariables.PresentationExperienceID + "=" + MainHelper.Presentation.PresentationExperienceID + "&" + SfRequestVariables.ViewerMode + "=" + SfRequestVariables.ViewerModeDefault;
			if (MainHelper.Presentation.UserTicketId != null)
			{
				url += "&" + SfRequestVariables.UserTicketId + "=" + MainHelper.Presentation.UserTicketId;
			}
			return url;
		case PopupNames.PreviewSlide:
			return MainHelper.ViewerAppBaseURL + "/PreviewSlide.aspx";
		case PopupNames.FullSize:
			var url = MainHelper.ViewerAppBaseURL + "/" + MainHelper.Presentation.FullSizePage;
			if (MainHelper.Presentation.UserTicketId != null)
			{
				url += "&" + SfRequestVariables.UserTicketId + "=" + MainHelper.Presentation.UserTicketId;
			}
			return url;
	}
}

function GetStandAloneURL(popupName)
{
	switch (popupName)
	{
		case PopupNames.Help:
			return "Popups/help/Overview.htm";
		case PopupNames.PreviewSlide:
			return "PreviewSlide.htm";
		default:
			return popupName + ".html";
	}
}


function StartViewer(url, viewerMode, shouldResize)
{
	var playerType = new PlayerDetect().GetPlayerType();
//	var playerType = PlayerType.WM64Lite;
//	var playerType = PlayerType.WM64;
//	var playerType = PlayerType.WM7;
	var playerWidth = 790;
	var playerHeight = 569;
	if (playerType == PlayerType.Unknown)
	{
		alert('You must have Windows Media 6.4 player or higher installed in your machine.');
		return;
	}
	
	WindowHelper.CreatePopup(url + 
		'&' + SfRequestVariables.PlayerType + '=' + playerType + 
		'&' + SfRequestVariables.ViewerMode + '=' + viewerMode +
		'&' + SfRequestVariables.ShouldResize + '=' + shouldResize,
		'Viewer', 
		playerWidth , 
		playerHeight , 
		false, 
		true);
}

// ENDFILE Windows.js ------------------------------------------------------------------------------------->

// BEGINFILE SfCookie.js ---------------------------------------------------------------------------------->

function SfCookie(cookieName,cookieDomain,cookiePath)
{
	var Name,Domain,Path;  // Member values

	this.Name = cookieName;
	this.Domain = cookieDomain;
	this.Path = cookiePath;

	// Member Functions below
	
	this.Set = function(value)
	{
	
		this.Value = value; // keep a copy
		
		var NewCookie = this.Name + "=" + escape(value) +
		((this.Path) ? "; path=" + this.Path : "") +
		((this.Domain) ? "; domain=" + this.Domain : "") +
		((this.Expires) ? "; expires=" + this.Expires.toGMTString() : "") +
		((this.Secure) ? "; secure" : "");
		
		document.cookie = NewCookie;
	}

	this.Get = function()
	{
		if (document.cookie)
		{
			begin = document.cookie.indexOf(this.Name+"=");
			if (begin != -1)
			{
				begin+=this.Name.length+1;
				end=document.cookie.indexOf(";",begin);
				if (end == -1)
					end = document.cookie.length;
				return unescape(document.cookie.substring(begin,end));
			}
		}
		return null;
	}

	this.Delete = function()
	{
		if (this.Get())
		{
			document.cookie = this.Name + "=" + 
			((this.Path) ? "; path=" + this.Path : "") +
			((this.Domain) ? "; domain=" + this.Domain : "") +
			";expires=Thu, 01-Jan-70 00:00:01 GMT";
		}
	}
	
	this.Persist = function()
	{
		// persist it for a year otherwise you can set your own value by setting
		// the Expires property 
		
		var now = new Date();
		
		this.Expires = new Date(now.getFullYear()+1, now.getMonth(),now.getDate());
		this.Set(this.Value);
	}
	
	this.PersistValue = function(val)
	{
		// persist it for a year otherwise you can set your own value by setting
		// the Expires property 
		
		var now = new Date();
		
		this.Expires = new Date(now.getFullYear()+1, now.getMonth(),now.getDate());
		this.Set(val);
	}
	
	this.SetBool = function(fTrue)
	{
		if (fTrue)
		{
			this.Set("true");
		}
		else
		{
			this.Set("false");
		}

	}
	
	this.GetBool = function()
	{
		var strTrue;
		
		strTrue = this.Get();
		
		if (strTrue != null)
		{
			if (strTrue=="true")
			{
				return true;
			}
		}
	
		return false;
	}
}




function SfCookieHome(path,domain)
{
	var Path,Domain;  // member values
		
	if (path)
		this.Path = path;
		
	if (domain)
		this.Domain = domain;
		
		
	this.NewCookie = function(name)
	{
		return new SfCookie(name,this.Path,this.Domain);
	}
	
}

// ENDFILE SfCookie.js ------------------------------------------------------------------------------------>

// BEGINFILE Util.js -------------------------------------------------------------------------------------->

function Util(){}

	// returns http://host/LiveViewer/ etc we need it because
	// for some reason mac player doesn't recognize relative path
	// remember last slash is included
	Util.GetDocumentBase = function()
	{
		if (typeof MainHelper == 'undefined')
		{
			MainHelper = opener.MainHelper;
		}
		return MainHelper.ViewerAppBaseURL;
	}
	
	// Generates a new psuedo random guid
	Util.GetGuid = function()
	{
		var guid = "";
		for (var i = 0; i < 32; i++)
		{
			guid += Math.floor(SfRandom.Next() * 16).toString(16) + (i == 7 || i == 11 || i == 15 || i == 19 ? "-" : "")
		}
		return guid;
	}

var CursorType = 
{
	Default:0,
	Hand:1
}

	Util.SetCursor = function(element, cursorType)
	{
		if (cursorType == CursorType.Default)
		{
			element.style.cursor = 'default';
		}
		else if (cursorType == CursorType.Hand)
		{
			try
			{
				element.style.cursor = 'pointer';
			}
			catch (e)
			{
				element.style.cursor = 'hand';
			}
		}
	}
	
	Util.GetInvokableFunction = function(obj, meth, par)
	{
		return (function()
		{
			meth.call(obj, par);
		});
	}

// ENDFILE Util.js ----------------------------------------------------------------------------------------->

// BEGINFILE SfRandom.js -------------------------------------------------------------------------------------->

// Static random number generator
// (an implementation of the Park-Miller algorithm, transcribed to js)
// This was necessary in order to defeat a bug found in Math.random() on Safari...
// It appears that in certain instances, Safari always starts with the same seed, yielding
// identical "random" results between sessions.  It's recommended to use this instead of
// Math.random() for cross platform consistency.
function SfRandom()
{
}
	// Set the seed to a user specified value.  Assumption: should preserve
	// the same random sequence in multiple runs given the same seed.
	SfRandom.SetSeed = function(newSeed)
	{
		SfRandom._seed = newSeed;
		
		// Reset other calculation values
		SfRandom._a = 48271;
		SfRandom._m = 2147483647;
		SfRandom._q = SfRandom._m / SfRandom._a;
		SfRandom._r = SfRandom._m % SfRandom._a;
		SfRandom._oneOverM = 1.0 / SfRandom._m;
	}
		
	// Get the next pseudo random number in the sequence
	SfRandom.Next = function()
	{
		var hi   = SfRandom._seed / SfRandom._q;
		var lo   = SfRandom._seed % SfRandom._q;
		var test = SfRandom._a * lo - SfRandom._r * hi;
		if (test > 0)
			SfRandom._seed = test;
		else
			SfRandom._seed = test + SfRandom._m;
		return (SfRandom._seed * SfRandom._oneOverM);
	}
	
	// generates a random number between min and max 
	// with a precision of accuracy decimal places
	SfRandom.Range = function(min, max, accuracy)
	{
		// get random number between min and max
		var number = SfRandom.Next()*(max-min) + min;
		return Math.round(number*Math.pow(10, accuracy))/Math.pow(10, accuracy);
	}
		
	SfRandom.SetSeedByTime = function(sessionId)
	{
		// note: flip some of the low order bits to get rid of near consecutive seeds
		var t = (new Date()).getTime();
		var b=12; var n=(t>>(b-1)); 
		for (var i=0; i<b; i++)
		{	n |= ((t >> i) & 1); n <<= 1;	}
		SfRandom.SetSeed(n>>1); // shift down into valid seed space
		SfRandom.Next(); // throw 1st out
	}

	SfRandom.SetSeedByTime();

// ENDFILE SfRandom.js ----------------------------------------------------------------------------------------->	

// BEGINFILE ImageCache.js --------------------------------------------------------------------------------->

function CachedImageStatus(){}
CachedImageStatus.Error = "Error";
CachedImageStatus.Complete = "Complete";
CachedImageStatus.Loading = "Loading";

// an array containing the images
function ImageCache(container)
{
	this.m_debugLevel = SfDebug.Verbose;
//	this.m_debugLevel = SfDebug.ErrAlert;
	this.Container = container;
	this.CachedImages = new Array();
	this.NumItemsToCache = 1;
 	
	this.AddImage = function(url, shouldDelayLoad)
	{
		if (shouldDelayLoad == true)
		{
			// random time between 3 and 5 seconds
			// it will get something like 3.123 * 1000 = 3123
			var randomTime = SfRandom.Range(3, 5, 3) * 1000;
			setTimeout(this.Container + '.Internal_AddImage("' + url + '")', randomTime);
		}
		else
		{	
			this.Internal_AddImage(url);
		}
	}
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "ImageCache: " + msg);
	}
	
	this.Internal_AddImage = function(url)
	{
		var length = this.CachedImages.length;
		var currentIndex = 0;
		if (length >= this.NumItemsToCache)
		{
			currentIndex = length-1;
		}
		else
		{
			currentIndex = length;
		}
		
		var cachedImage = new CachedImage(url, this.Container + ".CachedImages[" + currentIndex + "]");
		this.CachedImages[currentIndex] = cachedImage;
		cachedImage.Load();
	}
	
	this.FindInCache = function(url)
	{
		var i;
		for (i=0; i<this.CachedImages.length; ++i)
		{
			if (this.CachedImages[i].Source == url)
			{
				return this.CachedImages[i]; 
			}
		}
		return null;
	}
	
	function CachedImage(source, container)
	{
		this.Source = source;
		this.Container = container;
		this.Status = CachedImageStatus.Loading;
//		this.m_debugLevel = SfDebug.ErrAlert;
		this.m_debugLevel = SfDebug.Verbose;
		
		this.Load = function()
		{
			this.Debug("CachedImage load called");
			this.Img = new Image();
			this.Img.onerror = new Function("", this.Container + ".OnError()");
			this.Img.onload = new Function("", this.Container + ".OnLoad()");
			this.Img.src = this.Source;
		}
		
		this.OnError = function()
		{
			this.Debug("OnError called");
			this.Status = CachedImageStatus.Error;
		}	
		
		this.OnLoad = function()
		{
			this.Debug("OnLoad called");
			this.Status = CachedImageStatus.Complete;
		}
		
		this.toString = function()
		{
			var retVal =
				"Source: " + this.Source + 
				", Status: " + this.Status
			return retVal;
		}
		
		this.Debug = function(msg)
		{
			SfDebug.DPF(this.m_debugLevel, "CachedImage: " + msg);
		}
	}
}

// ENDFILE ImageCache.js ---------------------------------------------------------------------------------->

// BEGINFILE ImageUpdater.js ------------------------------------------------------------------------------>

function ImageUpdater(container, win, imageElement, extraWidth, extraHeight)
{
	this.m_debugLevel = SfDebug.Verbose;
//	this.m_debugLevel = SfDebug.Information;
	
	this.Container = container;
	this.Window = win;
	this.ImageElement = imageElement;
	this.ExtraWidth = extraWidth;
	this.ExtraHeight = extraHeight;
	this.ScrollbarWidth = 20;
	this.ScrollbarHeight = 20;
	
	this.TempImage = null;
	this.PreviousImageWidth = null;
	this.PreviousImageHeight = null;
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "ImageUpdater: " + msg);
	}
	
	this.ChangeImage = function(imageSrc)
	{
		this.Debug("ChangeImage: " + imageSrc);

		this.ImageElement.onload = new Function("", this.Container + ".ChangeSizes();");
		this.ImageElement.onerror = new Function("", this.Container + ".OnError();");
		this.ImageElement.src = imageSrc;
	}
	
	this.OnError = function()
	{
		this.Debug('Error loading image');
	}

	this.ChangeSizes = function()
	{
		this.Debug("ChangeSizes called");
		
		var imageDimension = this.GetImageDimension();
		if (this.ValidateDimension(imageDimension) == false)
		{
			this.Debug("Could not validate dimension");
			return;
		}
		// if we are here... image width and height is valid
		var imageWidth = imageDimension.Width;
		var imageHeight = imageDimension.Height;
		
		this.Debug("imageWidth: " + imageWidth + ", imageHeight: " + imageHeight);
		
		// has the image size changed from the previous
		if (this.IsChangeNecessary(imageWidth, imageHeight) == false)
		{
			this.Debug("there is no need to change size");
			return;
		}
		this.Debug("changing size is necessary!!");
		
		this.ChangeWindowSize(imageWidth, imageHeight);
		this.ChangeImageSize(imageWidth, imageHeight);
	}
	
	this.ChangeWindowSize = function(imageWidth, imageHeight)
	{
		this.Debug("ChangeWindowSize called");

		var dimension = this.GetOptimumWindowDimension(imageWidth, imageHeight);
		if (dimension == null)
		{
			this.Debug("could not get window dimension");
			return;
		}
		this.Debug("window width: " + dimension.Width + 
			", window Height: " + dimension.Height);
		
		WindowHelper.Center(window, dimension.Width, dimension.Height);
		window.resizeTo(dimension.Width, dimension.Height);
	}
	
	this.ChangeImageSize = function(imageWidth, imageHeight)
	{
		this.Debug("ChangeImageSize called");

		this.SetImageDimension(imageWidth, imageHeight);
//		this.UpdateImageContainerDimension(imageWidth, imageHeight);
	}

	this.GetImageDimension = function()
	{
		var ret = new Object();
		if (!this.ImageElement)
		{
			this.Debug("could not find tempimage");
			return null;
		}
		
		ret.Width = this.ImageElement.width;
		ret.Height = this.ImageElement.height;

		return ret;
	}
	
	this.ValidateDimension = function(dimension)
	{
		if (dimension == null)
		{
			return false;
		}
		
		var width = dimension.Width;
		var height = dimension.Height;
		if (!width)
		{
			this.Debug("could not find width");
			return false;
		}
		if (width < 100)
		{
			this.Debug("width < 100");
			return false;
		}
		
		if (!height)
		{
			this.Debug("could not find height");
			return false;
		}
		if (height < 100)
		{
			this.Debug("height < 100");
			return false;
		}
		
		return true;
	}
	
	// has image size changed (or, not initialized)
	this.IsChangeNecessary = function(imageWidth, imageHeight)
	{
		if (this.PreviousImageWidth == null || this.PreviousImageHeight == null)
		{
			return true;
		}
		
		if (this.PreviousImageWidth != imageWidth || this.PreviousImageHeight != imageHeight)
		{
			return true;
		}
		
		return false;	
	}
	
	this.GetOptimumWindowDimension = function(imageWidth, imageHeight)
	{
		this.Debug("GetOptimumWindowDimension called");
		
		var ret = new Object();

		var availWidth = screen.availWidth;
		var availHeight = screen.availHeight;

		var frameExtra = this.GetFrameExtraDimension();
		this.Debug("Frame Extra Width: " + frameExtra.Width + ", Height: " + frameExtra.Height);
		// windowWidth is optimum window width
		// extrawidth comes from constructor
		var windowWidth = imageWidth + this.ExtraWidth + frameExtra.Width + this.ScrollbarWidth; 
		if (windowWidth > availWidth)
		{
			ret.Width = availWidth;
		}
		else
		{
			ret.Width = windowWidth;
		}
		
		var windowHeight = imageHeight + this.ExtraHeight + frameExtra.Height + this.ScrollbarHeight;
		if (windowHeight > availHeight)
		{
			ret.Height = availHeight;
		}
		else
		{
			ret.Height = windowHeight;
		}
		
		return ret;				
	}
	
	this.GetImageContainerDimension = function(imageWidth, imageHeight)
	{
		this.Debug("GetImageContainerDimension called");
		var containerDimension = new Object();
		
		var clientWidth = document.body.offsetWidth;
		if (!clientWidth)
		{
			this.Debug("null clientWidth");
			return null;
		}
		var clientHeight = document.body.offsetHeight;
		if (!clientHeight)
		{
			this.Debug("null clientHeight");
			return null;
		}
		this.Debug("clientWidth: " + clientWidth + ", clientHeight: " + clientHeight);
		
		if (imageWidth + this.ExtraWidth > clientWidth)
		{
			// no sufficient space
			containerDimension.Width = clientWidth - this.ExtraWidth;
		}
		else
		{
			containerDimension.Width = imageWidth + this.ExtraWidth;
		}
		
		if (imageHeight + this.ExtraHeight > clientHeight)
		{
			containerDimension.Height = clientHeight - this.ExtraHeight;
		}
		else
		{
			containerDimension.Height = imageHeight + this.ExtraHeight;
		}
		
		return containerDimension;
	}
	
	this.UpdateImageContainerDimension = function(imageWidth, imageHeight)
	{
		this.Debug("UpdateImageContainerDimension called");
		var dimension = this.GetImageContainerDimension(imageWidth, imageHeight);
		if (dimension == null)
		{
			this.Debug("could not get container dimension");
			return;
		}
		this.Debug("container Width: " + dimension.Width);
		this.Debug("container Height: " + dimension.Height);
		
		if ((dimension.Width == (imageWidth + this.ExtraWidth)) 
			&& (dimension.Height == (imageHeight + this.ExtraHeight)))
		{
			this.Debug("no need to set container dimension");
			return;
		}
		var cont = SfDOM.FindElementFromID(document, "ImageContainer");
		if (!cont)
		{
			this.Debug("could not find container");
			return;
		}
		
		cont.style.width = dimension.Width;
		cont.style.height = dimension.Height;
	}
	
	this.SetImageDimension = function(imageWidth, imageHeight)
	{
		this.Debug("Setting current image dimension to: width: " + imageWidth + ", height: " + imageHeight);
		
		
		this.ImageElement.width = imageWidth;
		this.ImageElement.height = imageHeight;
		
		this.PreviousImageWidth = imageWidth;
		this.PreviousImageHeight = imageHeight;
		
	}
	
	this.GetMainHelper = function()
	{
		this.Debug("GetMainHelper called");
		if (opener.closed)
		{
			this.Debug("opener is closed");
			return null;
		}
		
		if (!opener.MainHelper)
		{
			this.Debug("Could not find MainHelper in opener");
			return null;
		}
		var mainHelper = opener.MainHelper;
		return mainHelper;
	}
	
	this.GetFrameExtraDimension = function()
	{
		this.Debug("GetFrameExtraDimension called");
		var dimension = new Object();
		
		dimension.Width = 0;
		dimension.Height = 0;
		var mainHelper = this.GetMainHelper();
		if (mainHelper != null)
		{
			dimension.Width = mainHelper.GetFrameExtraWidth();
			dimension.Height = mainHelper.GetFrameExtraHeight();		
		}
		else
		{
			this.Debug("null mainhelper");
		}
		return dimension;
	}
}

// ENDFILE ImageUpdater.js -------------------------------------------------------------------------------->
// BEGINFILE AreaBase.js ---------------------------------------------------------------------------------->

function Point(x, y)
{
	this.X = x;
	this.Y = y;
	
	this.toString = function()
	{
		return "x: " + this.X + ", y: " + this.Y;
	}
}

function AreaBase()
{
	var Width;
	var Height;
	var Position;
	var IsVisible;
	var Container;
	var ContainingWindow;
	var ID;
	
	this.m_debugLevel = SfDebug.Verbose;
	
	this.Debug = function(str)
	{
		SfDebug.DPF(this.m_debugLevel, "AreaBase: " + str);
	}
	
	this.InitializeArea = function(container, containingWindow, ID)
	{

		this.Container = container;
		this.ContainingWindow = containingWindow;
		this.ID = ID;

		this.Debug("InitializeArea called: " + this);
		
		SfOnLoad.AddHandler("" + this.Container + ".MasterOnLoad()");
//		this.MasterOnLoad();
		SfOnUnLoad.AddHandler("" + this.Container + ".MasterOnUnLoad()");
	}
	
	this.InitializePosition = function()
	{
		var divElement = this.GetDiv();
		if (!divElement)
		{
			return;
		}
		var left = divElement.style.left;
		if (!left)
		{
			return;
		}
		var top = divElement.style.top;
		if (!top)
		{
			return;
		}
		var width = divElement.style.width;
		if (!width)
		{
			return;
		}
		var height = divElement.style.height;
		if (!height)
		{
			return;
		}
		this.Width = this.ParsePx(width);
		this.Height = this.ParsePx(height);
		this.Position = new Point(this.ParsePx(left), this.ParsePx(top));
		this.Debug("InitializePosition called: " + this.ID + ", position: " + this.Position + ", width: " + this.Width + ", height: " + this.Height);
	}
	
	this.MasterOnLoad = function()
	{
		this.Debug("MasterOnLoad called: " + this);
		
		this.OnLoad();
		this.InitializePosition();

		var areaManager = GetAreaManager();
		if (areaManager)
		{
			this.Debug("Adding area: " + this.ID);
			areaManager.AddArea(this.ID, this);
		}
	}
	
	this.OnLoad = function()
	{
		SfDebug.DPF(SfDebug.Verbose, "OnLoad not implemented for: " + this);
	}
	
	this.MasterOnUnLoad = function()
	{
		this.Debug("MasterOnUnLoad called: " + this);
		
		this.OnUnLoad();
		
		var areaManager = GetAreaManager();
		if (areaManager)
		{
			this.Debug("Removing area: " + this.ID);
			areaManager.RemoveArea(this.ID);
		}
	}
	
	this.OnUnLoad = function()
	{
		this.Debug("OnUnLoad not implemented for: " + this);
	}
	
	this.Div = null;
	this.GetDiv = function()
	{
		if (this.Div == null)
		{
			this.Div = SfDOM.FindElementFromID(this.ContainingWindow.document, this.ID);
		}
		return this.Div;
	}
	
	this.Move = function(p)
	{
		var divElement = this.GetDiv();
		divElement.style.left = p.X;
		divElement.style.top = p.Y;
		this.Position.X = p.X;
		this.Position.Y = p.Y;
	}
	
	// begin: test --------------------------->
	this.m_maxBound = 700;
	this.m_minBound = 0;
	this.Animate = function()
	{
		var newX = this.Position.X + 10;
		if (newX > this.m_maxBound)
		{
			newX = this.m_minBound;
		}
		this.Move(new Point(newX, this.Position.Y));
		
		var args = new Object();
		args.invokee = this;
		
		SfTimedEvent.setTimeOut(this.Animate, 1, args);
	}
	// end: test ----------------------------------->
	
	// width and height
	this.Resize = function(width, height)
	{
		var divElement = this.GetDiv();
		divElement.style.width = width;
		divElement.style.height = height;
		this.Width = this.ParsePx(width);
		this.Height = this.ParsePx(height);
	}
	
	this.Hide = function()
	{
		var divElement = this.GetDiv();
		divElement.style.display = 'none';		
	}
	
	this.Show = function()
	{
		var divElement = this.GetDiv();
		divElement.style.display = '';		
	}
	
	this.IsShowing = function()
	{
		var displayVal = this.GetDiv().style.display;
		if (displayVal == 'none')
		{
			return false;	
		}
		else
		{
			return true;
		}
	}
	
	this.toString = function()
	{
		var retVal = "Container: " + this.Container + ", ID: " + this.ID;
		return retVal;
	}
	
	this.ParsePx = function(arg)
	{
		var retVal;
		var re = /\d+px/i;
		if (arg.match(re))
		{
			retVal = arg.substr(0, arg.length-2);
		}
		else
		{
			retVal = arg;
		}
		return Number(retVal);
	}
}

// ENDFILE AreaBase.js ------------------------------------------------------------------------------------->

// BEGINFILE PresentationInfo.js --------------------------------------------------------------------------->

// this must be in sync with the db
var PresentationStatus =
{
	Unknown:0,
	NotReady: 1,//before prelive
	CaptureReady: 2, //prelive
	CaptureInProgress: 3, // Live
	Ended: 4,//ended
	ReplayReady: 5 // replay // or recorderavailable
}

var PollShowType =
{
	Unknown: 0,
	Begin: 1,
	End: 2
}

var SlideType =
{
	Normal: 0,
	FullSize: 1,
	ThumbNail: 2,
	Unknown: 3
}


function CaptureImageInfo()
{
	this.Image = null;
	this.Width = null;
	this.Height = null;
}

// PresentationInfo.SlideTimings is setup as follows
// SlideTimings[0].Time = 
//					.Normal.Image = 
//							.Width =
//							.Height =
//					.Thumb.Image =
//							.Width =
//							.Height =
//					.FullSize.Image =
//							.Width =
//							.Height =
// SlideTimings[1].Time =
// ...
// ...

function SlideTimingType()
{
	this.Normal = new CaptureImageInfo();
	this.ThumbNail = new CaptureImageInfo();
	this.FullSize = new CaptureImageInfo();
}


function ImageDimensions()
{
	this.ThumbNail = new Dimension();
	this.Normal = new Dimension();
}

function Dimension(width, height)
{
	this.Width = width;
	this.Height = height;
}

function PresentationInfo()
{
	this.DoReporting = null;
	this.IsAudioOnly = null;
	this.IsStandAlone = null;
	this.PresentationExperienceID = null;
	this.PresentationID = null;
	this.EventID = null;
	this.UserTicketId = null;
	this.MediaTicketId = null;
	this.MediaTicketInitializationDone = false;
	this.FullSizePage = null;
	
	this.VideoUrl = null;
	this.ImageBaseUrl = null;
	
	this.Status = null;
	this.PollsEnabled = null;
	this.PollsResultsEnabled = null;
	this.ForumEnabled = null;
	
	this.TestPassword = null;
	this.CurrentPreviewImage = null;

	this.ImageDimensions = new ImageDimensions();
	this.SlideTimings = new Array();
		
}

// ENDFILE PresentationInfo.js ---------------------------------------------------------------------------->

// BEGINFILE SfButton.js ---------------------------------------------------------------------------------->

function SfButtonImage()
{
	this.Normal=null;
	this.Pressed=null;
	this.Over=null;
	this.Disabled=null;
}

function SfButton(id)
{
	this.id=id;
	this.Style=SfButton.StylePush;
	this.IsEnabled=true;
	this.IsChecked=false;
	this.IsPressed=false;
	this.IsHilighted=false;
	this.Image= new Array(2);
	this.Image[0]= new SfButtonImage();
	this.Image[1]= new SfButtonImage();
	
	this.ToolTip;
	this.DebugLevel = SfDebug.Verbose;

	this.Initialize = function()
	{
		this.Debug("Initialize called");

		var whichImageCtl= this.GetImage();
		var whichLinkCtl= this.GetLink();
		
		if (this.Container==null)
		{
			SfDebug.DPF(SfDebug.ErrMsgCritical, "Null container in button area");
			return;
		}
		whichLinkCtl.onmouseover= new Function("",this.Container+".OnMouseOver();");
		whichLinkCtl.onmouseout= new Function("",this.Container+".OnMouseOut();");
		whichLinkCtl.onclick= new Function("",this.Container+".OnClick();");
		whichLinkCtl.onmousedown= new Function("",this.Container+".OnMouseDown();");
		whichLinkCtl.onmouseup= new Function("",this.Container+".OnMouseUp();");
		whichImageCtl.alt=this.ToolTip;
		whichLinkCtl.title=this.ToolTip;
		
		this.Paint();
	}

	this.GetImage = function()
	{
		this.Debug("GetImage called");
		var image;
		
		image=SfDOM.FindElementFromName(document,this.id+"Img");
		
		if (image==null)
			image=SfDOM.FindElementFromName(document,this.id);
			
		if (image==null)
		{
		    SfDebug.DPF(SfDebug.ErrMsgCritical,"No image for "+this.id+"Img");
		}
			
		return image;
	}
	
	this.GetLink = function()
	{
		var link = SfDOM.FindElementFromName(document,this.id+"Link");
		
		if (link==null)
		{
		    SfDebug.DPF(SfDebug.ErrMsgCritical,"No link for "+this.id+"Link");
		}
		
		return link;
	}
	
	this.SetToolTip = function(strToolTip)
	{
		var whichImageCtl= this.GetImage();
		var whichLinkCtl= this.GetLink();
		this.ToolTip = strToolTip;
		whichImageCtl.alt=this.ToolTip;
		whichLinkCtl.title=this.ToolTip;
	}
	
	this.SetCheck = function(Checked)
	{
		this.IsChecked=Checked;
		
		this.Paint();
	}
	
	this.Enable = function(Enabled)
	{
		this.IsEnabled=Enabled;
		
		this.Paint();
	}
	
	// only expect this when we aren't holding the mouse down
	this.OnMouseOver = function()
	{
		this.Debug("OnMouseOver called");
		this.IsHilighted = true;
		this.Paint();
	}
	
	// we get this once if we move off with no mouse down or if we let go of the button outside of the button
	this.OnMouseOut = function()
	{
		this.IsPressed=false;
		this.IsHilighted=false;
		this.Paint();
	}
	

	this.OnMouseDown = function()
	{
		this.Debug("OnMouseDown called");
		this.IsPressed=true;
		this.Paint();
	}

	// kind of useless since we only get this if we let go on top of the control
	// we'll get a OnClick anyway unless we're using capture in which case we need it
	this.OnMouseUp = function()
	{
		this.IsPressed=false;
		this.Paint();
	}
	
	this.OnClick = function()
	{
		this.Debug("OnClick called");
		this.IsPressed=false;
		
		if (this.IsEnabled)
		{
			this.ClickHandler();
		}
			
		this.Paint();
	}
	
	this.Paint = function()
	{
	
		var whichImageCtl= this.GetImage();
		var imgToSet,btnImage;
		
		if (null==whichImageCtl)
			return;
		
		btnImage=this.Image[0];
		
		if (this.Style==SfButton.StyleCheck)
		{
			if (this.IsChecked)
			{
				btnImage=this.Image[1];
			}
		}
		
		imgToSet = btnImage.Normal;
		
		if (btnImage.Normal!=null)
		{
				imgToSet=btnImage.Normal;
		}
		else
		{
			if (this.Image[0].Normal!=null)
			{
				imgToSet=this.Image[0].Normal;
			}
		}
		
		// All buttons should have this image.			
		if (null==imgToSet)
		{
			SfDebug.DPF(SfDebug.Information, "imgToSet = null");
			return;
		}
		
		// Disabled button
		if (!this.IsEnabled)
		{
			this.Debug("PAINT DISABLED");
			if (btnImage.Disabled!=null)
			{
				imgToSet=btnImage.Disabled;
			}
			else
			{
				if (this.Image[0].Disabled!=null)
				{
					imgToSet=this.Image[0].Disabled;
				}
			}
		}
		else
		{
			if (this.IsPressed)
			{
				this.Debug("PAINT PRESS");
				if (btnImage.Pressed!=null)
				{
					imgToSet=btnImage.Pressed;
				}
				else
				{
					if (this.Image[0].Pressed!=null)
					{
						imgToSet=this.Image[0].Pressed;
					}
				}
			}
			else
			{
				if (this.IsHilighted)
				{
					if (btnImage.Over!=null)
					{
						imgToSet=btnImage.Over;
						this.Debug("PAINT HILIGHT "+imgToSet);
					}
					else
					{
						if (this.Image[0].Over!=null)
						{
							imgToSet=this.Image[0].Over;
							this.Debug("PAINT HILIGHT DEFAULT "+imgToSet);
						}
					}
				}
				else
				{
					this.Debug("PAINT NORMAL");
				}
			}
		}
			
		if (!imgToSet)
		{
			SfDebug.DPF(SfDebug.ErrMsgCritical,"MISSING IMAGE for "+this.id);
		}

		whichImageCtl.src = imgToSet;
	}
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.DebugLevel, "Container: " + this.Container + ", Msg: " + msg);
	}
	
	this.ClickHandler = function()
	{
		alert("Unimplimented Button ClickHandler id: "+this.id);
	}
}

SfButton.StylePush=0;
SfButton.StyleCheck=1;

// ENDFILE SfButton.js ------------------------------------------------------------------------------------>

// BEGINFILE FrameHelper.js ------------------------------------------------------------------------------->

// !! revisit this shouldn't be called FrameHelper
function FrameHelper()
{
	this.m_debugLevel = SfDebug.Verbose;
//	this.m_debugLevel = SfDebug.Information;

	// Default Sizes
	this.DefaultFullSizeWidth = 1024;
	this.DefaultFullSizeHeight = 768;

	this.DefaultFullSizeWindowWidth = 1024;
	this.DefaultFullSizeWindowHeight = 795;

	this.EventCommand = new SfEvent(SfEventType.Command);
	this.EventScript = new SfEvent(SfEventType.Script);
	this.EventSlideChanged = new SfEvent(SfEventType.SlideChanged);
	this.EventDataAvailable = new SfEvent(SfEventType.DataAvailable);
	this.EventSlideAdded = new SfEvent(SfEventType.SlideAdded);
	this.EventPlayBegin = new SfEvent(SfEventType.PlayBegin);

	// Player Type Stuff
	this.PlayerDetect = new PlayerDetect();
	this.WindowsFrameExtraWidth = 10;
	this.WindowsFrameExtraHeight = 35;
	
	// Player Events
	this.EventPlayerSetupComplete = new SfEvent(SfEventType.PlayerSetupComplete);
	this.EventPlayerStateChanged = new SfEvent(SfEventType.PlayerStateChanged);
	this.EventPlayerTimerUpdated = new SfEvent(SfEventType.PlayerTimerUpdated);
	this.EventPlayerMediaLengthObtained = new SfEvent(SfEventType.MediaLengthObtained);
	this.EventPlayerPositionChanged = new SfEvent(SfEventType.PlayerPositionChanged);
	this.EventPlayerPlayStateChanged = new SfEvent(SfEventType.PlayerPlayStateChanged);

	// Others
	this.EventSliderNotify = new SfEvent(SfEventType.SliderNotify);
	this.EventVolumeInitialized = new SfEvent(SfEventType.VolumeInitialized);
	this.EventVolumeChanged = new SfEvent(SfEventType.VolumeChanged);
	this.EventOptionsChangeToAreas = new SfEvent("EventOptionsChangeToAreas");
	this.EventOptionsChangeFromAreas = new SfEvent("EventOptionsChangeFromAreas");
		
	this.ViewerBaseAppURL = null;
	
	this.CurrentSlideNumber = -1;
	this.CurrentFullSizeImage = null;
	this.DynamicAdd = false;
	this.PresentationEnded = false;
	this.ShouldChangeView = true;
	
	// Popup Windows
	this.PopupWindows = new Object();
	this.PopupWindows.FullSize = null;
	this.PopupWindows.PreviewSlide = null;
	
	
	this.Presentation = new PresentationInfo();
	
	// this can be only called after window is loaded
	this.Initialize = function()
	{
		this.InitializeSlideTimings();
		this.InitializeEventID();
		this.InitializeMediaTicketId();
		this.InitializeReporting();
		SfOnUnLoad.AddHandler("MainHelper.CloseFullSizeWindow()");
	}
	
	this.CloseFullSizeWindow = function()
	{
		if (WindowHelper.IsOpen(MainHelper.PopupWindows.FullSize) == false)
		{
			return;
		}
		
		MainHelper.PopupWindows.FullSize.close();
	}
	
	this.InitializeEventID = function()
	{
		if (MainHelper.Presentation.IsStandAlone == true)
		{
			return;
		}
		MainHelper.Presentation.EventID = Util.GetGuid();
		
		var separator;
		if (MainHelper.Presentation.VideoUrl.indexOf("?") > -1)
		{
			separator = "&";
		}
		else
		{
			separator = "?";
		}
		MainHelper.Presentation.VideoUrl = MainHelper.Presentation.VideoUrl + separator + SfRequestVariables.EventID + "=" + MainHelper.Presentation.EventID;
		
	}
	
	this.InitializeMediaTicketId = function()
	{
		if (MainHelper.Presentation.IsStandAlone == true)
		{
			MainHelper.Presentation.MediaTicketInitializationDone = true;
			return;
		}
		
		var source = Util.GetDocumentBase() + 
			"/Caching/MediaInfo.aspx?" +
			"&" + SfRequestVariables.PresentationExperienceID + "=" + MainHelper.Presentation.PresentationExperienceID +
			"&random=" + SfRandom.Next();
			
		if (MainHelper.Presentation.UserTicketId != null)
		{
			source += "&" + SfRequestVariables.UserTicketId + "=" + MainHelper.Presentation.UserTicketId;
		}
			
		var frameLoader = new FrameLoader(source);
		frameLoader.Load();
	}
	
	this.InitializeReporting = function()
	{
		if (this.Presentation.DoReporting == false)
		{
			return;
		}
		SfOnUnLoad.AddHandler("MainHelper.ReportEndViewingPresentation()");	
	}
	
	this.ReportEndViewingPresentation = function()
	{
		if (MainHelper.Presentation.DoReporting == false)
		{
			return;
		}
		
		var imageSource = 
			Util.GetDocumentBase() + 
			"/Reporting/ReportViewerPageClosed.aspx?" + 
			"&" + SfRequestVariables.PresentationExperienceID + "=" + MainHelper.Presentation.PresentationExperienceID +
			"&" + SfRequestVariables.MediaTicketId + "=" + MainHelper.Presentation.MediaTicketId +
			"&random=" + SfRandom.Next() + 
			"&" + SfRequestVariables.EventID + "=" + MainHelper.Presentation.EventID;
		
		var img = new Image();
		img.width = 0;
		img.height = 0;
		img.src = imageSource;
	}
	
	this.InitializeSlideTimings = function()
	{
		this.Debug("Initializing slidetimings");
		
		//Debug
//		this.Presentation.SlideTimings = new Array(0);
//		this.MaxSlideTimings = 0;
//		return;
		//EndDebug
		
		// Live or no slides in the database
		if (Timings == null)
		{
			this.Debug("MainHelper.Presentation.SlideTimings is null");
			this.Presentation.SlideTimings = new Array(0);
			this.MaxSlideTimings = 0;
			return;
		}
		
		var len = Timings.length;
		this.MaxSlideTimings = len;
		this.Debug("MaxSlideTimings: " + this.MaxSlideTimings);

		this.Presentation.SlideTimings = new Array(len);
		var i;
		for (i=0; i<len; ++i)
		{
			var slideNumber = Number(i+1);
			this.Presentation.SlideTimings[i] = new SlideTimingType();
			this.Presentation.SlideTimings[i].Time = Timings[i];
			this.Presentation.SlideTimings[i].Normal.Image = this.GetImageLocation(slideNumber, SlideType.Normal);
			this.Presentation.SlideTimings[i].ThumbNail.Image = this.GetImageLocation(slideNumber, SlideType.ThumbNail);
			this.Presentation.SlideTimings[i].FullSize.Image = this.GetImageLocation(slideNumber, SlideType.FullSize);
		}
	}
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "MainHelper: " + msg);
	}
	
	this.GetFrameExtraWidth = function()
	{
		var playerType = this.PlayerDetect.GetPlayerType();
		if (playerType == PlayerType.WM64Lite)
		{
			return 0;
		}
		else
		{
			return this.WindowsFrameExtraWidth;
		}
	}
	
	this.GetFrameExtraHeight = function()
	{
		var playerType = this.PlayerDetect.GetPlayerType();
		if (playerType == PlayerType.WM64Lite)
		{
			return 0;
		}
		else
		{
			return this.WindowsFrameExtraHeight;
		}
	}
	
	this.OnSlideAddedEventHandler = function()
	{
		this.Debug("OnSlideAddedEventHandler called");
		
	}
	
	this.CreateShowSlideEventArgs = function(slideNumber)
	{
		var args = new Object();
		
		args.Command = SfScriptCommandType.ShowSlide;
		args.Index = slideNumber;
		
		if (slideNumber < 1)
		{
			return args;
		}
		
		args.Image = this.GetImageLocation(slideNumber, SlideType.Normal);
		args.FullSizeImage = this.GetImageLocation(slideNumber, SlideType.FullSize);
		args.ThumbNailImage = this.GetImageLocation(slideNumber, SlideType.ThumbNail);
	
		return args;
	}
	
	this.KeepAddingToSlideTimings = function(slideNumber)
	{
		this.Debug("KeepAddingToSlideTimings(): ");
		var maxTimings = this.MaxSlideTimings;
		if (maxTimings > slideNumber)
		{
			return;
		}
		
		var startIndex = maxTimings + 1;
		var endIndex = slideNumber;
		
		var i;
		for (i=startIndex; i<=endIndex; ++i)
		{
			this.AddToSlideTimings(i);
		}
	}
	
	this.AddToSlideTimings = function(slideNumber)
	{
		this.Debug("AddToSlideTimings(): " + slideNumber);
		var newTiming = new SlideTimingType();
		newTiming.Time = -1.00;
		
		newTiming.Normal.Image = this.GetImageLocation(slideNumber, SlideType.Normal);
		newTiming.ThumbNail.Image = this.GetImageLocation(slideNumber, SlideType.ThumbNail);
		newTiming.FullSize.Image = this.GetImageLocation(slideNumber, SlideType.FullSize);

		this.Presentation.SlideTimings[this.MaxSlideTimings] = newTiming;
		this.MaxSlideTimings = this.MaxSlideTimings + 1;
	}

	this.DisplayShowSlideEventArgs = function(args)
	{
		this.Debug("ShowSlideArguments ===========>");
		this.Debug("Command: " + args.Command);
		this.Debug("Index: " + args.Index);
		this.Debug("Image: " + args.Image);
		this.Debug("FullSizeImage: " + args.FullSizeImage);
		this.Debug("ThumbNailImage: " + args.ThumbNailImage);
	}
	
	this.GetImageLocation = function(slideNumber, type)
	{
		if (this.Presentation.IsStandAlone == true)
		{
			return 	this.Presentation.ImageBaseUrl + "/" + this.GetStandAloneImageName(slideNumber, type);
		}

		var val = this.Presentation.ImageBaseUrl + 
			'&' + SfRequestVariables.SlideNumber + '=' + slideNumber;
			
		if (this.Presentation.UserTicketId != null)
		{
			val += '&' + SfRequestVariables.UserTicketId + '=' + this.Presentation.UserTicketId;
		}
		
		if (type == SlideType.FullSize)
		{
			return val;
		}
		
		var width = -1;
		var height = -1;

		try 
		{
			if (type == SlideType.Normal)
			{
				width = CurrentSlideAreaInstance.Width;
				height = CurrentSlideAreaInstance.Height;
			}
			else if (type == SlideType.ThumbNail)
			{
				width = MainHelper.Presentation.ImageDimensions.ThumbNail.Width;
				height = MainHelper.Presentation.ImageDimensions.ThumbNail.Height;
			}
		} 
		catch (e) 
		{
			// no CurrentSlideAreaInstance
			return "";
		}
		
		return val +  '&width=' + width + '&height=' + height;
	}
	
	this.GetStandAloneImageName = function(slideNumber, type)
	{
		return "Slide_" + this.CreateStringSlideNumber(slideNumber) + "_Full.jpg";
	}
	
	this.m_numDigits = 4;
	this.CreateStringSlideNumber = function(slideNumber)
	{
		var slideString = new String(slideNumber);	
		var len = slideString.length;
		var numZeroes = this.m_numDigits - len;
		var retVal = "";
		for (i=0; i<numZeroes; ++i)
		{
			retVal = retVal.concat("0");
		}
		retVal = retVal.concat(slideString);
		return retVal;
	}
	
}

// ENDFILE FrameHelper.js ---------------------------------------------------------------------------------->

// BEGINFILE FrameLoading.js ------------------------------------------------------------------------>
function FrameLoader(location)
{
	this.location = location;
//	this.m_debugLevel = SfDebug.Information;
	this.m_debugLevel = SfDebug.Verbose;

	this.Debug = function(str)
	{
		SfDebug.DPF(this.m_debugLevel, "FrameLoader: " + str);
	}
	
	this.Load = function()
	{
		var ifr = document.createElement('DIV');
		ifr.style.visibility = 'hidden'; 
		ifr.style.position = 'absolute'; 
		ifr.style.top = '0px'; 
		ifr.style.left = '0px';
		var frameSrc = this.location + '&random=' + SfRandom.Next();
		this.Debug("frameSrc: " + frameSrc);
		ifr.innerHTML = '<iframe src="'+ frameSrc + '" height="0" width="0"></iframe>';
		document.body.appendChild(ifr);
	}
	
}

// ENDFILE FrameLoading.js ------------------------------------------------------------------------>

// BEGINFILE HiddenFrame.js ----------------------------------------------------------------------->

function HiddenFrame(id)
{
 	this.FrameId = id;
	
//	this.m_debugLevel = SfDebug.Information;
	this.m_debugLevel = SfDebug.Verbose;

	this.Debug = function(str)
	{
		SfDebug.DPF(this.m_debugLevel, "HiddenFrame: " + str);
	}
	
	this.Load = function(src)
	{
		this.Debug("Load() src: " + src);
		var frame = SfDOM.FindElementFromID(document, this.FrameId);
		frame.src = src;
	}
	
	this.CreateFrame = function()
	{
		var frame = document.createElement('iframe');
		
		frame.setAttribute('height', '0');
		frame.setAttribute('width', '0');
		frame.setAttribute('id', this.FrameId);
		frame.style.visibility = 'hidden';

		document.body.appendChild(frame);
	}
	
}

// ENDFILE HiddenFrame.js ------------------------------------------------------------------------->
// BEGINFILE SfSlider.js ----------------------------------------------------------------------------->
function SfSliderDragEventType(){}
SfSliderDragEventType.BeginDrag = "BeginDrag";
SfSliderDragEventType.EndDrag = "EndDrag";
SfSliderDragEventType.DragMove = "DragMove";

var SfSliderOrientation =
{
	Horizontal : "Horizontal",
	Vertical : "Vertical"
}

function SfSlider(namePrefix, orientation)
{
	var m_debugLevel = SfDebug.Verbose;
//	var m_debugLevel = SfDebug.Information;

	this.NamePrefix = namePrefix;
	this.Orientation = orientation;

	this.IsEnabled = true;
	
	var m_this = this;

	var m_thumbLength = -1;
	var m_rangeMin = 0;
	var m_rangeMax = 100;
	var m_physicalMin = -1;
	var m_physicalMax = -1;
	var m_elementThumb = null;
	var m_elementGuide = null;
	
	//Events
	this.ClickEvent = null;
	this.DragEvent = null;

	var Debug = function(msg)
	{
		SfDebug.DPF(m_debugLevel, "SfSlider: (" + m_this.NamePrefix + "): " + msg);
	}
	
	this.OnLoad = function()
	{
		Debug("OnLoad()");
		Initialize();
	}
	
	this.OnUnLoad = function()
	{
		Debug("OnUnLoad()");
	}
	
	this.SetRange = function(min, max)
	{
		m_rangeMin = min;
		m_rangeMax = max;
	}
	
	this.GetRangeMin = function()
	{
		return m_rangeMin;
	}
	
	this.GetRangeMax = function()
	{
		return m_rangeMax;
	}
	
	this.SetPosition = function(position)
	{
		SetLogicalPosition(position);
	}
	
	var Initialize = function()
	{
		Debug("Initialize()");

		m_elementThumb = SfDOM.FindElementFromID(document, m_this.NamePrefix + "_thumb");
		m_elementGuide =  SfDOM.FindElementFromID(document, m_this.NamePrefix + "_positionGuide");
		
		m_thumbLength = GetThumbLength();
		m_physicalMin = GetPhysicalMin();
		m_physicalMax = m_physicalMin + GetPhysicalLength();
		Debug("PhysicalMin: " + m_physicalMin);
		Debug("PhysicalMax: " + m_physicalMax);

		if (m_this.IsEnabled == true)
		{
			m_elementThumb.onmousedown = function(e){BeginDrag(e);};
			m_elementGuide.onclick = function(e){GuideOnClick(e)};
		}
		
		m_this.ClickEvent = new SfEvent("ClickEvent");
		m_this.DragEvent = new SfEvent("DragEvent");
	}
	
	var GetThumbLength = function()
	{
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			return m_elementThumb.offsetWidth;
		}
		else
		{
			return m_elementThumb.offsetHeight;
		}
	}
	
	var GetPhysicalMin = function()
	{
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			return GetPhysicalLeft();
		}
		else
		{
			return GetPhysicalTop();
		}
	}
	
	var GetPhysicalLength = function()
	{
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			return m_elementGuide.offsetWidth;
		}
		else
		{
			//!! bug in IE
			return ParsePx(m_elementGuide.style.height);
//			return m_elementGuide.offsetHeight;
		}
	}
	
	var ParsePx = function(arg)
	{
		var retVal;
		var re = /\d+px/i;
		if (arg.match(re))
		{
			retVal = arg.substr(0, arg.length-2);
		}
		else
		{
			retVal = arg;
		}
		return Number(retVal);
	}

	var GetPhysicalLeft = function()
	{
		var physicalLeft = m_elementGuide.offsetLeft;
		var par = m_elementGuide.offsetParent;
		while (par)
		{
			physicalLeft += par.offsetLeft;
			par = par.offsetParent;
		}
		return physicalLeft;
	}
	
	var GetPhysicalTop = function()
	{
		var physicalTop = m_elementGuide.offsetTop;
		var par = m_elementGuide.offsetParent;
		while (par)
		{
			physicalTop += par.offsetTop;
			par = par.offsetParent;
		}
		return physicalTop;
	}

	var LogicalToPhysical = function(logicalLength)
	{
		var physicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = m_rangeMax-m_rangeMin;
		totalPhysicalLength = m_physicalMax-m_physicalMin;
		
		if (totalLogicalLength==0)
		{
			physicalLength = 0;
		}
		else
		{
			physicalLength = (totalPhysicalLength) * logicalLength;
			physicalLength = physicalLength/(totalLogicalLength);
		}

		var physicalPosition;
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			physicalPosition = m_physicalMin + physicalLength;
		}
		else
		{
			physicalPosition = m_physicalMax - physicalLength;
		}
		
		return physicalPosition;
	}
	
	var PhysicalToLogical = function(physicalPosition)
	{
		var logicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = m_rangeMax-m_rangeMin;
		totalPhysicalLength = m_physicalMax-m_physicalMin;
		
		if (totalLogicalLength==0 || totalPhysicalLength==0)
		{
			logicalLength=0;
		}
		else if (physicalPosition < m_physicalMin)
		{
			if (m_this.Orientation == SfSliderOrientation.Horizontal)
			{
				logicalLength = 0;
			}
			else
			{
				logicalLength = totalLogicalLength;
			}
		}
		else if (physicalPosition > m_physicalMax)
		{
			if (m_this.Orientation == SfSliderOrientation.Horizontal)
			{
				logicalLength = totalLogicalLength;
			}
			else
			{
				logicalLength = 0;
			}
		}
		else
		{
			var physicalLength;
			if (m_this.Orientation == SfSliderOrientation.Horizontal)
			{
			    physicalLength = physicalPosition - m_physicalMin;
			}
			else
			{
				physicalLength = m_physicalMax - physicalPosition;
			}
			
			logicalLength = (totalLogicalLength) * physicalLength;
			logicalLength = logicalLength/(totalPhysicalLength);
		}
		
		return logicalLength;
	}
	
	var SetPhysicalPosition = function(position)
	{
	    if (position < m_physicalMin)
	    {
			position = m_physicalMin;
		}
	    if (position > m_physicalMax)
	    {
			position = m_physicalMax;
		}
		
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			m_elementThumb.style.left = '' + (position - m_physicalMin - m_thumbLength/2) + 'px';
		}
		else
		{
			m_elementThumb.style.top = '' + (position - m_physicalMin - m_thumbLength/2) + 'px';
		}
	}
	
	var SetLogicalPosition = function(position)
	{
		if (position < m_rangeMin)
		{
			position = m_rangeMin;
		}
		if (position > m_rangeMax)
		{
			position = m_rangeMax;
		}
		
		SetPhysicalPosition(LogicalToPhysical(position));
	}
	
	var GuideOnClick = function(evt)
	{
		evt = SfBrowserEvent.GetEvent(evt);
		PostClickEvent(GetLogicalPositionFromEvent(evt));
	}
	
	var GetPhysicalPositionFromEvent = function(evt)
	{
		if (m_this.Orientation == SfSliderOrientation.Horizontal)
		{
			return evt.clientX;
		}
		else
		{
			return evt.clientY;
		}
	}
	
	var GetLogicalPositionFromEvent = function(evt)
	{
		var physicalPos = GetPhysicalPositionFromEvent(evt);
		return PhysicalToLogical(physicalPos);
	}
	
	var PostClickEvent = function(logicalPosition)
	{
		var args = new Object();
 		args.Position = logicalPosition;
		Debug("PostClickEvent(): " + args.Position);
		m_this.ClickEvent.Post(args);
	}
	
	var PostDragEvent = function(type, logicalPosition)
	{
		var args = new Object();
		args.DragEventType = type;
 		args.Position = logicalPosition;
		Debug("PostDragEvent(), DragEventType :" + args.DragEventType + ", Position: " + args.Position);
		m_this.DragEvent.Post(args);
	}
	
	
	var BeginDrag = function(evt)
	{
		Debug("BeginDrag()");
		
		evt = SfBrowserEvent.GetEvent(evt);
		
		SfBrowserEvent.Attach("mousemove", OnMove);
		SfBrowserEvent.Attach("mouseup", OnUp);
		SfBrowserEvent.StopPropagation(evt);
		SfBrowserEvent.PreventDefault(evt);
		PostDragEvent(SfSliderDragEventType.BeginDrag, GetLogicalPositionFromEvent(evt));
	}

	var OnUp = function (evt)
	{
		evt = SfBrowserEvent.GetEvent(evt);
		var logicalPosition = GetLogicalPositionFromEvent(evt);

		Debug("OnUp(), logicalPosition: " + logicalPosition);

		SfBrowserEvent.Detach("mousemove", OnMove);
		SfBrowserEvent.Detach("mouseup", OnUp);
		SfBrowserEvent.StopPropagation(evt);
		SfBrowserEvent.PreventDefault(evt);
		
		PostDragEvent(SfSliderDragEventType.EndDrag, logicalPosition);
	}
		
	var OnMove = function(evt)
	{
		evt = SfBrowserEvent.GetEvent(evt);
		var logicalPosition = GetLogicalPositionFromEvent(evt);

		Debug("OnMove(): position: " +  logicalPosition);

		SfBrowserEvent.StopPropagation(evt);
		SfBrowserEvent.PreventDefault(evt);
		
		if (logicalPosition < m_rangeMin || logicalPosition > m_rangeMax)
		{
			return;
		}

		PostDragEvent(SfSliderDragEventType.DragMove, logicalPosition);
	}

}
// ENDFILE SfSlider.js ------------------------------------------------------------------------------->
// BEGINFILE SfDiscreteSlider.js ------------------------------------------------------------------------------->
SfDiscreteSlider.Inherits(SfSlider); //Function.prototype.Inherits
function SfDiscreteSlider(namePrefix, orientation, numPoints)
{
	if (numPoints < 2)
	{
		SfDebug.DPF(SfDebug.ErrAlert, "SfDiscreteSliderArea: numPoints can not be less than 2");
		return;
	}
	
	var m_debugLevel = SfDebug.Verbose;
//	var m_debugLevel = SfDebug.Information;
	
	this.Inherits(SfSlider, namePrefix, orientation); //Object.prototype.Inherits
	
	var m_numPoints = numPoints;
	var m_this = this;
	var m_points = null;
	
	var Debug = function(msg)
	{
		SfDebug.DPF(m_debugLevel, "SfDiscreteSlider: " + msg);
	}
	
	this.SetPointNumber = function(pointNumber)
	{
		Debug("SetPointNumber(): " + pointNumber);
		this.SetPosition(m_points[pointNumber]);
	}
	
	this.FindClosestPointNumber = function(pos)
	{
		Debug("FindClosestPointNumber(): " + pos);
		var closestPoint = 0;
		var minDistance = Math.abs(m_points[0] - pos);
		for (var i=1; i<m_points.length; ++i)
		{
			var distance = Math.abs(m_points[i] - pos);
			if (distance < minDistance)
			{
				minDistance = distance;
				closestPoint = i;
			}
		}
		
		return closestPoint;
	}

	var DivideIntoPoints = function()
	{
		Debug("DivideIntoPoints()");

		var min = m_this.GetRangeMin();
		var max = m_this.GetRangeMax();
		
		var length = max - min;
		var numSegments = m_numPoints - 1;
		var segmentLength = length / numSegments;
		
		m_points = new Array(m_numPoints);
		
		m_points[0] = min;
		for (var i=1; i<=numSegments; ++i)
		{
			m_points[i] = min + i*segmentLength;
		}
		Debug("min: " + min + ", max: " + max);
	}
	
	DivideIntoPoints();
}

// ENDFILE SfDiscreteSlider.js ------------------------------------------------------------------------------->
// BEGINFILE ControlButtonArea.js ------------------------------------------------------------------------->
ControlButtonArea.prototype = new AreaBase();
function ControlButtonArea(container, containingWindow, ID)
{
	this.m_debugLevel = SfDebug.Verbose;
//	this.m_debugLevel = SfDebug.Information;
	
	this.Enabled = true; // comes from code
	this.CommandName = null;// comes from code
	this.ControlArea = null;// comes from code
	
	if (typeof(container) != 'undefined')
	{
		this.InitializeArea(container, containingWindow, ID);
	}
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "ControlButtonArea: ID, " + this.ID + ", msg: " + msg);
	}
	
	this.OnLoad = function()
	{
		this.Debug("OnLoad");
		if (this.Enabled == false)
		{
			this.Debug("Not Enabled");
			this.Hide();
			return;
		}
		else
		{
			this.Debug("Enabled");
			this.Show();
		}
		this.button.Initialize();
		this.button.ClickHandler = new Function("", this.Container + ".OnClick();");
	}
	
	this.OnUnLoad = function()
	{
		this.Debug("OnUnLoad");
	}
	
	this.OnClick = function()
	{
		if (this.button.IsChecked)
		{
			this.ControlArea.Hide();
		}
		else
		{
			this.ControlArea.Show();
		}
		this.button.SetCheck(!this.button.IsChecked);
	}
	
	this.ShowControlArea = function()
	{
		this.ControlArea.Show();	
		this.button.SetCheck(true);
	}
	
	this.HideControlArea = function()
	{
		this.ControlArea.Hide();
		this.button.SetCheck(false);
	}
}
// ENDFILE ControlButtonArea.js --------------------------------------------------------------------------->
// BEGINFILE ControlButtonGroupArea.js -------------------------------------------------------------------------->
function ControlButtonGroupArea(container, containingWindow, ID)
{
	this.m_debugLevel = SfDebug.Verbose;
//	this.m_debugLevel = SfDebug.Information;

	var m_this = this;
	var m_commandHandler = null;
	
	this.Debug = function(msg)
	{
		SfDebug.DPF(this.m_debugLevel, "ControlButtonGroupArea: " + msg);
	}
		
	this.Initialize = function(container, containingWindow, ID)
	{
		this.Debug("Initialize called");
		this.Container = container;
		this.ContaingWindow = containingWindow;
		this.ID = ID;
		SfOnLoad.AddHandler("" + this.Container + ".OnLoad()");
		SfOnUnLoad.AddHandler("" + this.Container + ".OnUnLoad()");
	}
	
	this.Initialize(container, containingWindow, ID);
	
	this.OnLoad = function()
	{
		this.Debug("OnLoad()");
		
		this.ResetClickHandlersForButtons();
		this.HandleButtonStates();
		
		m_commandHandler = new SfEventHandler(this.Container);
		m_commandHandler.Container = this.Container;
		m_commandHandler.MethodName = "OnCommandEvent";
		MainHelper.EventCommand.AddHandler(m_commandHandler);
	}
	
	this.HandleButtonStates = function()
	{
		this.Debug("HandleButtonStates()");

		if (this.IsNumEnabledButtonsMoreThanOne() == true)
		{
			var firstEnabledIndex = this.GetFirstEnabledIndex();
			this.OnClick(this.Buttons[firstEnabledIndex].Container);				
		}
		else
		{
			for (var i=0; i<this.Buttons.length; ++i)
			{
				this.Buttons[i].button.SetCheck(false);
			}
		}
	}
	
	this.GetFirstEnabledIndex = function()
	{
		for (var i=0; i<this.Buttons.length; ++i)
		{
			if (this.Buttons[i].Enabled == true)
			{
				return i;
			}
		}
		return -1;
	}
	
	this.IsNumEnabledButtonsMoreThanOne = function()
	{
		var num = 0;

		for (var i=0; i<this.Buttons.length; ++i)
		{
			if (this.Buttons[i].Enabled == true)
			{
				++num;
				if (num > 1)
				{
					return true;
				}
			}
		}

		return false;
	}

	this.OnUnLoad = function()
	{
		this.Debug("OnUnLoad()");
		MainHelper.EventCommand.RemoveHandler(m_commandHandler);
	}

	this.ResetClickHandlersForButtons = function()
	{  
		this.Debug("OnLoad called");
		var len = this.Buttons.length;
		
		for (var i=0; i<len; ++i)
		{
			this.Buttons[i].Group = this;
			this.Buttons[i].button.ClickHandler = new Function("", 
				this.Container + ".OnClick('" + this.Buttons[i].Container + "');");

		}
	}
	
	this.OnCommandEvent = function(args)
	{
		this.Debug("OnCommandEvent: " + args.Command);
		for (var i=0; i<this.Buttons.length; ++i)
		{
			if (this.Buttons[i].CommandName == args.Command)
			{
				this.ShowThisAndHideOthers(i);
				return;
			}
		}
	}
	
	this.ShowThisAndHideOthers = function(index)
	{
		this.Debug("ShowThisAndHideOthers(): " + index);
		for (var i=0; i<this.Buttons.length; ++i)
		{
			if (i == index)
			{
				this.Buttons[i].ShowControlArea();
			}
			else
			{
				this.Buttons[i].HideControlArea();
			}
		}
	}
	
	this.OnClick = function(buttonContainer)
	{
		this.Debug("OnClick()");
		this.Debug("container: " + buttonContainer);

		var index = this.FindClickedButtonIndex(buttonContainer);
		if (this.Buttons[index].button.IsChecked == true)
		{
			return;
		}
		this.ShowThisAndHideOthers(index);
	}
	
	this.FindClickedButtonIndex = function(buttonContainer)
	{
		for (var i=0; i<this.Buttons.length; ++i)
		{
			if (this.Buttons[i].Container == buttonContainer)
			{
				return i;
			}
		}
		return -1;
	}
}
// ENDFILE ControlButtonGroupArea.js -------------------------------------------------------------------------->
var ZIndex =
{
	Lowest:0,
	Highest:1000
}
// BEGINFILE SfMenu.js --------------------------------------------------------------------------->
var MenuType =
{
	RootMenu : "RootMenu",
	SubMenu : "SubMenu",
	Leaf : "Leaf"
}

function LocationInfo(topOffset, leftOffset, width, height)
{
	this.Width = width;
	this.Height = height;
	this.TopOffset = topOffset;
	this.LeftOffset = leftOffset;
}

function SizeInfo(width, height)
{
	this.Width = width;
	this.Height = height;
}

function MenuItem(container, text, template)
{
	if (container && text && template)
	{
		this.Container = container;
		this.Text = text;
		this.Width = template.LocationInfo.Width;
		this.Height = template.LocationInfo.Height;
		this.TopOffset = template.LocationInfo.TopOffset;
 		this.LeftOffset = template.LocationInfo.LeftOffset;
 		this.Template = template;
	}

	this.MenuType = null;
	this.Parent = null;

	this.RootDiv = null;
	this.TextDiv = null;
	this.DivLeft = null;
	this.DivMiddle = null;
	this.DivRight = null;
	
	this.ZIndex = 1;
		
	this.InitializeCalculator = function()
	{
		if (navigator.userAgent.toLowerCase().indexOf("msie")>1)
		{
			this.Calculator = new IECalculator();
		}
		else
		{ 
			this.Calculator = new NonIECalculator();
		}
	}
		
	this.CreateElement = function(top, left, width, height)
	{
		var elem = document.createElement("div");
		elem.style.position = 'absolute';
		elem.style.top = top + 'px';
		elem.style.left = left + 'px';
		elem.style.width = width + 'px';
		elem.style.height = height + 'px';
		return elem;
	}
	
	this.GetDivClassName = function(hilite, loc)
	{
		alert('should be overridden');
	}
	
	this.Hide = function()
	{
		this.RootDiv.style.visibility = 'hidden';
		this.UnHiliteDiv();
	}
	
	this.Show = function()
	{
		this.RootDiv.style.visibility = 'visible';
	}
	
	this.OnMouseOver = function()
	{
		if (this.Parent != null)
		{
			var children = this.Parent.GetChildren();
			for (var i=0; i<children.length; ++i)
			{
				children[i].CollapseChildrenNow();
			}
		}
		this.ExpandChildrenNow();

		this.HiliteDiv();
		this.HiliteAllParents();	
	}
	
	this.HiliteAllParents = function()
	{
		var current = this;
		var par = current.Parent;
		while (par != null)
		{
			par.HiliteDiv();
			var children = par.GetChildren();
			for (var i=0; i<children.length; ++i)
			{
				if (children[i].Container != current.Container)
				{
					children[i].UnHiliteDiv();
				}
			}
			current = par;
			par = par.Parent;
		}
	}
	
	this.HiliteDiv = function()
	{
		this.DivLeft.className = this.GetDivClassName(true, 'Left');
		this.DivRight.className = this.GetDivClassName(true, 'Right');
		this.DivMiddle.className = this.GetDivClassName(true, 'Middle');
	}
	
	this.OnMouseOut = function()
	{
		this.UnHiliteDiv();
	}
	
	this.UnHiliteDiv = function()
	{
		this.DivLeft.className = this.GetDivClassName(false, 'Left');
		this.DivRight.className = this.GetDivClassName(false, 'Right');
		this.DivMiddle.className = this.GetDivClassName(false, 'Middle');
	}
	
	this.GetRootParent = function()
	{
		var currentElem = this;
		while (currentElem.Parent != null)
		{
			currentElem = currentElem.Parent;
		}
		return currentElem;
	}
	
	this.CollapseChildrenNow = function()
	{
	}
	
	this.ExpandChildrenNow = function()
	{
	}
	
	this.CreateRootDiv = function()
	{
		this.RootDiv = this.CreateElement(this.TopOffset, this.LeftOffset, this.Calculator.GetWidth(this.Width, this.GetBorderWidth()), this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
	}

	this.GetLeftDivWidth = function()
	{
		return this.Template.LeftDivWidth;
	}
	
	this.GetRightDivWidth = function()
	{
		return this.Template.RightDivWidth;
	}

	this.GetBorderWidth = function()
	{
		return this.Template.ChildBorderWidth;
	}
	
	this.CreateTextDiv = function()
	{
		this.TextDiv = this.CreateElement(0, 0, this.Calculator.GetWidth(this.Width, this.GetBorderWidth()), this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
		this.RootDiv.appendChild(this.TextDiv);

		this.DivLeft = this.CreateElement(0, 0, this.GetLeftDivWidth(), this.Height-2*this.GetBorderWidth());
		this.DivLeft.className = this.GetDivClassName(false, 'Left');
		this.TextDiv.appendChild(this.DivLeft);

		this.DivMiddle = this.CreateElement(0, this.GetLeftDivWidth(), this.Calculator.GetPaddingBorderAdjustment(this.Width - (this.GetLeftDivWidth() + this.GetRightDivWidth()), this.GetBorderWidth(), this.Template.PaddingLeft), this.Calculator.GetPaddingBorderAdjustment(this.Height, this.GetBorderWidth(), this.Template.PaddingTop));
		this.DivMiddle.className = this.GetDivClassName(false, 'Middle');
		this.DivMiddle.style.paddingLeft = this.Template.PaddingLeft + 'px';
		this.DivMiddle.style.paddingTop = this.Template.PaddingTop + 'px';
		this.DivMiddle.appendChild(document.createTextNode(this.Text));
		this.TextDiv.appendChild(this.DivMiddle);

		this.DivRight = this.CreateElement(0, this.Width-this.GetRightDivWidth()-2*this.GetBorderWidth(), this.GetRightDivWidth(), this.Height-2*this.GetBorderWidth());
		this.DivRight.className = this.GetDivClassName(false, 'Right');
		this.TextDiv.appendChild(this.DivRight);
		
		this.TextDiv.onmouseover = new Function("", this.Container + ".OnMouseOver();");
		this.TextDiv.onmouseout = new Function("", this.Container + ".OnMouseOut();");
	}
	
}

LeafItem.Inherits(MenuItem);
function LeafItem(container, text, template, onClickFunction)
{
	if (container)
	{
		this.Inherits(MenuItem, container, text, template)
		this.OnClickFunction = onClickFunction;
	}
	
	this.MenuType = MenuType.Leaf;
	this.IsSelectedLeaf = false;
	
	this.Create = function()
	{
		this.InitializeCalculator();
		this.CreateRootDiv();
		this.CreateTextDiv();
		this.TextDiv.onclick = new Function("", this.Container + ".OnClick();");
	}
	
	this.OnClick = function()
	{
		var rootParent = this.GetRootParent();
		rootParent.CollapseChildrenNow();
		rootParent.Expanded = false;
		rootParent.UnHiliteDiv();
		
		if (this.OnClickFunction)
		{
			this.OnClickFunction();
		}
		
		if (this.Group)
		{
			this.Group.Select(this);
		}
	}

	this.GetDivClassName = function(hilite, loc)
	{
		if (hilite == true)
		{
			if (this.IsSelectedLeaf == true)
			{
				return 'div' + this.Template.CssPrefix + 'SelectedLeaf' + loc + 'Over';
			}
			else
			{
				return 'div' + this.Template.CssPrefix + loc + 'Over';
			}
		}
		else
		{
			if (this.IsSelectedLeaf == true)
			{
				return 'div' + this.Template.CssPrefix + 'SelectedLeaf' + loc;
			}
			else
			{
				return 'div' + this.Template.CssPrefix + loc;
			}
		}
	}
}

function LeafGroup()
{
	this.Leafs = new Array();
	this.Add = function(leaf)
	{
		this.Leafs[this.Leafs.length] = leaf;
		leaf.Group = this;
	}
	
	this.Select = function(leaf)
	{
		for (var i=0; i<this.Leafs.length; ++i)
		{
			if (this.Leafs[i].Container == leaf.Container)
			{
				this.Leafs[i].IsSelectedLeaf = true;
			}
			else
			{
				this.Leafs[i].IsSelectedLeaf = false;
			}
			this.Leafs[i].UnHiliteDiv();
		}
	}
}

SubMenuItem.Inherits(MenuItem);
function SubMenuItem(container, text, template)
{
	if (container)
	{
		this.Inherits(MenuItem, container, text, template);
		this.SubMenuWidth = this.Template.SubMenuSizeInfo.Width;
		this.SubMenuHeight = this.Template.SubMenuSizeInfo.Height;
	}
	
	this.MenuType = MenuType.SubMenu;

	this.ChildDiv = null;
	this.Children = null;
	
	this.GetDivClassName = function(hilite, loc)
	{
		if (hilite == true)
		{
			return 'div' + this.Template.CssPrefix + 'SubMenu' + loc + 'Over';
		}
		else
		{
			return 'div' + this.Template.CssPrefix + 'SubMenu' + loc;
		}
	}
	
	this.GetChildren = function()
	{
		return this.Children;
	}
	
	this.AddLeaf = function(text, onClickFunction)
	{
		var template = this.Template.Clone();
		template.LocationInfo = new LocationInfo(this.GetCurrentChildTopOffset(), 0, this.SubMenuWidth, this.SubMenuHeight);
 		var item = new LeafItem(this.GetCurrentChildContainer(), 
 			text, 
 			template,
 			onClickFunction);
 		item.Create();
		this.AddChild(item);
		return item;
	}
	
	this.AddSubMenu = function(text, subSubMenuWidth, subSubMenuHeight)
	{
		var template = this.Template.Clone();
		template.LocationInfo = new LocationInfo(this.GetCurrentChildTopOffset(), 0, this.SubMenuWidth, this.SubMenuHeight);
		template.SubMenuSizeInfo = new SizeInfo(subSubMenuWidth, subSubMenuHeight);
		var sub = new SubMenuItem(this.GetCurrentChildContainer(), text, template);
		sub.Create();
		this.AddChild(sub);
		return sub;
	}
	
	this.GetCurrentChildContainer = function()
	{
		return this.Container + ".GetChildItem(" + this.Children.length + ")";
	}
	
	this.GetChildItem = function(index)
	{
		return this.Children[index];
	}
	
	this.ExpandChildrenNow = function()
	{
		this.ChildDiv.style.visibility = 'visible';
		for (var i=0; i<this.Children.length; ++i)
		{
			this.Children[i].Show();
		}
	}
	
	this.CollapseChildrenNow = function()
	{
		this.ChildDiv.style.visibility = 'hidden';
		for (var i=0; i<this.Children.length; ++i)
		{
			this.Children[i].Hide();
			if (this.Children[i].MenuType == MenuType.SubMenu)
			{
				this.Children[i].CollapseChildrenNow();
			}
		}
	}
	
	
	this.AddChild = function(item)
	{
		item.Parent = this;
		item.ZIndex = this.ZIndex+1;
		this.ChildDiv.style.border = this.Template.ChildBorderWidth + 'px solid ' + this.Template.ChildBorderColor;

		item.TextDiv.style.zIndex = item.ZIndex;

		this.ChildDiv.appendChild(item.RootDiv);
		this.Children[this.Children.length] = item;
		this.ChildDiv.style.height = this.Calculator.GetHeight(((this.SubMenuHeight-2*this.Template.ChildBorderWidth)*this.Children.length+2*this.Template.ChildBorderWidth), this.Template.ChildBorderWidth) + 'px';
	}
	
	this.GetCurrentChildTopOffset = function()
	{
		return this.Children.length * (this.SubMenuHeight-2*this.Template.ChildBorderWidth);
	}
		
	this.Create = function()
	{
		this.InitializeCalculator();
		this.CreateRootDiv();
		this.CreateTextDiv();
		this.CreateChildDiv();
		this.Children = new Array(0);
	}
	
	this.CreateChildDiv = function()
	{
		this.ChildDiv = this.CreateElement(
			this.Calculator.GetCalculatedChildTopOffset(0, this.GetBorderWidth()), 
			this.Calculator.GetCalculatedChildLeftOffset(this.Width, this.GetBorderWidth()), 
			this.Calculator.GetWidth(this.SubMenuWidth, this.GetBorderWidth()), 
			this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
		this.RootDiv.appendChild(this.ChildDiv);
	}
}

BaseMenuItem.Inherits(SubMenuItem);
function BaseMenuItem(container, text, template)
{
	this.Inherits(SubMenuItem, container, text, template);

	this.GetBorderWidth = function()
	{
		return this.Template.BaseBorderWidth;
	}
	
	this.GetDivClassName = function(hilite, loc)
	{
		if (hilite == true)
		{
			return 'div' + this.Template.CssPrefix + 'Base' + loc + 'Over';
		}
		else
		{
			return 'div' + this.Template.CssPrefix + 'Base' + loc;
		}
	}

	this.CreateChildDiv = function()
	{
		this.ChildDiv = this.CreateElement(
			this.Height,
			0,
			this.Calculator.GetWidth(this.SubMenuWidth, this.Template.ChildBorderWidth), 
			this.Calculator.GetHeight(this.Height, this.Template.ChildBorderWidth));
		this.RootDiv.appendChild(this.ChildDiv);
	}

	this.GetLeftDivWidth = function()
	{
		return this.Template.BaseLeftDivWidth;
	}
	
	this.GetRightDivWidth = function()
	{
		return this.Template.BaseRightDivWidth;
	}
	
	this.OnMouseOver = function()
	{
		this.HiliteDiv();
	}

	this.OnMouseOut = function()
	{
		if (this.Expanded == true)
		{
			return;
		}
		this.UnHiliteDiv();
	
	}

	this.Create();

	this.TextDiv.onclick = new Function("", this.Container + ".OnClick();");
	
	this.Expanded = false;
	this.OnClick = function()
	{
		if (this.Expanded == true)
		{
			this.CollapseChildrenNow();
		}
		else
		{
			this.ExpandChildrenNow();
		}
		this.Expanded = !this.Expanded;
	}

	this.TextDiv.style.border = this.GetBorderWidth() + 'px solid ' + this.Template.BaseBorderColor;
}

function GenericCalculator()
{
}

IECalculator.Inherits(GenericCalculator);
function IECalculator()
{
	this.Inherits(GenericCalculator);

	this.GetCalculatedChildLeftOffset = function(intended, borderWidth)
	{
		return intended - 2*borderWidth;
	}
	
	this.GetCalculatedChildTopOffset = function(intended, borderWidth)
	{
		return intended - 1*borderWidth;
	}
	
	this.GetWidth = function(intended)
	{
		return intended;
	}
	
	this.GetHeight = function(intended)
	{
		return intended;
	}
	
	this.GetPaddingBorderAdjustment = function(intended, borderWidth, padding)
	{
		return intended - 2*borderWidth;
	}
}

NonIECalculator.Inherits(GenericCalculator);
function NonIECalculator()
{
	this.Inherits(GenericCalculator);
	
	this.GetCalculatedChildLeftOffset = function(intended, borderWidth)
	{
		return intended - 2*borderWidth;
	}
	
	this.GetCalculatedChildTopOffset = function(intended, borderWidth)
	{
		return intended - 1*borderWidth;
	}

	this.GetWidth = function(intended, borderWidth)
	{
		return intended-2*borderWidth;
	}
	
	this.GetHeight = function(intended, borderWidth)
	{
		return intended-2*borderWidth;
	}
	
	this.GetPaddingBorderAdjustment = function(intended, borderWidth, padding)
	{
		return intended - 2*borderWidth - padding;
	}
}

function MenuTemplate()
{
	this.LocationInfo = new LocationInfo();
	this.SubMenuSizeInfo = new SizeInfo();
	
	this.LeftDivWidth = 0;//13;
	this.RightDivWidth = 0;//13;
	this.BaseLeftDivWidth = 0;
	this.BaseRightDivWidth = 0;//13;
	
	this.PaddingTop = 2;
	this.PaddingLeft = 10;
	
	this.BaseBorderWidth = 1;
	this.ChildBorderWidth = 1;
	this.BaseBorderColor = '#777';
	this.ChildBorderColor = '#777';
	
	this.CssPrefix = "";
	
	this.Clone = function()
	{
		var copy = new MenuTemplate();
		copy.LocationInfo = this.LocationInfo;
		copy.SubMenuSizeInfo = this.SubMenuSizeInfo;
		copy.LeftDivWidth = this.LeftDivWidth;
		copy.RightDivWidth = this.RightDivWidth;
		copy.BaseLeftDivWidth = this.BaseLeftDivWidth;
		copy.BaseRightDivWidth = this.BaseRightDivWidth;
		copy.PaddingTop = this.PaddingTop;
		copy.PaddingLeft = this.PaddingLeft;
		copy.BaseBorderColor = this.BaseBorderColor;
		copy.ChildBorderColor = this.ChildBorderColor;
		copy.CssPrefix = this.CssPrefix;
		return copy;
	}
}
// ENDFILE SfMenu.js ----------------------------------------------------------------------------->
