function ajax(){
	//private vars
	var url='';
	var divID='';
	var datakeys=new Array();
	var datavalues=new Array();
	var func;
	var bIsPost=false;
	var bIsSync=false;
	//------------------------

	//public members
	this.SetBlocking=_setBlocking;              //Property that determines whether this is AJAX or SJAX
	this.SetURL=_setUrl;						//writeonly prop to set url to request	[method](string)
	this.Post=_postXMLDoc;						//perform a HTTP post to specified url [method](string)
	this.Get=_loadXMLDoc;						//perform a HTTP get to specified url [method]()
	this.AddPostElement=_addData;				//Add a name/value pair to data to be posted to url [method](string,string)
	this.SetOnChangeEvent=_setfunc;				//Set the callback function [method](function)
	this.ThrowErrorOnServerError=false;		    //if true a http status of 500 (internal server error) from the requested page will throw a javascript exception, 
												//  if false the AjaxResponse object ErrorString will be set to the error message.
	
	//the following are standard items to be included in most requests, they don't effect the ajax object itself
	this.ContentID=null;							//Content Item (i.e Live stream,VOD stream) Unique Identifier [property](string)
	this.Page_Enum=-1;								//calling page identifier (i.e. Multicasts.aspx,ListContent.aspx...) [property](enumPage)
	this.Event_Enum=-1;								//calling event identifier (i.e. Play,Stop...) [property](enumEvent)
	this.SessionID='';								//aspx SessionID  [property](string)
	this.Username='';								//Logged in MCS username [property](string)
	this.LID=null;									//Access Logger id [property](int)
	this.SDUID=null;								//SDU id [property](int)
	this.PresentationID=null;						//Presentation id [property](string)
	this.Browser=null;								//Client Browser name [property](enumBrowser)
	this.Viewer=null;								//Client OS Name [property](enumViewer)
	this.OSVersion='';								//Client OSVersion [property](string)
	this.ZoneType='';								//MCS ZoneType [property](string)
	this.ClosedCaptioning=false;					//ClosedCaptioning on/off [property](bool)
	this.WMPlyrVersion=null;						//the version number of windows media player [property](string)
	//-------------------------
	
	//public methods	
	/*
		_setUrl() - set the URL that ajax.Get or ajax.Post will be communicating with
		value - string
	*/
	function _setUrl(value){
		url=value;
	}
	
	function _setBlocking(value){
	    bIsSync=value;
	}
	
	/*
		_setfunc() - set the name of the callback function, that will be called as the XMLHTTPRequest objects readystate changes
		ffunc - function - (passed as reference, not passed in as string)
	*/
	function _setfunc(ffunc){
		func=ffunc;
	}
	
	/*
		_addData() - add name/value pair to collection. This will be posted to server upon ajax.Post
		Key - string 
		Value - string
	*/
	function _addData(Key,Value){
		datakeys[datakeys.length]=Key;
		datavalues[datavalues.length]=escape(Value);
	}

	/*
		_postXMLDoc() - create a HTTP post to the give url.
		xml - string - option parameter. User may provide an XML fragment to be posted to server. All other items will be ignored.
	*/
	function _postXMLDoc(xml) {
		getReq();
		bIsPost=true;
		if(req) {
			if(url==''){
				throw 'URL has not been set!';
				return;
			}
			var data;
			if(xml==null){
				var dom=new XMLDom();
				dom.AddRoot("Request"); //add root element
				//add standard request items
				if(this.Page_Enum>-1){dom.AddElement('Page',this.Page_Enum);}
				if(this.Event_Enum>-1){dom.AddElement('Event',this.Event_Enum);}
				dom.AddElement('LID',this.LID);
				dom.AddElement('SDUID',this.SDUID);
				dom.AddElement('PresentationID',this.PresentationID);
				dom.AddElement('SessionID',this.SessionID);
				dom.AddElement('Username',this.Username);
				dom.AddElement('ContentID',this.ContentID);
				dom.AddElement('Viewer',this.Viewer);
				dom.AddElement('Browser',this.Browser);
				dom.AddElement('OSVersion',this.OSVersion);
				dom.AddElement('ZoneType',this.ZoneType);
				dom.AddElement('ClosedCaptioning',this.ClosedCaptioning);
				dom.AddElement('WMPlyrVersion',this.WMPlyrVersion);
				
				//add any user added items
				for(var i=0;i<datavalues.length;i++){
					dom.AddCDataElement(datakeys[i],datavalues[i]);
				}
				xml=dom.toXML();
			}
			
			data="xmlinput="+xml;
			req.onreadystatechange = processReqChange;
			req.open("POST", url, !bIsSync);
			req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			req.send(data);
			//Ajax call is failing on external player close SCR 5671
            pause(100)
		}
	}

    function pause(millis) 
    {
        //Pause for millis Milliseconds
        var date = new Date();
        var curDate = null;
        do { curDate = new Date(); } 
        while(curDate-date < millis);
    } 
	
	/*
		_loadXMLDoc() - request a give url from the server. No data is sent to server.
	*/
	function _loadXMLDoc() {
		getReq();
		if(req) {
			if(url==''){
				throw 'URL has not been set!';
				return;
			}
			req.onreadystatechange = processReqChange;
			req.open("GET", url, !bIsSync);
			req.send("");
		}
	}
	//-------------------------
	
	//private methods
	/*
		getReq() - get the XMLHttpRequest object for various browsers
	*/
	function getReq(){
		req = false;
		// branch for native XMLHttpRequest object
		if(window.XMLHttpRequest) {
    		try {
				req = new XMLHttpRequest();
			} catch(e) {
				req = false;
			}
		// branch for IE/Windows ActiveX version
		} else if(window.ActiveXObject) {
       		try {
        		req = new ActiveXObject("Msxml2.XMLHTTP");
      		} catch(e) {
        		try {
          			req = new ActiveXObject("Microsoft.XMLHTTP");
        		} catch(e) {
          			req = false;
        		}
			}
		}
		if(!req){
			throw 'XMLHttpRequest object could not be initialized';
		}
	}
	
	/*
		dispose() - null out objects
	*/
	function dispose(){
		req=null;
		url='';
	}
	
	/*
		getValueFromNode() - helper function to get the string value of a given xml tagname
		dom - XMLDom object
		NodeTagName - string - the name of the xml element you want the innertext of.
	*/
	function getValueFromNode(dom,NodeTagName){
		var e=dom.GetSingleElement('/Response/'+NodeTagName);
		if(e==null)
			return "";
		else
			return e.Value;
	}

	/*
	processReqChange() - event handler for the XMLHttpRequest's onreadystatechange event
	readyState Codes:
	0 = uninitialized
	1 = loading
	2 = loaded
	3 = interactive
	4 = complete
	
	Status codes are http status codes
	see:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
	code 200=OK
	*/
	function processReqChange() {
		if(req==null){return;}
		if (req.readyState == 4) {
			var resp=new AjaxResponse();
			if(req.status==500){
				if(this.ThrowErrorOnServerError){
					throw "Server Error!:"+req.responseText;
				}else{
					resp.ErrorString="Server Error!:"+FormatServerError(req.responseText);
				}
			}else if(req.status==404){
				if(this.ThrowErrorOnServerError){
					throw "Server Error!:Handler page was not found";
				}else{
					resp.ErrorString="Server Error!:Handler page was not found";
				}
			}else{ //req.status!=500
				if(req.responseText==""){
						resp.ErrorString="Null response recieved from server.";
				}else{
					if(bIsPost){
						var dom=new XMLDom();
						dom.FromXML(req.responseText);
						resp.IsPost=true;
						resp.ErrorString=getValueFromNode(dom,'ErrorString');
						resp.ContinueAfterError=getValueFromNode(dom,'Continue');
						resp.URL=getValueFromNode(dom,'URL');
						resp.LID=getValueFromNode(dom,'LID');
						resp.ReturnValue=getValueFromNode(dom,'ReturnValue');
						resp.JSCallback=getValueFromNode(dom,'JSCallback');
						resp.Message=getValueFromNode(dom,'Message');
						resp.StreamType=getValueFromNode(dom,'StreamType');
						resp.SDUControlTemplateFileName=getValueFromNode(dom,'SDUControlTemplateFileName');
						resp.ContentExpirationID=getValueFromNode(dom,'ContentExpirationID');
						resp.Event=getValueFromNode(dom,'Event');
						resp.VODServerTypeName=getValueFromNode(dom,'ServerTypeName');
						resp.VODServerSoftwareRevision=getValueFromNode(dom,'SoftwareRevision');
						var offset=getValueFromNode(dom,'StartOffset');
						resp.StartOffset=(offset == "") ? 0: parseInt(offset);
						resp.Duration=getValueFromNode(dom,'Duration');
					}else{
						resp.IsPost=false;
					}
					resp.ServerResponseString=req.responseText; //if this is a Get then responseText will just be markup from server, will be XML on a Post
				}
			}
			func(req.readyState,req.status,resp);
			dispose();
		}else{ //readyState!=4
			func(req.readyState);
		}
	}
	//-------------------------
}
function FormatServerError(text){
	var ret='';
	var s=text.indexOf('<title>')+7;
	var e=text.indexOf('</title>',s);
	ret=text.substring(s,e);
	return ret;
}

//response object
function AjaxResponse(){
	this.ErrorString="";								//Error message to display via alert()
	this.ContinueAfterError=false;						//If true client script will continue processing after error message is displayed
	this.URL="";										//URL of media to play either live url,vod url, or presentation url
	this.LID="";										//Log ID - PK from loggin table, for Access Logging
	this.ReturnValue="";								//Generic return value
	this.JSCallback="";									//JavaScript function to call upon response
	this.Message="";									//Text for global message area of MCS
	this.StreamType="";									//MPEG-1,MPEG-2,MPEG-4,WM,Presentation
	this.SDUControlTemplateFileName="";					//SDU control template filename [template].html
	this.IsPost=false;									//if ajax.Post was called this will be true, if ajax.Get then false
	this.ServerResponseString='';						//unaltered response string from page requested via ajax.URL
	this.ContentExpirationID='';						//the PID
	this.Event=-1;										//enumEvent
	this.VODServerTypeName='';							//name of the VOD server type, i.e. Infovalue,Kassenna, etc
	this.VODServerSoftwareRevision='';					//the version number of the vod server software (kassena specifically)
	this.StartOffset=0;                                 //time offset to start playing
	this.Duration="";                                   //duration of content including portion skipped by offset
}

//enumerations - these correspond to serverside enums!
//enumPage = which mcs page the object is being called from
var enumPage={
	LiveContent:0,				//Multicasts.aspx
	VideoLibrary:1,				//ListContent.aspx
	Thumbnail:2,				//AdminThumbnail.aspx
	PresentationLive:3,		    //index.htm in Live Mode
	PresentationStored:4,	    //index.htm in Stored Mode
	Unknown:5,					//unknown
	ScheduledPrograms:6		    //Scheduled.aspx
}
//enumEvent = client event
var enumEvent={
	Play:0,						//Play Button click
	ContentSelect:1,			//Content item clicked	
	Stop:2,						//Stop button clicked
	Record:3,					//record button clicked
	PageChange:4,				//onunload event fired
	ThumbnailCreate:5,
	ThumbnailDelete:6,
	VBrickSTB_BeginVideoEvent:7,
	VBrickSTB_EndVideoEvent:8,
	BookMarkCreate:9,
	PlayListSelect:10			//Playlist click (list or item)
}
var enumBrowser={
	Unknown:0,
	IE:1,
	FireFox:2,
	Safari:3,
	Opera:4
}
var enumViewer={
	Unknown:0,
	WindowsPC:1,
	MacPC:2,
	LinuxPC:3,
	VBrickSTB:4,
	Amino:5	
}
