/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	Slip.js - Lotto slip object constructor.
	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	(c) Copyright 2003, 2007, 2008, Finsoft Ltd
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

var LBS = null;
var LBS_Constructor = function() {
	var self = this;
	var _bReady = false;

	/*
		PROPERTIES	- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	*/
	var _oForm = null;

	this.bOpenSlipOnUpdate = false;
	this.sLoadURL = "/numbers/incasp/updateLBS.asp";
	this.sSlipURL = "/numbers/SlipLayout.asp";
	this.sSlipBodyID = "LBS_body";
	this.sFormID = "LBS_form";

	this.sCurrency = "";
	this.nMinimumStake = 0;
	this.bIsTotalStakeTooLow = false;
	
	this.bSlipEmpty = true;
	/*
		METHODS		- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	*/
	//	
	this.Init = function() {
		//	get form pointer
		var oForm = document.getElementById(self.sFormID);
		//	slip form submit
		this.onsubmit = function() {
			var bAtLeastOne = false;
			var nMkBound = this.elements["mkub"].value;
		
			//	check if at least one stake is entered
			var aStake;
				aStake = this.elements["LBS_stake"];
		
				if (aStake.length) {
					for (var j=0;j<aStake.length;j++) {
						if (aStake[j].value != "") {
							bAtLeastOne = true;
							break;
						}
					}
				} else {
					bAtLeastOne = (aStake.value != "");
				}
		
			if (!bAtLeastOne) {
				alert(NB_MsgSlipNoStakeEntered);
				return false;
			} else {
				var sValue;
				//	check for proper values being entered
					aStake = this.elements["LBS_stake"];
			
					if (aStake.length) {
						for (var j=0;j<aStake.length;j++) {
							sValue = aStake[j].value;
							if (sValue != "") {
								if ( isNaN(sValue) || parseFloat(sValue) <= 0 ) {
									alert(NB_MsgSlipInvalidStakeValue.replace(/#01/, sValue));
									aStake[j].focus();
									return false;
								}
								aStake[j].value = parseFloat(sValue);
								aStake[j].blur();
							}
						}
					} else {
							sValue = aStake.value;
							if ( isNaN(sValue) || parseFloat(sValue) <= 0 ) {
								alert(NB_MsgSlipInvalidStakeValue.replace(/#01/, sValue));
								aStake.focus();
								return false;
							}
							aStake.value = parseFloat(sValue);
							aStake.blur();
					}
			}
/*		
			if (BS.bIsTotalStakeTooLow) {
				if (BS_MsgTotalStakeTooLow != "") alert(BS_MsgTotalStakeTooLow + " " + self.sCurrency + " " + self.nMinimumStake);
				return false;
			}
*/
			return true;
		};
		//	re-read user state
		self.RestoreUserState();
		//	
		self.ClientInit();

		_bReady = true;
	};

	//	round and format the number, to always have decimals
	this.Round = function(nNum, nDecimals) {
		if (!nDecimals) nDecimals = nNumOfDecimals;
		return SG_GetNumWithDecimals(SG_Round(nNum, nDecimals), nDecimals);
	};

	//	this executes remote call
	this.oSrv = new AjaxConn();
	//	this is what will happen after each update
	if (this.oSrv)
		this.oSrv.Done = function() {
			//	if response is empty, do nothing
			var sResponse = this.responseText;
			if (sResponse == "") return;

			//	remote call will return entire new slip content - simply dump it in
			var oSlipBody = document.getElementById(LBS.sSlipBodyID);
			if (!oSlipBody) return;
			oSlipBody.innerHTML = sResponse;
			
			//	check: if ADD has failed, then ... (TBD)
			var oForm = document.getElementById(BS.sFormID);
			if (oForm) {
			}

			//	reenable all behaviors - calculations, links override etc.
			LBS.SetupBehavior();

			//	re-read user state
			LBS.RestoreUserState();

			//	hide the loader indicator
			LBS.HideLoader();

			//after update client overides
			LBS.AfterUpdate();
			
			//	should slip be opened automatically?
			if (self.bOpenSlipOnUpdate)
				self.ShowHide(null, true);
			//	always re-set to false. it will be set to true when needed
			self.bOpenSlipOnUpdate = false;
		};

	//	this is called from numbers.js, when "Open betslip" button is clicked
	this.LoadSlip = function(sQS) {
		if (!_bReady) return;

		//	show the loader indicator
		self.ShowLoader();

		//	automatically open the slip when it is loaded from the main page
		self.bOpenSlipOnUpdate = true;

		//	clear the save state
		setCookie("lbsuserstate", "");

		//	send request
		var sURL = self.sLoadURL;
		self.oSrv.connect("POST", sURL, sQS);
	};

	//	mainly for outside use, simple refresh of the state. called on page load
	this.Refresh = function() {
		if (!_bReady) return;

		//	show the loader indicator
		self.ShowLoader();

		var sQS = "", sURL = self.sSlipURL;
		self.oSrv.connect("POST", sURL, sQS);
	};

	//	override links as needed
	this.SetupBehavior = function() {
		//	BS_body exists only on layer slip, not on full page slip
		var oSlipBody = document.getElementById(self.sSlipBodyID);

		//	- - - - - ONLY ON LAYER SLIP - - - - -

		//	intercept remove clicks on the layer slip
		if (oSlipBody) xGetElementsByClassName("x", oSlipBody, "*", function(oTD) {
			var oA;
			if (oTD.nodeName.toLowerCase() == "a")
				oA = oTD;
			else
				oA = oTD.getElementsByTagName("a")[0];
			if (!oA) return;

			oA.onclick = function() {
				//	show the loader indicator
				BS.ShowLoader();

				//	clean URL
				var sURL = this.href.replace(/\&amp;/gi, '&');

				//	split URL and querystring
				var nPos = sURL.indexOf("?");
				sQS = sURL.substring(nPos+1);
				sURL = sURL.substring(0, nPos);

				//	contact server to get current slip content
				LBS.oSrv.connect("POST", sURL, sQS);

				return false;
			};
		});

		//	- - - - - ON BOTH FULL PAGE & LAYER SLIP - - - - -

		//	slip form exists on both slips
		var oSlipForm = document.getElementById(self.sFormID);
		//	setup stake update to...
		if (oSlipForm) xGetElementsByClassName("lbsstake", oSlipForm, "td", function(oTD) {
			var oStake = oTD.getElementsByTagName("input")[0];
			if (!oStake) return;
			//	since there is a stake, slip is not empty
			LBS.bSlipEmpty = false;
			//	setup handler
			oStake.onkeyup = function() {
				//	...trigger calculations
				LBS.Calc(this.form);
				//	...and save stake values in cookie (along with other stuff)
				LBS.SaveState(this.form);
			};
		});
		//	setup bet type update
		if (oSlipForm) {
			var aTmp, aTmp2 = oSlipForm.elements['bettype'];
			if (aTmp2) {
				if (aTmp2.type == 'select-one') {
					//	if just one bettype drop-down
					aTmp = new Array(); aTmp[0] = aTmp2;
					//	otherwise it's already an array
				} else
					aTmp = aTmp2;
				//	attach handlers to each of them
				for (var i=0;i<aTmp.length;i++) {
					//	setup handler
					if (aTmp[i].type == 'select-one') aTmp[i].onchange = function() {
						//	update bet type name
						var nRow = this.id.substring(8);	//	this.id == "bettype_X"
						var oHidFld = document.getElementById('bettypename_' + nRow);
						if (oHidFld) {
							oHidFld.value = BS_aBT[this.options[this.selectedIndex].value][0];
						}
						//	...trigger calculations
						LBS.Calc(this.form);
						//	...and save bet type values in cookie (along with other stuff)
						LBS.SaveState(this.form);
					};
				}
			}
		}
	};

	//	display loader, position it over entire betslip body
	this.ShowLoader = function() {
		var oLoader = document.getElementById("lottoloader");
		if (!oLoader) return;
		var oBS = document.getElementById(self.sSlipBodyID);
		xTop(oLoader, xTop(oBS));
		xWidth(oLoader, xWidth(oBS));
		xHeight(oLoader, xHeight(oBS));
		oLoader.style.visibility = "visible";
	};
	
	//	display loader, position it over entire betslip
	this.HideLoader = function() {
		var oLoader = document.getElementById("lottoloader");
		if (!oLoader) return;
		oLoader.style.visibility = "hidden";
	};

	//	save the data entered by punter into cookie, as JSON
	this.SaveState = function(oForm) {
		var oState = { Bettype: {}, Stake: {} };

		//	BETTYPEs
		var aTmp, aTmp2 = oForm.elements['bettype'];
		if (aTmp2.type == 'select-one') {
			//	if just one bettype drop-down
			aTmp = new Array(); aTmp[0] = aTmp2;
			//	otherwise it's already an array
		} else
			aTmp = aTmp2;
		//	collect set values for each
		for (var i=0;i<aTmp.length;i++) {
			if (aTmp[i].type == 'select-one') 
				oState.Bettype[aTmp[i].id] = aTmp[i].selectedIndex;
			else
				oState.Bettype[aTmp[i].id] = aTmp[i].value;
		}

		//	STAKEs
		aTmp2 = oForm.elements['LBS_stake'];
		if (aTmp2.type == 'text') {
			//	if just one stake field
			aTmp = new Array(); aTmp[0] = aTmp2;
			//	otherwise it's already an array
		} else
			aTmp = aTmp2;
		//	collect set values for each
		for (var i=0;i<aTmp.length;i++)
			oState.Stake[aTmp[i].id] = aTmp[i].value;

		//	ok, now transform into string using JSON and save into cookie
		setCookie("lbsuserstate", JSON.stringify(oState));
	};

	//	restore, from cookie, the data entered by punter
	this.RestoreUserState = function() {
		//	get the state from cookie
		var s = "";
		var oState = ((s=getCookie("lbsuserstate")) != "") ? JSON.parse(s) : null;
		if (!oState) return;

		//	restore bettypes
		var oFld, oFld2;
		for (var i in oState.Bettype) {
			if (!(oFld = document.getElementById(i))) continue;
			if (!(oFld2 = document.getElementById(i.replace('bettype', 'bettypename')))) continue;
			if (oFld.type == 'select-one') {
				oFld.selectedIndex = oState.Bettype[i];
				oFld2.value = BS_aBT[oFld.options[oFld.selectedIndex].value][0];
			} else {
				oFld.value = oState.Bettype[i];
				oFld2.value = BS_aBT[oFld.value][0];
			}
		}

		//	restore stakes
		for (i in oState.Stake) {
			if (!(oFld = document.getElementById(i))) continue;
			oFld.value = oState.Stake[i];
		}

		//	re-calculate cost and return
		self.Calc(document.getElementById(self.sFormID));
	};

	this.Calc = function(oForm) {
		if (!oForm) return false;
		//	save the reference to slip form
		_oForm = oForm;
		//	call the calculator
		var sAction = oForm.action;
		oForm.target = LBS_oCalcFrame.sName;
		oForm.action = "/numbers/calc.asp";
		oForm.submit();
		//	revert things back, to get ready 4 placement
		oForm.action = sAction;
		oForm.target = "";
		return false;
	};

	this.UpdateValues = function(aCost, aReturn) {
		var oFld, oTD, aFld, i, j, oForm = _oForm, sTmp;
		if (!oForm) return;
	
		var nTotalCost = 0;
		var nTotalReturn = 0;
		var nTmp;
		
		var sBetcostID = "LBS_betcost";
	
		aFld = oForm.elements[sBetcostID];
		if (aFld) {
			for (j in aCost) {
				sTmp = aCost[j];
				if (sTmp != "")
					sTmp = SG_GetNumWithDecimals(sTmp, nNumOfDecimals)
	
				if (aFld.length)
					aFld[j].value = sTmp;
				else
					aFld.value = sTmp;
					
				oTD = document.getElementById('id' + sBetcostID + '_' + j);
				if (oTD) oTD.innerHTML = sTmp;
	
				if (aCost[j] != "" && !isNaN(aCost[j])) {
					nTmp = parseFloat(aCost[j]);
					nTotalCost += nTmp;
				}
			}
		}
		
		var sBetreturnID = "LBS_betreturn";
	
		aFld = oForm.elements[sBetreturnID];
		if (aFld) {
			for (j in aReturn) {
				sTmp = aReturn[j];
				if (sTmp != "")
					sTmp = SG_GetNumWithDecimals(sTmp, nNumOfDecimals)
	
				if (aFld.length)
					aFld[j].value = sTmp;
				else
					aFld.value = sTmp;
	
				oTD = document.getElementById('id' + sBetreturnID + '_' + j);
				if (oTD) oTD.innerHTML = sTmp;
	
				if (aReturn[j] != "" && !isNaN(aReturn[j])) {
					nTmp = parseFloat(aReturn[j]);
					nTotalReturn += nTmp;
				}
			}
		}
	
		var nMk = 0, oMkCount = oForm.elements["mk4pub"];
		if (oMkCount)
			nMk = parseInt(oMkCount.value, 10)+1;
	
		nTotalCost *= nMk;
		nTotalReturn *= nMk;
		
		var sBetcosttotal = "LBS_betcost_total";
		var sBetreturntotal = "LBS_betreturn_total";
	
		var sTotalCost = SG_GetNumWithDecimals(nTotalCost, nNumOfDecimals);
		oFld = oForm.elements[sBetcosttotal];
		if (oFld)
			oFld.value = sTotalCost;
		oTD = document.getElementById('id'+sBetcosttotal);
		if (oTD)
			oTD.innerHTML = sTotalCost;
	
		var sTotalReturn = SG_GetNumWithDecimals(nTotalReturn, nNumOfDecimals);
		oFld = oForm.elements[sBetreturntotal];
		if (oFld)
			oFld.value = sTotalReturn;
		oTD = document.getElementById('id'+sBetreturntotal);
		if (oTD)
			oTD.innerHTML = sTotalReturn;
	};

	//	extendability for specific client needs
	//	1. toggle slip on/off
	this.ShowHide = function() {return true;};
	//	2. change header
	this.Header = function() {return true;};
	//	3. init
	this.ClientInit = function() {};
	// 4. after update
	this.AfterUpdate =function() {};

	return this;
};

//	make an instance
LBS = new LBS_Constructor();

//	execute Init on page load
DomLoaded.load(LBS.Init);

//	update instance of basic constructor
if (LBS) {
	LBS.ClientInit = function() {
		var oHeader = document.getElementById("LBS_header");
		if (!oHeader) return;
		//	setup header clickability
		oHeader.onclick = function() {
			if (LBS)
				LBS.ShowHide(this);
			this.blur();
		};

		return true;
	};

	LBS.ShowHide = function(oHeader, bForceOpen) {
		if (!oHeader) oHeader = document.getElementById("LBS_header");
		if (!oHeader) return;
		var oBS = oHeader.parentNode;
		if (oBS.className.indexOf("lbshide") != -1) {
			//	show BS body
			oBS.className = oBS.className.replace(/lbshide/gi, "lbsshow");
			if (typeof(WCH) != "undefined" && WCH) WCH.Apply(oBS, document.getElementById("cmain"), true);
		} else if (!bForceOpen) {
			//	hide BS body
			oBS.className = oBS.className.replace(/lbsshow/gi, "lbshide");
			if (typeof(WCH) != "undefined" && WCH) WCH.Discard(oBS, document.getElementById("cmain"));
		}
	};
}
