//TODO cross browser xml support removed. see nczXMLDOMWrapper.js for wrapping Mozilla xml functions with IE style
var sDataFileName = "avatar";
var xmlBlankDataControl = '<?xml version="1.0" encoding="UTF-16"?><oDataControls schemaVersion="2"></oDataControls>';

function cast(obj,type){
	//TODO this a rather simplistic version, it should support more types.
	switch(type){
		case "string":
			return obj.toString();
		case "number":
			return parseFloat(obj);
		case "boolean":
		    return obj.toString().toLowerCase()=="true";
		default:
			//return "";
			//case "undefined","function","object":
		break;
	}
}


///////////////////////////////////////////////////////////////////////////
//	oWindow object
///////////////////////////////////////////////////////////////////////////
function oWindow(name,xx,yy,ww,hh,top,act,minw,minh,intask,dock){
	this.name = name;
	this.x = xx;

	this.y = yy;
	this.w = ww;
	this.h = hh;
	this.docked = dock;
	this.top = top;
	this.active = act;
	if(minw && minw > 0){this.minWidth = minw;}else{minw = 0;}
	if(minh && minh > 0){this.minHeight = minh;}else{minh = 0;}
	this.inTaskbar = intask;

	//these don't need to be in the contructor params
	this.querystring = " ";
	this.maximized = false;
	this.size = 3;
	
	try{
		if(typeof(document.body.offsetWidth) != "undefined"){
			this.clientHeight = document.body.offsetWidth;
			this.clientWidth = document.body.offsetHeight;
		}else{
			this.clientHeight = window.innerWidth;
			this.clientWidth = window.innerHeight;
		}
	}catch(e){
		this.clientHeight = window.innerWidth;
		this.clientWidth = window.innerHeight;
	}
}

///////////////////////////////////////////////////////////////////////////
//	oUser object
///////////////////////////////////////////////////////////////////////////
function oUser(uname,def,version,currentoutfit,csettings,cwsettings){
	this.FBConnected = 0;
	this.versionNumber = 0;
	this.currentOutfit = 0;
	this.username = "";
	this.gender = "";
	this.chatSettings = "";
	this.cwSettings = "";
	this.interstVer = 0;
	this.species = "";
	this.zBucks = 0;
	this.numPrchItms = -1;
	this.prevZchiveLvl=0;
	this.desktopSettings = "";
	this.nuqGamesCashinCount = 0;
	this.nuqChatNavigateCount = 0;
	
	if(version > 0){this.versionNumber = version;}
	if(currentoutfit > 0){this.currentOutfit = currentoutfit;}
	if(uname){this.username = uname;}
	if(def){this.gender = def;}
	if(csettings) {this.chatSettings = csettings;}
	if(cwsettings) {this.cwSettings = cwsettings;}
}


///////////////////////////////////////////////////////////////////////////
//	oDataControl object
///////////////////////////////////////////////////////////////////////////
function oDataControl(){
	//window objects
	this.windowWardrobe = new oWindow();
	this.windowAvatar = new oWindow();
	this.windowLogin = new oWindow();
	this.windowChat = new oWindow();

	//user objects
	this.currentUser = new oUser();

	//Default values of the above objects set here
	//moved out of constructor for readability.
	this.initialize();
	
	//application flags
	this.flagInternetCheck = true;
	this.flagStartMinimized = false;
	this.lastLogin = 0;
	this.lastPing = 0;
	this.schemaVersion = 2;


	//Used so as not to have to examine the object
	this.arrWindowParams = ["clientWidth", "clientHeight",  "clientWidth",  "clientHeight",  "size",  "maximized",  "querystring",  "inTaskbar",  "minHeight",  "minWidth",  "active",  "top",  "docked",  "h",  "w",  "y",  "x",  "name"];
	this.arrUserParams = ["chatSettings", "cwSettings", "currentOutfit", "gender", "FBConnected", "versionNumber", "username","interstVer","species","numPrchItms","prevZchiveLvl","desktopSettings","nuqGamesCashinCount","nuqChatNavigateCount"];
	this.arrDataControlParams = ["flagInternetCheck", "flagStartMinimized", "lastLogin", "lastPing", "schemaVersion"];
	this.arrChildren = [
						["oUser","currentUser",this.currentUser,this.arrUserParams],
						["oWindow","windowWardrobe",this.windowWardrobe,this.arrWindowParams],
						["oWindow","windowAvatar",this.windowAvatar,this.arrWindowParams],
						["oWindow","windowLogin",this.windowLogin,this.arrWindowParams],
						["oWindow","windowChat",this.windowChat,this.arrWindowParams]
					   ];

	//Used to reduce number of writes
	this.xmlDoc = null;
}
oDataControl.prototype.createXMLDoc = function(){
	var bFound = false;
	if(!this.xmlDoc){
		if(window.ActiveXObject){
			var ARR_ACTIVEX = [ "MSXML2.DOMDocument","MSXML4.DOMDocument", "MSXML3.DOMDocument", "MSXML.DOMDocument", "Microsoft.XmlDom"];
			for (var i=0; i < ARR_ACTIVEX.length && !bFound; i++) {
				try {
					//try to create
					this.xmlDoc = new ActiveXObject(ARR_ACTIVEX[i]);
					this.xmlDoc.async=false;
					bFound = true                
				}catch(e){}
			}
		}
	}	
}
oDataControl.prototype.loadXML = function(strXml){
	//Init xmldoc, if needed
	this.createXMLDoc();
	//attempt to load string, or blank if fails
	//if(window.ActiveXObject){ //Firefox need diff load
	this.xmlDoc.loadXML(strXml);
	if(this.xmlDoc.parseError.errorCode !== 0){this.xmlDoc.loadXML(xmlBlankDataControl);}
	//}
	
	//Check this is in the correct schema, ish
	var nodeDataControls = this.xmlDoc.selectSingleNode("/oDataControls");
	if(!nodeDataControls){
		//Discard this xml, why is it here?, or should we save it??
		//save existing, we need /oDataControls as the root element
		var str = this.xmlDoc.xml;
		//reset 
		this.xmlDoc.loadXML(xmlBlankDataControl);
		//readd existing
		nodeDataControls = this.xmlDoc.selectSingleNode("/oDataControls");
		var elem = this.xmlDoc.createElement("oLegacyDataControl");

		elem.text = str;

		nodeDataControls.appendChild(elem);
	}
};

oDataControl.prototype.write = function(){
	//Write out current datacontrol from memory to Datacontrol filestore
	oDataCntrl.SetData(this.xmlDoc.xml);
};
oDataControl.prototype.save = function(){

	//Save user's settings to the user's datastore
	if(this.currentUser && this.currentUser.username){
		this.saveUser(this.currentUser.username);
	}

	//Save user's settings to the default datastore
	//This is kinda bad, we should reset the app when we load a user's data??
	//   but it implements a "Current User" object
	this.saveUser("");

};

oDataControl.prototype.saveUser = function(uname){

	var nodeDataControls = this.xmlDoc.selectSingleNode("/oDataControls");

	//select user's datastore
	var nodeDataControlUser = nodeDataControls.selectSingleNode("oDataControl[@name='"+uname+"']");

	//If user's node doesn't exists, create a new one
	if(!nodeDataControlUser){
		nodeDataControlUser = nodeDataControls.appendChild(this.xmlDoc.createElement("oDataControl"));
		nodeDataControlUser.setAttribute("name",uname);
	}

	//Save user's user and window objects
	//Loop through arrChildren(oUser,oWindow,oWindow, etc)
	var i = this.arrChildren.length - 1;
	do{
		var arr = this.arrChildren[i];
		var key = arr[0];
		var nm = arr[1];
		var obj = arr[2];
		var arrParams = arr[3];
		var nodeObject = nodeDataControlUser.selectSingleNode(key+"[@name='"+nm+"']");
		if(!nodeObject){
			nodeObject = nodeDataControlUser.appendChild(this.xmlDoc.createElement(key));
			nodeObject.setAttribute("name",nm);
		}
		
		//Loop through child attributes of oUser/oWindow
		var j = arrParams.length - 1;
		do{
			var namej = arrParams[j];
			var nodej = nodeObject.selectSingleNode(namej);
			if(!nodej){nodej = nodeObject.appendChild(this.xmlDoc.createElement(namej));}
			try{
				nodej.text = obj[namej].toString();
			}catch(e){}
			if(namej == "querystring"){
				//hackdaddy - why does this be set to undefined? does mal set it to null?
				nodej.setAttribute("type","string");
			}else{
				nodej.setAttribute("type",typeof(obj[namej]));
			}
		}while(j--);
	}while(i--);
	
	//Save user's other data.
	var k = this.arrDataControlParams.length - 1;
	do{
		var namek = this.arrDataControlParams[k];
		var nodek = nodeDataControlUser.selectSingleNode(namek);
		if(!nodek){
			nodek = nodeDataControlUser.appendChild(this.xmlDoc.createElement(namek));
			nodek.setAttribute("type",typeof(this[namek]));
		}
		nodek.text = this[namek];
		
	}while(k--);
};


oDataControl.prototype.load = function(){
	this.loadUser();
};

oDataControl.prototype.loadUser = function(uname){
	var nodeDataControls = this.xmlDoc.selectSingleNode("/oDataControls");
	if(!nodeDataControls){return;} //no data to load
	if(!uname){
		var nodeCurUser = this.xmlDoc.selectSingleNode("/oDataControls/oDataControl[@name='']/oUser/username");
		if(!nodeCurUser){return;} //no data to load
		uname = nodeCurUser.text;
	}

	var xpDataControlUser ="oDataControl[@name='"+uname+"']";

	//select user's node
	var nodeDataControlUser = nodeDataControls.selectSingleNode(xpDataControlUser);
	if(!nodeDataControlUser){return;} //no data to load

	//load user's user object,
	//load user's window objects
	var i = this.arrChildren.length - 1;
	do{
		var arr = this.arrChildren[i];
		var key = arr[0];
		var nm = arr[1];
		var obj = arr[2];
		var arrParams = arr[3];

		var nodeObject = nodeDataControlUser.selectSingleNode(key+"[@name='"+nm+"']");
		if(nodeObject){
		
			var j = arrParams.length - 1;
			do{
				var namej = arrParams[j];
				var nodej = nodeObject.selectSingleNode(namej);
				if(namej=="username"){obj[namej]="";}
				if(nodej){
					obj[namej] = cast(nodej.text,nodej.getAttribute("type"));
				}
			}while(j--);
		}
	}while(i--);


	// Load user's other data.
	var k = this.arrDataControlParams.length - 1;
	do{
		var namek = this.arrDataControlParams[k];
		var nodek = nodeDataControlUser.selectSingleNode(namek);
		if(nodek){
			this[namek] = cast(nodek.text,nodek.getAttribute("type"));
		}
	}while(k--);

};


//Initialise objects to default values. Rather important as they're not initialised elsewhere
oDataControl.prototype.initialize = function(){

	var ww = 0;
	var hh = 0;
	var xx = 0;
	var yy = 0;
	var wxx = window.screen.availWidth;
	var wyy = window.screen.availHeight;

	//window objects
	//oWindow(name,xx,yy,ww,hh,cWidth,cHeight,top,act,minw,minh,intask,dock)
	//Wardrobe
	ww = 870;
	hh = 570;
	xx = 0;
	yy = 0;
	this.windowWardrobe = new oWindow("Wardrobe", xx,yy,ww,hh,false,true,870,570,true,"none");

	//Avatar
	ww = 246; //226+20
	hh = 331; //263+68
	xx = 0;
	yy = Math.floor(wxx - (hh * 2));
	this.windowAvatar = new oWindow("Avatar", xx,yy,ww,hh,true,true,-1,-1,false,"none");

	//Login
	ww = 480;
	hh = 420;
	xx = wxx - ww;
	yy = wyy - hh;
	this.windowLogin = new oWindow("Login", xx,yy,ww,hh,false,false,ww,hh,true,"none");
	
	//Chat Module
	ww = 311;
	hh = 600;
	xx = 500;
	yy = 0;
	this.windowChat = new oWindow("Chat", xx,yy,ww,hh,false,true,360,311,true,"none");
};

//Function to switch datastores
function updateDataUser(newUser){

	//Load from user's data store in data control
	oData.currentUser.username = newUser.username;
	oData.loadUser(oData.currentUser.username);

	//Set timestamp 
	var now = new Date();
	oData.lastLogin = now.getTime();

	//Update the prefs to match any values set in newUser
	for(key in newUser){
		if(key != "username"){
			try{
				if(newUser[key]){oData.currentUser[key] = newUser[key];}
			}catch(e){}
		}
	}
	oData.currentUser.username = "";
	oData.currentUser.username = newUser.username;

	//write changes
	oData.save();
	oData.write();
}

//function to detect Datacontrol in Mozilla
function findPlugin(pMimeType){
	navigator.plugins.refresh(false);
	var numPlugins = navigator.plugins.length;
	for (var i = 0; i < numPlugins; i++) {
		var plugin = navigator.plugins[i];
		var numTypes = plugin.length;
        for (var j = 0; j < numTypes; j++) {
            if (plugin[j] && plugin[j].type == pMimeType) {
                	return true;
            }//end if
        }//end for
	}//end for
	return false;
}

/**** public functions ****/
/**
Add your own function named dataChangedCB (CallBack)
to handle specific updates need for datafile updates.
*** Also remember to call initData! ***
function dataChangedCB(){
	var iCurVer = oData.currentUser.versionNumber;
	updateData();
	if(oData.currentUser.versionNumber!=iCurVer){updateAvatar();}		
}
**/
if(window.ActiveXObject){
	document.write('<object CLASSID="clsid:25560540-9571-4D7B-9389-0F166788785A" id="DataControl" width="1" height="1" style="display:none;"></object>');
}else{
	if (findPlugin("application/x-mws-mywebsearchplugin")) {
		document.write("<embed id='DataControl' type='application/x-mws-mywebsearchplugin' ProgId='FunWebProducts.DataControl' style='display: none;'></embed>");		
	}
}

//Preferences Object
var oData = new oDataControl();
//DataControl ActiveX Object
var oDataCntrl=document.getElementById('DataControl');

//Global functions
function initData(){
	try{
		oDataCntrl.DataFileName = sDataFileName;
		try{oDataCntrl.OnDataChanged = dataChangedCB;}catch(e){}//Only if dataChangeDB available	
		try{
			updateData();
		}catch(ex){
			s = oDataCntrl.GetData();
			oDataCntrl.DataFileName = "corrupt";
			oDataCntrl.SetData(s);

			oDataCntrl.DataFileName = sDataFileName;
			oDataCntrl.SetData("");

			oData = new oDataControl();
		}
	}catch(e){}//blows on firefox
}

function updateData(){
	oData.loadXML(oDataCntrl.GetData());
	oData.load();
}
function setData(){ 
	oData.save();
	oData.write();
}
function generateFlashObject(url, id, width, height, oContainer, bReturn, Style, OtherAttributes, bUseCodeBase, quality, wmode, avatarParams, bPlay) {
	//is this old or new?
	if(arguments.length <= 3){
		//width is really params;
		params = arguments[2];	
	}else{
		return generateFlashObject(url,id,
			{width:width, height:height, oContainer:oContainer, bReturn:bReturn,
			 Style:Style, OtherAttributes:OtherAttributes, bUseCodeBase:bUseCodeBase,
			 quality:quality, wmode:wmode, avatarParams:avatarParams, bPlay:bPlay
			}
		);
	}

	//Function really starts here
	var defaults = {
		width:null, height:null, oContainer:null, bReturn:false,
		Style:null, OtherAttributes:null, bUseCodeBase:false,
		quality:"high", wmode:"Transparent", avatarParams:null, bPlay:false,
    	salign:"tl"
	}
	//update params with default values
	for(key in defaults){
		if(params[key] == null){
			params[key] = defaults[key];
		}
	}
	
	var VERSION_NUM=0;

	//URL required
	if (! url){ return false; }
	if (! id){ id="oAvatarControl"; }
	if(url.indexOf('?')==-1){
		url+='?';
	}
	url+='&V='+VERSION_NUM;
	
	var html = '<object id="'+id+'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"';

	if ( params.bUseCodeBase ){
		html+=' codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"';
	} else {
		html+=' codebase="#version=8,0,0,0"';
	}

	html += ' align="middle"';
	html += ' onerror="if ( typeof(generateFlashObjectError) == \'function\' ) generateFlashObjectError();return false;"';

	if (params.width){
		 html+=' width="'+params.width+'"';
	}
	if (params.height){
		html+=' height="'+params.height+'"';
	}
	if (params.Style) {
		html+=params.Style;
	}
	if (params.OtherAttributes){
		html+=params.OtherAttributes;
	}

	html+='>';

	html+='<param name="movie" value="'+url+'">';
	html+='<param name="WMode" value="'+params.wmode+'">';
	html+='<param name="allowScriptAccess" value="always">';
	html+='<param name="quality" value="'+params.quality+'">';
	html+='<param name="menu" value="0">';
	html+='<param name="play" value="'+params.bPlay+'">';
	if(params.salign){
		html+='<param name="salign" value="'+params.salign+'">';
	}
	if (params.avatarParams){
		html+='<param name="FlashVars" value="'+params.avatarParams+'">';
	}
	
	var NAV_IE=(navigator.appName.toLowerCase().indexOf("microsoft internet explorer")>-1);
	
	if (! NAV_IE) {
		html+='<embed src="'+url+'" play="'+params.bPlay+'" menu="'+params.bPlay+'" quality="'+params.quality+'" wmode="'+params.wmode+'"';
		if (params.width){ html+=' width="'+params.width+'"'; }
		if (params.height){ html+=' height="'+params.height+'"'; }
		if (params.avatarParams){ html+=' FlashVars="'+params.avatarParams+'"'; }
		html+=' name="'+id+'" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" '+
		'pluginspage="http://www.macromedia.com/go/getflashplayer" />';
	}
	
	html+='</object>';
	
	if (params.oContainer) {
		params.oContainer.innerHTML = html;
	} else if (params.bReturn) {
		return html;
	} else {
		document.write(html);	
	}
}
function generateExternalObject( html ) { document.write( html ); }

//START Chat functions 
function launchRoom(r,utm_id){
	loadDesktop("chat",r,utm_id);
}
function loadDesktop(page, r, utm_id){
	if(typeof(tbCheck) != "function" || tbCheck()){		
		var ls="HKLM,SOFTWARE\\MyWebSearch\\SkinTools,PlayerPath, Avatar desktop?page="+page;
		if(page=="chat"){
			ls+="&room="+r;
		}		
		document.getElementById("ToolbarCtlMWS").Launch(ls);
	}else{
		if(!utm_id){utm_id=18;}
		window.location.href=downloadURL+"&utm_id="+utm_id;
	}
}
//END Chat functions


//deprecated
function getCookieVal(offset){
  var endstr = document.cookie.indexOf (";", offset);
  if (endstr == -1) { endstr = document.cookie.length; }
  return unescape(document.cookie.substring(offset, endstr));
}
 
function GetCookie(name){
  var arg = name + "=";
  var alen = arg.length;
  var clen = document.cookie.length;
  var i = 0;
  while (i < clen) {
   var j = i + alen;
   if (document.cookie.substring(i, j) == arg) {
    return getCookieVal (j);
    }
   i = document.cookie.indexOf(" ", i) + 1;
   if (i == 0) break; 
   }
  return null;
}
function setCookie(name,value,expires,path,domain,secure){
	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires.toGMTString() : "" ) + 
	( ( path ) ? ";path=" + path : "" ) + 
	";domain=.zwinky.com" +
	( ( secure ) ? ";secure" : "" );
}
	
function newCookieParse(sChip,sCookVal){
	var c = new RegExp("(?:\\&|^)"+sChip+"=(?:\\w|\.)+(\\&|$)");
	var tmp = sCookVal;
	var b = 0;
	if ((tmp != null) && (tmp != "")) {	
		var rtmp = c.exec(tmp);
		if ((rtmp != null) && (typeof rtmp.length == 'number')){
			b = rtmp[0];
			if(b.indexOf("&")!=-1){//remove &
				b=b.substring(1,(b.length-1));
			}
			b=b.substring(sChip.length+1);
		}
	}
	return b;
}
function setCookieChip(sCookieName,sChipName,sChipVal){	
	var sCookieVal=GetCookie(sCookieName);
	var fSetChip=function(){
		var s=sChipName+'='+sChipVal+'&';
		//format if first chip or just append
		(sCookieVal==null)?sCookieVal='&'+s:sCookieVal+=s;
		//set
		setCookie(sCookieName,sCookieVal,getPermDate(),'/');
	}
	if(sCookieVal==null){//no cookie
		fSetChip();
	}else{
		var sExistChipVal=newCookieParse(sChipName,sCookieVal);
		if((!sExistChipVal) && (sCookieVal.indexOf(sChipName+'=')==-1)){//cookie is set, not the chip
			fSetChip();
		}//else its already set - we're good
	}
}
function getPermDate(){
	var dExp = new Date();
	dExp.setTime(dExp.getTime() + (1825*24*60*60*1000));//5 yrs
	return dExp;
}
function getToolbarObj(){
	var oCntrl=document.getElementById('ToolbarCtlMWS');
	if(oCntrl==null){//try another name
		oCntrl=document.getElementById('SettingsControl');
	}
	return oCntrl;
}

function testForTrkParams(){
	var sSHARED_COOKIE_NAME='cssP';
	var sUID_CHIP='uid';
	var sP_CHIP='p';
	
	var oCntrl=getToolbarObj();
	//UID
	if(oCntrl!=null && typeof(oCntrl.I)=='string'){
		var sUID=oCntrl.I;
		setCookieChip(sSHARED_COOKIE_NAME,sUID_CHIP,sUID);
	}
	//partner
	if(oCntrl!=null && typeof(oCntrl.P)=='string'){
		var sPartner=oCntrl.P;
		setCookieChip(sSHARED_COOKIE_NAME,sP_CHIP,sPartner);
	}
}
testForTrkParams();

var uid = newCookieParse('uid',GetCookie('cssP'));
if(typeof(uid) == "undefined") {
	uid = "0";
}