/* BetSlip shell
I thought I'd create a rough shell of the betslip functionality so whoever takes it over will have somewhere to start
*/

// ============================ Container variable ============================ //
// let's try hard not to pollute the global object - makes debugging *Much* easier
// we'll put everything in a uWin
var uWin = {
    config: {
        api_url: "/_api-scripts/www/RPC-JSON/"
    },
    debug: function() {
        /*if ("undefined" !== typeof(console)) {
            if ("undefined" !== typeof(console.log)) {
                console.log.apply(console, arguments);
            }
        }*/
    },
    objects: {},
    test: {}
};

// contains:
//	objects: {},
//	state: {},
//	api: {},
//	ui: {},
//	site: {}
//	test: {}
// ============================ Utilities ============================ //
// provides a shortcut to inheritance - makes 'this' a subclass of 'parent'
Function.prototype.inherits = function(parent) {
    if ("function" === typeof(parent)) {
        this.prototype = new parent();
    }
    return this;
};

// allows you to bind a function to the specified scope - basically, let's you set what the 'this' of a function refers to
Function.prototype.bind = function(context) {
    var fn = this;
    return function() {
        return fn.apply(context, arguments);
    };
};

// cross browser Array.each - uses native (fast) Array.forEach if it exists (eg. FireFox, Safari, Chrome)
if ("function" === typeof([].forEach)) {
    Array.prototype.each = Array.prototype.forEach;
} else {
    Array.prototype.each = function(fn) {
        for (var i = 0, l = this.length; i < l; i++) {
            fn(this[i], i, this);
        }
    };
}

// cross browser Array.filter based on example on the MDC page
if (!Array.prototype.filter) {
    Array.prototype.filter = function(fn) {
        var res = [];
        for (var i = 0, l = this.length; i < l; i++) {
            var val = this[i];
            // in case fn mutates this
            if (fn.call(this, val, i, this)) {
                res.push(val);
            }
        }
        return res;
    };
}

// ============================ Core Object (superclass) ============================ //
uWin.objects.uWin_OBJECT = function() {
    this.get = function(property) {
        return this[property];
    };
    this.set = function(property, value) {
        this[property] = value;
    };
    this.populate = function(data) {
        if (data) {
            for (var prop in this) {
                // don't set to undefined - we're using null as the 'empty' marker
                if ("undefined" !== typeof(data[prop]) && "_parent" !== prop) {
                    // do not want to filter with ownProperty because we're inheriting
                    this[prop] = data[prop];
                }
            }
        }
        return this;
    };
};

// ============================ Re-usable Objects ============================ //
uWin.objects.BetLeg = function(data) {
    this.EachWayPlaceTerms = null;
    this.EachWayReduction = null;
    this.Handicap = null;
    this.IDFOEventScorecast = null;
    this.IDFOPriceType = "";
	this.IDFOMarket = 0;
    // "CP";
    this.IDFOSelection = 0;
    // 17502591.2;
    this.InterrelationTag = null;
    this.IsTrap = false;
    this.LowerBand = null;
    this.PriceDown = 0;
    // 1;
    this.PriceUp = 0;
    // 3;
    this.SystemTag = null;
    this.UpperBand = null;

    this.populate(data);
}.inherits(uWin.objects.uWin_OBJECT);

uWin.objects.Bet = function(data) {
    this.BetTypeName = null;
    // "Single"
    this.IDFOBetType = null;
    // "S"
    this.IDFOMultiRacePool = null;
    this.IsPool = false;
    this.PlaceStake = null;
    this.ShowStake = null;
    this.WinStake = null;
    // 1
    this.BetLegs = [];
    // aray of betLegs
    this.populate(data);
}.inherits(uWin.objects.uWin_OBJECT);

uWin.objects.BetSlipCommon = function(data) {
    this.IsFree = false;

    this.populate(data);
}.inherits(uWin.objects.uWin_OBJECT);

uWin.objects.BetSlipInbound = function(data) {
    this.Bets = [];
    // array of bet objects
    this.populate(data);
}.inherits(uWin.objects.BetSlipCommon);

// NOTE this object inherits differently to the xsd definition.
// instead of inheriting from BetCommon, it inherits form BetInbound. This is to flag the fact that I'm using BetSlipOutbound to store state, because it's functionally the superset of the BetSlip
uWin.objects.BetSlipOutbound = function(data) {
    this.ExternalReference = null;
    // "632"
    this.IDFOBetSlip = null;
    // "NEZcPnvZ+bndVHRkR6JW40udKjx0Y8CA9espMLHaTfA="
    this.TopupAmount = null;
    this.TotalStake = 1;

    this.Status = null;

    this.populate(data);
}.inherits(uWin.objects.BetSlipInbound);

uWin.objects.Status = function(data) {
    this.StatusCode = null;
    this.StatusText = null;
    this.State = null;
    // 2
    this.DetailedStatus = null;
    // 1
    this.populate(data);
}.inherits(uWin.objects.uWin_OBJECT);

uWin.objects.TexasContext = function(data) {
    //	no need to pass these properties about - API will add them from session token
    //	this.ClientIPAddress = null;
    //	this.IDDCLanguage = "UK";
    //	this.IDMMBusinessUnit = null;
    this.SessionToken = null;

    this.populate(data);
}.inherits(uWin.objects.uWin_OBJECT);

// ============================ State ============================ //
uWin.state = new
function($) {
    var self = this;

    var texasContext = new uWin.objects.TexasContext();
    var betLegs = [];
    var bets = [];
    var availableBets = [];
	var freeBetsFlag = false;
	var resetBetSlipFlag = false;

    // when a bet is removed from the slip, we'll need to take it out of the state
    var removeBetLeg = function(IDFOSelection) {
        betLegs = betLegs.filter(function(betLeg) {
            return IDFOSelection !== betLeg.IDFOSelection;
        });
        return betLegs;
    };
    // checks if the IDFOSelection passed already exists as a betLeg in the betslip's state
    var betLegExists = function(IDFOSelection) {
        var exists = false;
        betLegs.each(function(betLeg) {
            if (betLeg.IDFOSelection === IDFOSelection) {
                exists = true;
            }
        });
        return exists;
    };
	// create betSlip object
	var createBetSlip = function(checkedBets) {
		// create singles betSlip if type-C1 is empty
		var newBets = [];
		if (!(parseFloat($("#type-C1" + " div.slip-stake input[type='text']").val()) || 0)) {
            for (var i = 0; i < checkedBets.length; i++) {
				// check if stake is given
				if (parseFloat($("#bs" + checkedBets[i].IDFOSelection.replace(/\./, '\\.') + " input[type='text']").val()) || 0) {
					newBets.push({
		                    "BetLegs": [checkedBets[i]],
		                    "WinStake": parseFloat($("#bs" + checkedBets[i].IDFOSelection.replace(/\./, '\\.') + " input[type='text']").val()),
		                    "PlaceStake": null,
		                    "ShowStake": null,
		                    "IDFOBetType": "S",
		                    "BetTypeName": "Single",
		                    "IDFOMultiRacePool": null,
		                    "IsPool": false
		            });
				}
            }
		}
		// create accumulators betSlip
		if (availableBets) {
			for (var i = 0; i < availableBets.length; i++) {
				var betType = availableBets[i]["IDFOBetType"];
				if (parseFloat($("#type-" + betType + " div.slip-stake input[type='text']").val()) || 0) {
					newBets.push({
	                    "BetLegs": checkedBets,
	                    "WinStake": parseFloat($("#type-" + betType + " div.slip-stake input[type='text']").val()),
	                    "PlaceStake": null,
	                    "ShowStake": null,
	                    "IDFOBetType": betType,
	                    "BetTypeName": availableBets[i]["Name"],
	                    "IDFOMultiRacePool": null,
	                    "IsPool": false
	                });
				}
			}
		}
		return newBets;
	}
    // debugging
    this.getBetLegs = function() {
        return betLegs;
    };

    this.setBetLegs = function(value) {
        betLegs = value;
    };

	this.setFreeBets = function(value) {			
		uWin.ui.startAjaxLoader();
		freeBetsFlag = value;
		var priceUp, priceDown, decimals, changeFlag = false;
		for (var i = 0; i < betLegs.length; i++) {
			priceUp = betLegs[i].PriceUp;
			priceDown = betLegs[i].PriceDown;
			decimals = (priceUp / priceDown) + 1;
			// if free bets true, uncheck < 1.50 selections
			if (value && decimals < 1.50) {
				uWin.ui.uncheckSelection(betLegs[i].IDFOSelection);
				changeFlag = true;
			}
			// if free bets false, check < 1.50 selections back
			if (!value && decimals < 1.50) {
				uWin.ui.checkSelection(betLegs[i].IDFOSelection);
				changeFlag = true;
			}
		}
		// if something was changed, than ask for accumulators and calculate
		if (changeFlag) {
			// get allowed bet types and draw accumulators
			var betTypes = this.getAllowedBetTypes();
			if (betTypes) {
				uWin.ui.drawBetTypes(betTypes);
			} else {
				$("#bet-option div.slip-stake input[type='text']").each(function() {
					$(this).unbind();
				});
				$("#bet-option").empty();			
			}
			// count betslip after changing input
			var calculatedBets = this.calculateBetSlip();
			uWin.ui.calculateBetSlip(calculatedBets);				
		}
		uWin.ui.stopAjaxLoader();
	}

	this.freeBetsFlagReset = function() {
		freeBetsFlag = false;
	}

    // use BetSlipOutbound because it's a superset of the others
    this.BetSlip = new uWin.objects.BetSlipOutbound();

    // adds bet to
    this.addBet = function(betData, element) {
        // check if this betleg is already in
        if (betLegExists(betData.IDFOSelection)) {
            uWin.debug("Bet already exists");
            alert(_("You've already placed this bet."));
            return false;
        } else {
            uWin.debug("add bet");
            var betLeg = new uWin.objects.BetLeg(betData);
			if (betLegs.length == 15) {
	            uWin.debug("You can not place more than 15 selections");
	            alert(_("You've reached a maximum of 15 selections."));
	            return false;		
			}
            betLegs.push(betLeg);
            // call ui function to display in bet slip
            uWin.ui.addBet(betData, element, resetBetSlipFlag);
			resetBetSlipFlag = false;
			// save current betslip
			uWin.api.storeValue("betSlipHtml", $("#bet-window").html());
			uWin.api.storeValue("betLegs", betLegs);
            // recalculate allowed bet types
            var bet = new uWin.objects.Bet({
                BetLegs: betLegs
            });
            uWin.debug(bet);
            return betLeg;
        }
    };

    this.removeBet = function(IDFOSelection) {
        if (removeBetLeg(IDFOSelection)) {
			// call ui function to remove bet from bet slip
			uWin.ui.startAjaxLoader();
            uWin.ui.removeBet(IDFOSelection);
			if (betLegs.length == 0) {
				uWin.api.deleteValue("betSlipHtml");
				uWin.api.deleteValue("betLegs");
			} else {
				// overwrite current betslip
				uWin.api.storeValue("betSlipHtml", $("#bet-window").html());
				uWin.api.storeValue("betLegs", betLegs);
			}
			// get allowed bet types and draw accumulators
			var betTypes = this.getAllowedBetTypes();
			if (betTypes) {
				uWin.ui.drawBetTypes(betTypes);
			} else {
				$("#bet-option div.slip-stake input[type='text']").each(function() {
					$(this).unbind();
				});
				$("#bet-option").empty();			
			}
			// count betslip after changing input
			var calculatedBets = this.calculateBetSlip();
			uWin.ui.calculateBetSlip(calculatedBets);
			uWin.ui.stopAjaxLoader();
            return true;
        } else {
            return false;
        }
    };

    this.getAllowedBetTypes = function() {
		/*var isLoggedIn = uWin.api.isLoggedIn();
        if (!isLoggedIn) {
			return false;
		}*/
		var checkedBets = [];
		for (var i = 0; i < betLegs.length; i++) {
			if ($("#bs" + betLegs[i].IDFOSelection.replace(/\./, '\\.') + " div.slip-selection input").attr("checked")) {
				checkedBets.push(betLegs[i]);
			}
		}
		if (checkedBets.length == 0) {
			return false;
		}
        allowedBets = {
            "BetLegs": checkedBets,
            "WinStake": null,
            "PlaceStake": null,
            "ShowStake": null,
            "IDFOBetType": null,
            "BetTypeName": null,
            "IDFOMultiRacePool": null,
            "IsPool": false
        };
		availableBets = uWin.api.getAllowedBetTypes(allowedBets);
		availableBets = availableBets.BetType;
		return availableBets;
    };

	// function to return previously saved availableBets
	this.getAvailableBets = function() {
		return availableBets;
	};

    this.placeBetSlip = function() {
        if (betLegs.length > 0) {
			uWin.ui.startAjaxLoader();
            var isLoggedIn = uWin.api.isLoggedIn();
            if (!isLoggedIn) {
				uWin.ui.stopAjaxLoader();
                uWin.debug("Not logged in");
                uWin.ui.error(_("You must login before placing bet."));
				return false;
            }
			// get array of checked bets
            var checkedBets = [];
			for (var i = 0; i < betLegs.length; i++) {
				if ($("#bs" + betLegs[i].IDFOSelection.replace(/\./, '\\.') + " div.slip-selection input").attr("checked")) {
					checkedBets.push(betLegs[i]);
				}
			}
			// call method to build betSlip object
			var newBets = createBetSlip(checkedBets);
			// execute api call to place betSlip
			if (newBets.length > 0) {
				betSlip = {
		        	"Bets": newBets,
		            "IsFree": freeBetsFlag
		        };
				// execute api call to place betSlip
	            var betSlipOut = uWin.api.placeBetSlip(betSlip);
				this.freeBetsFlagReset();
				if (betSlipOut) {
					var clearBetslip = true;
					var detailedState = betSlipOut.Status.DetailedState;
					var message = "";
					// call user interface function to show result
					switch (betSlipOut.Status.State) {
						case 1:
							// any of states requiring confirmation
							var doConfirm = true;
							switch (detailedState) {
								case 2:
									message = _("Acceptable, awaiting confirmation.");
									break;
								case 8:
									message = _("Current offered price changed.");
									break;
								case 16:
									message = _("Current offered Handicap value changed.");
									break;
								case 32:
									message = _("Band value changed.");
									break;
								case 66:
									message = _("Stakes were reoffered.");
									break;
								case 512:
									message = _("Maximum takeout exceeded.");
									break;
								case 2048:
									message = _("Current offered EachWay changed.");
									break;
								case 16640:
									if (typeof(betSlipOut.TopupAmount)!='undefined' && parseFloat(betSlipOut.TopupAmount)>0) {
										uWin.ui.betSlipError({StatusText: _("You currently do not have enough funds to submit this betslip.")});
										clearBetslip = false;
									} else {
										uWin.ui.betSlipError(betSlipOut.Status);
									}
									doConfirm = false;	
									break;
							}
							if (doConfirm) {		
								uWin.ui.confirmBetSlip(checkedBets, betSlipOut, message);
							}
							break;
						case 2:
							uWin.ui.placeBetSlip(checkedBets, betSlipOut);
							uWinAccount.api.UpdateBalanceOnTop();		
							break;
						case 4:
							// rejected or terminated
							if (detailedState == 4096) {
								if (typeof(betSlipOut.TopupAmount)!='undefined' && parseFloat(betSlipOut.TopupAmount)>0) {
									uWin.ui.betSlipError({StatusText: _("You currently do not have enough funds to submit this betslip.")});
									clearBetslip = false;
								} else {
									uWin.ui.betSlipError(betSlipOut.Status);
								}	
							} else if (detailedState == 4) {
								uWin.ui.betSlipError(betSlipOut.Status);
							}
							break;
					}
					if (clearBetslip) {
						// remove selected bets from stored session, as we just placed them
						betLegs = [];
						uWin.api.deleteValue("betSlipHtml");
						uWin.api.deleteValue("betLegs");
						resetBetSlipFlag = true;				
					}	
				}
	            return true;				
			} else {
				uWin.ui.stopAjaxLoader();
	            uWin.debug("No bets are selected");
	            uWin.ui.error(_("No bets are selected."));
	            return false;				
			}
        } else {
            uWin.debug("Betslip empty");
            uWin.ui.error(_("Your betslip is empty."));
            return false;
        }
    };

    this.calculateBetSlip = function() {
		// get array of checked bets
        var checkedBets = [];
		for (var i = 0; i < betLegs.length; i++) {
			if ($("#bs" + betLegs[i].IDFOSelection.replace(/\./, '\\.') + " div.slip-selection input").attr("checked")) {
				checkedBets.push(betLegs[i]);
			}
		}
		// call method to build betSlip object
		var newBets = createBetSlip(checkedBets);
		var betSlip = {
        	"Bets": newBets,
            "IsFree": freeBetsFlag
        };
		return uWin.api.calculateBetSlip(betSlip);
    };

    // clears the whole slip and calls ui function that clears DOM
    this.clearSlip = function() {
        for (var i = 0; i < betLegs.length; i++) {
            // calls ui fucntion to remove element with specified id
            uWin.ui.removeBet(betLegs[i].IDFOSelection);
        }
        betLegs = [];
    };

    // called by the api layer when a successful login occurs
    this.login = function(data) {
        texasContext.populate(data);
    };
} (jQuery);

// ============================ Communication layer ============================ //
uWin.api = new
function($) {
    /**
	 *	AJAX request callbacks - metacallbacks, if you will
	 */
    // fires whenever a request begins - designed for UI interactions (eg loading icons)
    var onRequest = function(service, method, data) {

        };
    // fires whenever a request ends - designed for UI interactions (eg loading icons)
    var onComplete = function(request) {

        };
    // fires when a callcompletes successfully - designed for handling the response
    var onSuccess = function(data, status, service, method) {
        uWin.debug(".comms.onSuccess", arguments);
    };
    // fires when a request fails - designed for handling errors
    var onError = function(request, status, error, service, method) {
        uWin.debug(".comms.onError", arguments);
    };

    // rpc insists on having the call id per-service
    var id = {
        Customer: 1,
        Betting: 1
    };
    /**
	 *	Actually makes the request of the api
	 *
	 *
	 *	@param service String - the servce name, eg Customer
	 *	@param method String - the method name, eg Login
	 *	@param paras Array - an array of parameters to pss to the API
	 *	@param successCallback - a function to execute when the request completes succesfully (optional, but typically necessary)
	 *	@param errorCallback - a function to execute if the request fails (optional, but typically necessary)
	 *  @param async - boolean, if false - performs sync ajax call
	 *	
	 */
    var makeCall = function(service, method, params, successCallback, errorCallback, async) {
        var data = {
            method: method,
            params: params,
            jsonrpc: "2.0",
            id: id[service]++
        };

        uWin.debug(("undefined" === typeof(async)) ? true: false);

        onRequest(service, method, params);
        $.ajax({
            url: uWin.config.api_url + service + "/",

            cache: false,
            dataType: "json",
            data: JSON.stringify(data),
            async: ("undefined" === typeof(async)) ? true: false,
            type: "POST",

            complete: onComplete,
            error: function(request, status, error, service, method) {
                onError(request, status, error, service, method);
                if ("function" === typeof(errorCallback)) {
                    errorCallback(request, status, error);
                }
            },
            success: function(data, status) {
                var responseData = data.result;
                onSuccess(responseData, status, service, method);
                if ("function" === typeof(successCallback)) {
                    successCallback(responseData, status);
                }
            }
        });

    };

    var makeSyncCall = function(service, method, params, successCallback, errorCallback) {
        var data = {
            method: method,
            params: params,
            jsonrpc: "2.0",
            id: id[service]++
        };
        var responseData;

        onRequest(service, method, params);
        $.ajax({
            url: uWin.config.api_url + service + "/",
            cache: false,
            dataType: "json",
            data: JSON.stringify(data),
            async: false,
            type: "POST",
            complete: onComplete,
            error: function(request, status, error, service, method) {
                onError(request, status, error, service, method);
                if ("function" === typeof(errorCallback)) {
                    errorCallback(request, status, error);
                }
            },
            success: function(data, status) {
                responseData = data.result;
                onSuccess(responseData, status, service, method);
                if ("function" === typeof(successCallback)) {
                    successCallback(responseData, status);
                }
            }
        });

        return responseData;
    };


    /*
	 *	API methods - each comprised of a public method, a private success callback and a private error callback
	 */

    /**
	 *	EchoResponse
	 *	A means of testing the service is up - should return the passed text
	 */
    var echoSuccess = function(data, status) {
        // this ethod doesn't do anything but log the response
        uWin.debug("API Echo success", data);
    };
    var echoError = function(request, status, error) {
        uWin.debug("Echo call failed", request, status, error);
    };
    this.echo = function(service, message) {
        var params = [
        message
        ];
        makeSyncCall(service, "TexasEcho", params, echoSuccess, echoError);
    };


    var getAllowedBetTypesSuccess = function(data, status) {
        uWin.debug("getAllowedBetTypesSuccess", data);
    };
    var getAllowedBetTypesError = function(request, status, error) {
        uWin.debug("getAllowedBetTypesError", request, status, error);
    };
    this.getAllowedBetTypes = function(betSlip) {
        var params = [
        betSlip
        ];
        return makeSyncCall("Betting", "GetAllowedBetTypes", params, getAllowedBetTypesSuccess, getAllowedBetTypesError);
    };

    // calculate betslip / get allowed bets metacall
    var betSlipChangedSuccess = function(data, status) {
        uWin.debug("betSlipChangedSuccess", data);
    };
    var betSlipChangedError = function(request, status, error) {
        uWin.ui.error("Failed to update BetSlip");
        uWin.debug("Failed to update BetSlip", request, status, error);
    };
    this.betSlipChanged = function(texasContext, betSlip) {
        var params = [
        texasContext,
        betSlip
        ];
    };

    // placeBetSlip
    var placeBetSlipSuccess = function(data, status) {
        uWin.debug("Betslip sent", data);
    };
    var placeBetSlipError = function(request, status, error) {
        uWin.debug("Couldn't send bets", request, status, error);
    };
    this.placeBetSlip = function(betSlip) {
        var params = [
        betSlip,
        true
        ];
        return makeSyncCall("Betting", "PlaceBetSlip", params, placeBetSlipSuccess, placeBetSlipError);
    };

	// confirm betSlip
	this.confirmBetSlip = function(IDFOBetSlip, betSlipStatus, securityCode) {
		var params = [
		IDFOBetSlip,
		betSlipStatus,
		securityCode
		];
		return makeSyncCall("Betting", "ConfirmBetSlip", params);
	};

    // calculateBetSlip
    var calculateBetSlipSuccess = function(data, status) {
        uWin.debug("Betslip calculated", data);
    };
    var calculateBetSlipError = function(request, status, error) {
        uWin.debug("Couldn't calculate bets", request, status, error);
    };
    this.calculateBetSlip = function(betSlip) {
        var params = [
        betSlip
        ];
        return makeSyncCall("Betting", "CalculateBetSlip", params, calculateBetSlipSuccess, calculateBetSlipError);
    };

    // getBetDetails
    this.getBetDetails = function(language, marketId, selectionId) {
	    var lang = 'en';
		    if (document.cookie.length>0) {
		        c_start=document.cookie.indexOf ("lang=");
		        if (c_start!=-1) {
		            c_start=c_start + 5;
		            c_end=document.cookie.indexOf (";",c_start);
		            if (c_end==-1) c_end=document.cookie.length;
		            lang = unescape(document.cookie.substring(c_start,c_end));
		        }
		}
        var params = [
        lang,
        marketId,
        selectionId
        ];
        return makeSyncCall("Content", "getBetDetails", params);
    };

    // isLoggedIn
    this.isLoggedIn = function() {
        return makeSyncCall("Customer", "isLoggedIn");
    };

	// getBalances
	this.getBalances = function() {
		return makeSyncCall("Account", "GetBalances");
	};

	// store value
    var storeValueSuccess = function(data, status) {
        uWin.debug("Value stored", data);
    };
    var storeValueError = function(request, status, error) {
        uWin.debug("Couldn't store value", request, status, error);
    };
	this.storeValue = function(key, value) {
		var params = [
		key,
		value
		];
		return makeSyncCall("Content", "store", params, storeValueSuccess, storeValueError);
	};

	// get value
	this.getValue = function(key) {
		var params = [
		key
		];
		return makeSyncCall("Content", "get", params);
	}

	// delete value
    var deleteValueSuccess = function(data, status) {
        uWin.debug("Value deleted", data);
    };
    var deleteValueError = function(request, status, error) {
        uWin.debug("Couldn't delete value", request, status, error);
    };	
	this.deleteValue = function(key) {
		var params = [
		key
		];
		makeCall("Content", "delete", params, deleteValueSuccess, deleteValueError);
	}

} (jQuery);
//jarek edit

//
// ============================ BetSlip UI layer ============================ //
uWin.ui = new
function($) {
    // this is run first to set everything up
	// variable to keep info about input timeout ( to avoid calling calculate after every single key)
	var timeOut;
    // setup the necessary functions
    // called when an error occurs
    this.error = function(message) {
        alert(message);
    };

    // this.login - call this when the user logs in
    this.login = function() {
        // update something to say logged in
        // maybe pop up a box
        alert("you have been logged in");
    };

    // draws elements for new bet
    this.addBet = function(betData, element, resetBetSlipFlag) {
        //assuming that the span element has id = marketId/selectionId
        var betDetails = uWin.api.getBetDetails('uk', element.attr('id').split('/')[0], element.attr('id').split('/')[1]);	
		if (resetBetSlipFlag) {
			resetBetSlip();
		}
        if ("object" === typeof(betDetails)) {
			// remove no-bets info
			$("#no-bets").remove();
			$("#bet-window-header div.slip-header").remove();
            var html = "<div class=\"slip-selection\"><input type=\"checkbox\" checked=\"checked\"><label>" + betDetails.eventname + ' / ' + betDetails.externalDescription + "</label><span>[<a href=\"#\" onclick=\"uWin.state.removeBet('" + betData.IDFOSelection + "');return false;\">X</a>]</span></div>";
            html += "<div class=\"slip-stake\">";
            if (betDetails.decimals.indexOf(')')>0) {
               html += "<label>" + betDetails.name + ' ' + betDetails.decimals.replace(/\)/,') @') + "</label><input type=\"text\" value=\"\"/></div>";
            } else {
               html += "<label>" + betDetails.name + ' @ ' + betDetails.decimals + "</label><input type=\"text\" value=\"\"/></div>";
            }
            html += "<div class=\"slip-footer\"><a>" + _("Estimated Returns") + "</a></div>";
            $("#bet-window").append("<div class=\"single-bet\" id=\"bs" + betData.IDFOSelection + "\">" + html + "</div>");
			// action handling unselected class
			$("#bet-window div.slip-selection input:last").click(function() {
				uWin.ui.selectionClick($(this));
			});
			// action handling stake input
			$("#bet-window div.slip-stake input:last").bind("keyup", function() {
				uWin.ui.selectionStake($(this));
			});
			// add free bets html
			if ($("#bet-window-header div.free-bets").html() == "") {
				$("#bet-window-header div.free-bets").html("<input type=\"checkbox\" name=\"free-bets\" class=\"free-bets\" /><span>" + _("Place as free bets") + "</span>");
				// add handler for free bets checbox
				$("#bet-window-header input.free-bets").click(function() {
					var freeBets = false;
					if ($(this).attr("checked")) freeBets = true;
					uWin.state.setFreeBets(freeBets);
				});				
			}
        }
    };

	// click action for checkboxes
	this.selectionClick = function(element) {
		if ($("#bet-bottom input[type='submit']").attr("disabled") == false) {
			$("#bet-bottom input[type='submit']").attr("disabled", true);
		}
		uWin.ui.startAjaxLoader();
		if (element.attr("checked")) {
			element.parent("div").parent("div.single-bet").removeClass("unselected");
		} else {
			element.parent("div").parent("div.single-bet").addClass("unselected");
		}
		// get allowed bet types and draw accumulators
		var betTypes = uWin.state.getAllowedBetTypes();
		if (betTypes) {
			uWin.ui.drawBetTypes(betTypes);
		} else {
			$("#bet-option div.slip-stake input[type='text']").each(function() {
				$(this).unbind();
			});
			$("#bet-option").empty();			
		}
		// count betslip after changing input
		var calculatedBets = uWin.state.calculateBetSlip();
		uWin.ui.calculateBetSlip(calculatedBets);
		uWin.ui.stopAjaxLoader();
	};

	// change action for inputs
	this.selectionStake = function(element) {
		if ($("#bet-bottom input[type='submit']").attr("disabled") == false) {
			$("#bet-bottom input[type='submit']").attr("disabled", true);
		}
		uWin.ui.startAjaxLoader();
		validateStake(element);
		// check if singles input in accumulator needs to be cleared
		if (parseFloat(element.val()) != parseFloat($("#type-C1 div.slip-stake input[type='text']").val())) {
			$("#type-C1 div.slip-stake input[type='text']").val("");
		}
		// calculate betSlip with 2 secs lag
		if (timeOut) {
			clearTimeout(timeOut);
		}
		timeOut = setTimeout(function() {
			// count betslip after changing input
			var calculatedBets = uWin.state.calculateBetSlip();
			uWin.ui.calculateBetSlip(calculatedBets);
			uWin.ui.stopAjaxLoader();
		}, 1000);		
	};

    // removes elements of single bet
    this.removeBet = function(IDFOSelection) {
        $("#bs" + IDFOSelection.replace(/\./, '\\.')).remove();
		// add no bets info if empty betslip
		var betLegs = uWin.state.getBetLegs();
		if (betLegs.length == 0) {
			$("div.total-stake").after("<p id=\"no-bets\">" + _("There are no bets made.") + "<br/>" + _("To select a bet click on a price.") + "</p>");
			$("#bet-window-header div.free-bets").empty();
			uWin.state.freeBetsFlagReset();
		}
    };

	// draws allowed bet types
	this.drawBetTypes = function(betTypes) {
		// remove event from all inputs, also timeOut
		clearTimeout(timeOut);
		$("#bet-option div.slip-stake input[type='text']").each(function() {
			$(this).unbind();
		});
		$("#bet-option").empty();
		var betLegs = uWin.state.getBetLegs();
		if (betLegs.length > 1) {
			$("#bet-option-header").html("<h2 class=\"with-margin\">" + _("Accumulators / Multiples") + "</h2>");
			for (var i = 0; i < betTypes.length; i++) {
				var html = "<div class=\"slip-selection\"><p class=\"name\">" + betTypes[i]["Name"] + "</p><span>" + betTypes[i]["NumberOfBets"] + " " + _("Bets") + "</span></div>";
				html += "<div class=\"slip-stake\">";
				if (betTypes[i]["IsEachWayAllowed"] == true) {
					html += "<input class=\"checkbox\" type=\"checkbox\"/><label>" + _("Each Way") + " @ 1/5 1-3</label>";	
				}
				html += "<input type=\"text\"/></div><div class=\"slip-footer\"><a>" + _("Estimated Returns") +"</a></div>";
				$("#bet-option").append("<div id=\"type-" + betTypes[i]["IDFOBetType"] + "\" class=\"single-bet  multiples\">" + html + "</div>");
			}
		}
		// add event for input fields
		$("#bet-option div.slip-stake input[type='text']").each(function() {
			$(this).bind("keyup", function() {
				if ($("#bet-bottom input[type='submit']").attr("disabled") == false) {
					$("#bet-bottom input[type='submit']").attr("disabled", true);
				}
				uWin.ui.startAjaxLoader();
				validateStake($(this));
				var self = $(this);
				// populate for singles when type-C1 input changed
				if ($(this).parent("div").parent("div").attr("id") == "type-C1") {
					$("#bet-window div.slip-stake input").each(function() {
						if (self.val() == "") {
							$(this).val(self.val());
						} else {
							$(this).val(sprintf("%0.2f", self.val()));
						}
					});
				}
				// calculate betSlip with 2 secs lag
				if (timeOut) {
					clearTimeout(timeOut);
				}	
				timeOut = setTimeout(function() {
					var calculatedBets = uWin.state.calculateBetSlip();
					uWin.ui.calculateBetSlip(calculatedBets);
					uWin.ui.stopAjaxLoader();
				}, 1000);
			});
		});
	};

	// calculate betslip
	this.calculateBetSlip = function(calculatedBets) {
		// make estimated returns default for all entries
		$("div.slip-footer a").each(function() {
			$(this).text(_("Estimated Returns"));
		});
		//fetch language
	    	var lang = 'en';
		    if (document.cookie.length>0) {
		        c_start=document.cookie.indexOf ("lang=");
		        if (c_start!=-1) {
		            c_start=c_start + 5;
		            c_end=document.cookie.indexOf (";",c_start);
		            if (c_end==-1) c_end=document.cookie.length;
		            lang = unescape(document.cookie.substring(c_start,c_end));
		        }
			}

		var totalStake = 0.00;
		// if empty object print 0.00
		if (typeof(calculatedBets.CalculatedBet) == "undefined") {
			if (lang == 'en') {
				$("div.total-stake p").text(_("Total Stake") + ": " + _("%currency%") + sprintf("%0.2f", "0"));
			} else {
				$("div.total-stake p").text(_("Total Stake") + ": " + sprintf("%0.2f", "0") + _("%currency%"));
			}
			if ($("#bet-bottom input[type='submit']").attr("disabled") == true) {
				$("#bet-bottom input[type='submit']").attr("disabled", false);
			}
			return;
		}
		// populate estimated returns in right places
		// first get all checked, push ids of element
        var checkedBets = [];
		var betLegs = uWin.state.getBetLegs();
		for (var i = 0; i < betLegs.length; i++) {
			if ($("#bs" + betLegs[i].IDFOSelection.replace(/\./, '\\.') + " div.slip-selection input").attr("checked")) {
				checkedBets.push("bs" + betLegs[i].IDFOSelection.replace(/\./, '\\.'));
			}
		}
		// if singles multiple not used, push selections with filled stake
		var newBets = []
		if (!(parseFloat($("#type-C1" + " div.slip-stake input[type='text']").val()) || 0)) {
            for (var i = 0; i < checkedBets.length; i++) {
				// check if stake is given
				if (parseFloat($("#" + checkedBets[i] + " input[type='text']").val()) || 0) {
					newBets.push(checkedBets[i]);
				}
            }
		}
		// go through multiples and push selections with filled stake
		var availableBets = uWin.state.getAvailableBets();
		if (availableBets) {
			for (var i = 0; i < availableBets.length; i++) {
				var betType = availableBets[i]["IDFOBetType"];
				if (parseFloat($("#type-" + betType + " div.slip-stake input[type='text']").val()) || 0) {
					newBets.push("type-" + betType);
				}
			}
		}

		// count total stake and populate estimated for single bets
		if (calculatedBets.CalculatedBet.length > 1) {
			for (var i = 0; i < calculatedBets.CalculatedBet.length; i++) {
				totalStake += parseFloat(calculatedBets.CalculatedBet[i]["TotalStake"]);
				if (lang=='en') {
					$("#" + newBets[i] +" div.slip-footer a").text(_("Estimated Returns") + " " +_("%currency%")+ sprintf("%0.2f", calculatedBets.CalculatedBet[i]["PotentialReturn"]));
				} else {
					$("#" + newBets[i] +" div.slip-footer a").text(_("Estimated Returns") + " " + sprintf("%0.2f", calculatedBets.CalculatedBet[i]["PotentialReturn"])+_("%currency%"));
				}
			}
		} else {
			totalStake += parseFloat(calculatedBets["CalculatedBet"]["TotalStake"]);
			if (lang=='en') {
				$("#" + newBets[0] +" div.slip-footer a").text(_("Estimated Returns") + " "+_("%currency%")+sprintf("%0.2f", calculatedBets.CalculatedBet["PotentialReturn"]));
			} else {
				$("#" + newBets[0] +" div.slip-footer a").text(_("Estimated Returns") + " " + sprintf("%0.2f", calculatedBets.CalculatedBet["PotentialReturn"])+_("%currency%"));
			}
		}
		// print out total stake
		if (lang == 'en') {
			$("div.total-stake").html("<p>" + _("Total Stake") + ": " + _("%currency%") + sprintf("%0.2f", totalStake) + "</p>");
		} else {
			$("div.total-stake").html("<p>" + _("Total Stake") + ": " + sprintf("%0.2f", totalStake) + _("%currency%") + "</p>");
		}
		if ($("#bet-bottom input[type='submit']").attr("disabled") == true) {
			$("#bet-bottom input[type='submit']").attr("disabled", false);
		}
	}

	this.betSlipNoFunds = function(betSlipOut) {
		// remove event from all inputs, also timeOut
		clearTimeout(timeOut);
		$("div.slip-stake input[type='text']").each(function() {
			$(this).unbind();
		});
		// error with stake higher than 2% (?)
		if (betSlipOut.Status.StatusCode == "-20413") {
			$("#place").empty();
			$("#place").html("<div class=\"bet-main\"><h2>" + _("Bet Slip") + "</h2><div class=\"slip-header\"><p class=\"funds-error\">" + betSlipOut.Status.StatusText + "</p></div></div>");
			$("#no-bets").remove();
			$("#bet-bottom div.total-stake").remove();
			$("#bet-bottom div.bets-info input[type='submit']").remove();
			return;
		}
		var tempString = betSlipOut["Status"]["StatusText"].split(" = ");
		var totalSTake = tempString[1].substr(0, tempString[1].indexOf(","));
		var currBalance = tempString[2].substr(0, tempString[2].indexOf("."));
		$("#place").empty();
		$("#place").html("<div class=\"bet-main\"><h2>" + _("Bet Slip") + "</h2><div class=\"slip-header\"><p class=\"funds-error\">" + _("Sorry, you have insufficient funds available. Please deposit to place your bet.") + "</p></div></div>");
		$("#place div.bet-main").append("<div class=\"funds\"><p><span>" + _("Total Stake") + "</span>" + _("%currency%") + " " + totalSTake + "</p><p><span>" + _("Current balance") + "</span>" + _("%currency%") + " " + currBalance + "</p></div>");
		$("#place div.bet-main").append("<div class=\"funds\"><p class=\"deposit-amount\"><span>" + _("Deposit amount") + "</span> " + _("%currency%") + sprintf("%0.2f", betSlipOut.TopupAmount) + "</p><p><span>* " + _("Card Security code") + "</span><input value=\"\" class=\"cv2\" type=\"text\"></p><p class=\"question\">(what is this?)</p><p class=\"change-details\"><a href=\"#\">" + _("Click here") + "</a> " + _("to change your details") + "</p></div>");
		// draw successful bet placing mark at the bottom
		$("#no-bets").remove();
		$("#bet-bottom div.total-stake").remove();
		$("#bet-bottom div.bets-info input[type='submit']").remove();
		$("#bet-bottom div.bets-info").append("<input type=\"submit\" class=\"deposit-submit-button\" value=\"" + _("Deposit &amp; Bet") + "\" />");
		// click action for deposit
		$("#bet-bottom input.deposit-submit-button").click(function() {
			betSlipOut["Status"]["StatusText"] = null;
			var response = uWin.api.confirmBetSlip(betSlipOut["IDFOBetSlip"], betSlipOut["Status"], $("#place input.cv2").val());
			if (response.DetailedState == 132) {
				uWin.ui.betSlipTimeOut(response);
			}
		});
	};

	this.betSlipError = function(betSlipOut) {
		$("#place").empty();
		// draw main bet window
		$("#place").append("<div class=\"bet-main\"></div>");
		$("#place div.bet-main").append("<div id=\"bet-window-header\"></div>");
		$("#bet-window-header").append("<h2>" + _("Place Bets") + "</h2><span class=\"right-help\"><a href=\"#\" onclick=\"window.open('http://'+window.location.host+'/open-bets','newWindow','width=568,scrollbars=1,height=500');\">" + _("Open Bets") + "</a></span>");
		$("#bet-window-header").append("<div class=\"slip-header\"><p class=\"funds-error\">" + _("Your bet slip was rejected") + "</p></div>");
		$("#place div.bet-main").append("<div id=\"bet-window\"></div><div id=\"bet-option-header\"></div><div id=\"bet-option\"></div>");
		// draw bet bottom
		if ($("#no-bets").length == 0) {
			$("#bet-bottom div.total-stake").after("<p id=\"no-bets\">" + betSlipOut.StatusText + "</p>");	
		} else {
			$("#no-bets").text(betSlipOut.StatusText);
		}
		$("#bet-bottom div.total-stake").html("");
		$("#bet-bottom div.bets-info input[type='submit']").remove();
		$("#bet-bottom div.bets-info").append("<input type=\"submit\" class=\"submit-button\" value=\"" + _("Bet Again") + "\" />");
        // adds action to reset bet slip
        $("#bet-bottom input.submit-button").click(resetBetSlip);
	};

	this.confirmBetSlip = function(checkedBets, betSlipOut, message) {
		// remove event from all inputs, also timeOut
		clearTimeout(timeOut);
		$("div.slip-stake input[type='text']").each(function() {
			$(this).unbind();
		});
		// drawing your selections part
		var html = "";
		var betDetails;
		for (var i = 0; i < checkedBets.length; i++) {
			betDetails = uWin.api.getBetDetails('uk', checkedBets[i]["IDFOMarket"], checkedBets[i]["IDFOSelection"]);
			html += "<p>" + betDetails.eventname + " / " + betDetails.externalDescription + "</p>";
                        if (betDetails.decimals.indexOf(')')>0) {
			   html += "<p><b>" + betDetails.name + " " + betDetails.decimals.replace(/\)/,') @') + "</b></p>";	
                        } else {
			   html += "<p><b>" + betDetails.name + " @ " + betDetails.decimals + "</b></p>";	
                        }
		}
		$("#place").empty();
		$("#place").html("<div id=\"bet-success\" class=\"bet-main\"><h2>" + _("Bet Receipt") + "</h2><span class=\"right-help\"><a onclick=\"window.open('http://www.youwin.com/en/open-bets','newWindow','width=568,scrollbars=1,height=500');\" href=\"#\">" + _("Open Bets") + "</a></span><div class=\"single-bet\"></div></div>");
		$("#bet-success div.single-bet").append("<div class=\"slip-selection white\"><p>" + _("Your selections") + "</p></div>");
		$("#bet-success div.single-bet").append("<div class=\"slip-stake\">" + html + "</div>");
		// drawing bets part
		var htmlBets = "";
		var yourBets = betSlipOut["Bets"]["BetOutbound"];
		// check if yourBets is array or just one bet
		if (yourBets.length > 1) {
			for (var i = 0; i < yourBets.length; i++) {
				htmlBets += "<b>" + _("Win") + "</b></p><p>" + Math.round(yourBets[i]["TotalStake"] / yourBets[i]["WinStake"]) + " " + _("line(s) at") + " " + sprintf("%0.2f", yourBets[i]["WinStake"]) + " " + _("per line") + "</p>";
				htmlBets += "<p>" + _("Total stake for this bet") + ": " + _("%currency%") + sprintf("%0.2f", yourBets[i]["TotalStake"]) + "</p>";
				htmlBets += "<p>" + _("Potential returns") + ": " + _("%currency%") + sprintf("%0.2f", yourBets[i]["PotentialReturn"]) + "</p>";
			}
		} else {
			htmlBets += "<b>" + _("Win") + "</b></p><p>" + Math.round(yourBets["TotalStake"] / yourBets["WinStake"]) + " " + _("line(s) at") + " " + sprintf("%0.2f", yourBets["WinStake"]) + " " + _("per line") + "</p>";
			htmlBets += "<p>" + _("Total stake for this bet") + ": " + _("%currency%") + sprintf("%0.2f", yourBets["TotalStake"]) + "</p>";
			htmlBets += "<p>" + _("Potential returns") + ": " + _("%currency%") + sprintf("%0.2f", yourBets["PotentialReturn"]) + "</p>";
		}
		var htmlFooter = "<p>" + _("Total stake") + ": " + _("%currency%") + sprintf("%0.2f", betSlipOut["TotalStake"]) + "</p>";
		htmlFooter += "<p>" + _("Free bets voucher") + ": " + _("%currency%") + " 0.00</p>";
		htmlFooter += "<p>" + _("Total cost") + ": " + _("%currency%") + sprintf("%0.2f", betSlipOut["TotalStake"]) + "</p>";
		$("#bet-success").append("<div class=\"single-bet\"></div></div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-selection white\"><p>" + _("Your bets") + "</p></div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-stake\"><p>" + htmlBets + "</div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-footer\"><p>" + htmlFooter + "</div>");
		// draw successful bet placing mark at the bottom
		$("#bet-bottom div.total-stake").html("<p class=\"success-total\">" + _("Your bet awaits confirmation") + "</p>");
		if (message != "") {
			$("#bet-bottom div.total-stake").after("<p id=\"no-bets\">" + message + "</p>");
		}
		$("#bet-bottom div.bets-info input[type='submit']").remove();		   
		$("#bet-bottom div.bets-info").append("<input type=\"submit\" class=\"submit-button\" value=\"" + _("Confirm") + "\"/>");
		$("#bet-bottom div.bets-info input[type='submit']").click(function() {
			var response = uWin.api.confirmBetSlip(betSlipOut["IDFOBetSlip"], betSlipOut["Status"], "XYZ");
			if (response.DetailedState == 132) {
				uWin.ui.betSlipError(response);
			}
			if (response.State == 2 && response.DetailedState == 1) {
				uWin.ui.placeBetSlip(checkedBets, betSlipOut);
			}
		});
	};

	// draw betslip result
	this.placeBetSlip = function(checkedBets, betSlipOut) {
		// remove event from all inputs, also timeOut
		clearTimeout(timeOut);
		$("div.slip-stake input[type='text']").each(function() {
			$(this).unbind();
		});
		// drawing your selections part
		var html = "";
		for (var i = 0; i < checkedBets.length; i++) {
			betDetails = uWin.api.getBetDetails('uk', checkedBets[i]["IDFOMarket"], checkedBets[i]["IDFOSelection"]);
			html += "<p>" + betDetails.eventname + " / " + betDetails.externalDescription + "</p>";
                        if (betDetails.decimals.indexOf(')')>0) {
			   html += "<p><b>" + betDetails.name + " " + betDetails.decimals.replace(/\)/,') @') + "</b></p>";	
                        } else {
			   html += "<p><b>" + betDetails.name + " @ " + betDetails.decimals + "</b></p>";	
                        }
		}
		$("#place").empty();
		$("#place").html("<div id=\"bet-success\" class=\"bet-main\"><h2>" + _("Bet Receipt") + "</h2><span class=\"right-help\"><a onclick=\"window.open('http://www.youwin.com/en/open-bets','newWindow','width=568,scrollbars=1,height=500');\" href=\"#\">" + _("Open Bets") + "</a></span><div class=\"single-bet\"></div></div>");
		$("#bet-success div.single-bet").append("<div class=\"slip-selection white\"><p>" + _("Your selections") + "</p></div>");
		$("#bet-success div.single-bet").append("<div class=\"slip-stake\">" + html + "</div>");
		// drawing bets part
		var htmlBets = "";
		var yourBets = betSlipOut["Bets"]["BetOutbound"];
		// check if yourBets is array or just one bet
		if (yourBets.length > 1) {
			for (var i = 0; i < yourBets.length; i++) {
				htmlBets += "<b>" + _("Win") + "</b></p><p>" + Math.round(yourBets[i]["TotalStake"] / yourBets[i]["WinStake"]) + " " + _("line(s) at") + " " + sprintf("%0.2f", yourBets[i]["WinStake"]) + " " + _("per line") + "</p>";
				htmlBets += "<p>" + _("Total stake for this bet") + ": " + _("%currency%") + sprintf("%0.2f", yourBets[i]["TotalStake"]) + "</p>";
				htmlBets += "<p>" + _("Potential returns") + ": " + _("%currency%") + sprintf("%0.2f", yourBets[i]["PotentialReturn"]) + "</p>";
			}
		} else {
			htmlBets += "<b>" + _("Win") + "</b></p><p>" + Math.round(yourBets["TotalStake"] / yourBets["WinStake"]) + " " + _("line(s) at") + " " + sprintf("%0.2f", yourBets["WinStake"]) + " " + _("per line") + "</p>";
			htmlBets += "<p>" + _("Total stake for this bet") + ": " + _("%currency%") + sprintf("%0.2f", yourBets["TotalStake"]) + "</p>";
			htmlBets += "<p>" + _("Potential returns") + ": " + _("%currency%") + sprintf("%0.2f", yourBets["PotentialReturn"]) + "</p>";
		}
		var htmlFooter = "<p>" + _("Total stake") + ": " + _("%currency%") + " " + sprintf("%0.2f", betSlipOut["TotalStake"]) + "</p>";
		htmlFooter += "<p>" + _("Free bets voucher") + ": " + _("%currency%") + " 0.00</p>";
		htmlFooter += "<p>" + _("Total cost") + ": " + _("%currency%") + " " + sprintf("%0.2f", betSlipOut["TotalStake"]) + "</p>";
		$("#bet-success").append("<div class=\"single-bet\"></div></div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-selection white\"><p>" + _("Your bets") + "</p></div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-stake\"><p>" + htmlBets + "</div>");
		$("#bet-success div.single-bet:last").append("<div class=\"slip-footer\"><p>" + htmlFooter + "</div>");
		// draw successful bet placing mark at the bottom
		$("#bet-bottom div.total-stake").html("<p class=\"success-total\">" + _("Your bet has been placed successfully") + "</p>");
		$("#no-bets").remove();
		$("#bet-bottom div.bets-info input[type='submit']").remove();		   
		$("#bet-bottom div.bets-info").append("<input type=\"submit\" class=\"submit-button\" value=\"" + _("Bet Again") + "\"/>");
		$("#bet-bottom div.bets-info input[type='submit']").click(resetBetSlip);
	}

	this.uncheckSelection = function(selectionID) {
		$("#bs" + selectionID.replace(/\./, '\\.') + " div.slip-selection input").attr("checked", false);
		$("#bs" + selectionID.replace(/\./, '\\.') + " div.slip-selection input").attr("disabled", true);
	}

	this.checkSelection = function(selectionID) {
		$("#bs" + selectionID.replace(/\./, '\\.') + " div.slip-selection input").attr("checked", true);
		$("#bs" + selectionID.replace(/\./, '\\.') + " div.slip-selection input").attr("disabled", false);
	}

	// puts ajax loader img and disables place bet button when calls are processing
	this.startAjaxLoader = function() {
		if($("#bet-bottom div.total-stake img").length == 0 && $("#bet-bottom div.total-stake").html() != "") {
			$("#bet-bottom div.total-stake").append("<img src=\"http://www.youwin.tv/__data/assets/image/0017/5372/ajax-loader2.gif\" />");
		}
	}

	// removes ajax loader img and enables place bet button when calls are finished
	this.stopAjaxLoader = function() {
		$("#bet-bottom div.total-stake img").remove();
	}

	// validate stake input
	var validateStake = function(element) {
		var stake = element.val();
		// parse out anything that is not number or dot
		element.val(stake.replace(/[^0-9|\.]/,""));
		// parse out unneccessary dots and decimals
		if (!element.val().match(/^[0-9]+(\.[0-9]{0,2})?$/)) {
			stake = element.val().split(".");
			if (stake[0] == "") {
				if (typeof(stake[1]) == "undefined") {
					stake[0] = "";
				} else {
					if (stake[1] == "") {
						stake[0] = ".";
					} else {
						stake[0] = "0";
					}
				}
			}
			if (typeof(stake[1]) == "undefined" || stake[1] == "") {
				element.val(stake[0]);
			} else {
				element.val(stake[0] + "." + stake[1].substr(0, 2));
			}
		}
	};

	var resetBetSlip = function() {
		//fetch language
	    	var lang = 'en';
		    if (document.cookie.length>0) {
		        c_start=document.cookie.indexOf ("lang=");
		        if (c_start!=-1) {
		            c_start=c_start + 5;
		            c_end=document.cookie.indexOf (";",c_start);
		            if (c_end==-1) c_end=document.cookie.length;
		            lang = unescape(document.cookie.substring(c_start,c_end));
		        }
			}
					
		// draw main betslip section
		$("#place").empty();
		$("#place").append("<div class=\"bet-main\"></div>");
		$("#place div.bet-main").append("<div id=\"bet-window-header\"><h2>" + _("Place Bets") + "</h2><span class=\"right-help\"><a onclick=\"window.open('http://www.youwin.com/en/open-bets','newWindow','width=568,scrollbars=1,height=500');\" href=\"#\">" + _("Open Bets") + "</a></span></div>");
		$("#bet-window-header").append("<div class=\"free-bets\"></div>");
		$("#place div.bet-main").append("<div id=\"bet-window\"> </div> <div id=\"bet-option-header\"> </div> <div id=\"bet-option\"> </div>");
		// draw bottom and apply click action
		if (lang == 'en') {
			$("#bet-bottom div.total-stake").html("<p>" + _("Total Stake") + ": "+ _("%currency%")+"0.00 </p>");
		} else {
			$("#bet-bottom div.total-stake").html("<p>" + _("Total Stake") + ": 0.00" + _("%currency%") +"</p>");
		}
		if ($("#no-bets").length == 0) {
			$("#bet-bottom div.total-stake").after("<p id=\"no-bets\">" + _("There are no bets made.") + " <br/> " + _("To select a bet click on a price.") + "</p>");	
		} else {
			$("#no-bets").html(_("There are no bets made.") + " <br/> " + _("To select a bet click on a price."));
		}
		$("#bet-bottom div.bets-info input.submit-button").remove();
		$("#bet-bottom div.bets-info").append("<input type=\"submit\" class=\"submit-button\" value=\"" + _("Place Bet") + "\" />");
		$("#bet-bottom div.bets-info input.submit-button").click(function() {
            uWin.state.placeBetSlip();
        });
		initBetSlip();
	};
	
	var initBetSlip = function() {
        // pageready code here

        // retain betslip if saved in session
		var betSlip = uWin.api.getValue("betSlipHtml");
		// trim whitespaces in betSlip Html
		if (betSlip) {
			betSlip = betSlip.replace("/^[\s\t\n]*/", "");
			betSlip = betSlip.replace("/[\s\t\n]*$/", "");
		}
		
		
		
		var betLegs = uWin.api.getValue("betLegs");
		if (betSlip != "" && betLegs.length > 0) {
			uWin.ui.startAjaxLoader();
			// add free bets html
			$("#bet-window-header div.free-bets").html("<input type=\"checkbox\" name=\"free-bets\" class=\"free-bets\" /><span>" + _("Place as free bets") + "</span>");
			// add handler for free bets checbox
			$("#bet-window-header input.free-bets").click(function() {
				var freeBets = false;
				if ($(this).attr("checked")) freeBets = true;
				uWin.state.setFreeBets(freeBets);
			});
			// add html and set betLegs object
			$("#bet-window").html(betSlip);
			uWin.state.setBetLegs(betLegs);
			// remove no-bets info
			$("#no-bets").remove();
			// get stakes variable and uncheck where needed
			var stakeValues = uWin.api.getValue("stakeValues");
			if (stakeValues != false) {
				for (var id in stakeValues) {
					if (stakeValues[id].split("_")[1] == "false") {
						$("#" + id.replace(/\./, '\\.') + " div.slip-selection input[type='checkbox']").attr("checked", false);
					}
				}
			}
			// get allowed bet types and draw accumulators
			var betTypes = uWin.state.getAllowedBetTypes();
			if (betTypes) {
				uWin.ui.drawBetTypes(betTypes);
			}
			// input stakes values
			if (stakeValues != false) {
				for (var id in stakeValues) {
					$("#" + id.replace(/\./, '\\.') + " div.slip-stake input[type='text']").val(stakeValues[id].split("_")[0]);
				}
			}
			var calculatedBets = uWin.state.calculateBetSlip();
			uWin.ui.calculateBetSlip(calculatedBets);
			uWin.ui.stopAjaxLoader();
			// action handling unselected class
			$("#bet-window div.slip-selection input").each(function() {
				$(this).click(function() {
					uWin.ui.selectionClick($(this));
				});
			});
			// action handling stake input
			$("#bet-window div.slip-stake input").each(function() {
				$(this).bind("change keyup", function() {
					uWin.ui.selectionStake($(this));
				});
			});
		}
		
		var isLoggedIn = uWin.api.isLoggedIn();
        if (isLoggedIn) {
			var data = uWin.api.getBalances();
			if (data.free) {
				if (parseFloat(data.free)<0.5) {
					$("#bet-window-header div.free-bets").hide();
				}
			} else {
				$("#bet-window-header div.free-bets").hide();
			}
        } else {
			$("#bet-window-header div.free-bets").hide();
		}		
	};

    // this function will run when the page is ready for JavaScript
    $(function() {
		initBetSlip();
	});
} (jQuery);

// ============================ Site interaction layer ============================ //
uWin.site = new
function($) {
    // this is run first to set everything up
    var site = this;
    // setup the necessary functions
    // this function will run when the page is ready for JavaScript
    $(function() {
        // pageready code here
        // this is a test example!

        // adds onclick action to every bet selection in content
        $("#content span.selection").each(function(i) {
            $(this).mouseover(function() {
                $(this).removeClass('out');
                $(this).addClass('over');
            });
            $(this).mouseout(function() {
                $(this).removeClass('over');
                $(this).addClass('out');
            });

            if ($(this).find("span.frac").html() != "N/A") {
                $(this).addClass('clickable');
                $(this).click(function(event) {
                    event.preventDefault();
                    var odds = $(this).find("span.frac").html();
                    if (odds == 'EVS') {
                        odds = '1/1';
                    }
                    odds = odds.split("/");
					uWin.ui.startAjaxLoader();
					
					if ($(this).find("span.orhn")) {
						var handicap = parseFloat($(this).find("span.orhn").text());
	                    uWin.state.addBet({
							"Handicap": handicap,
	                        "IDFOPriceType": "CP",
	                        "IDFOSelection": $(this).attr("id").split('/')[1],
	                        "IDFOMarket": $(this).attr("id").split('/')[0],
	                        "PriceDown": parseInt(odds[1]),
	                        "PriceUp": parseInt(odds[0])
	                    },
	                    $(this));
					} else { 
	                    uWin.state.addBet({
	                        "IDFOPriceType": "CP",
	                        "IDFOSelection": $(this).attr("id").split('/')[1],
	                        "IDFOMarket": $(this).attr("id").split('/')[0],
	                        "PriceDown": parseInt(odds[1]),
	                        "PriceUp": parseInt(odds[0])
	                    },
	                    $(this));
					}
					// get allowed bet types and draw accumulators
					var betTypes = uWin.state.getAllowedBetTypes();
					if (betTypes) {
						uWin.ui.drawBetTypes(betTypes);
					} else {
						$("#bet-option div.slip-stake input[type='text']").each(function() {
							$(this).unbind();
						});
						$("#bet-option").empty();
					}
					// count betslip after changing input
					var calculatedBets = uWin.state.calculateBetSlip();
					uWin.ui.calculateBetSlip(calculatedBets);
					uWin.ui.stopAjaxLoader();
				});
            }
        });

        // adds toggle action to show/hide betslip
        $("#betting-slip-button a").click(function(event) {
            event.preventDefault();
            $("#betting-slip-right-box").toggle("slow");
        });

        // adds action to clear a whole slip
        $("#bet-window-header p.slip-right").click(function() {
            uWin.state.clearSlip();
        });

		// add handler for free bets checbox
		$("#bet-window-header input.free-bets").click(function() {
			var freeBets = false;
			if ($(this).attr("checked")) freeBets = true;
			uWin.state.setFreeBets(freeBets);
		});

        // adds action to place bets
        $("#bet-bottom input.submit-button").click(function() {
            uWin.state.placeBetSlip();
        });

		// save betslip on page unload
		$(window).unload(function() {
			// overwrite current betslip
			var betLegs = uWin.state.getBetLegs();
			if (betLegs.length > 0) {
				var stakeValues = {};
				// set flag to check if we find any matches to save
				var inputFlag = false;
				$("#place div.single-bet").each(function() {
					// get the ones with filled stake or that are unchecked, separate stake from checked by underscore
					if ($(this).find("div.slip-stake input[type='text']").val() != "" || $(this).find("div.slip-selection input[type='checkbox']").attr("checked") == false) {
						checked = $(this).find("div.slip-selection input[type='checkbox']").attr("checked");
						// if on accumulators, set checked to true as there is no such checkbox for single accumulator bet
						if (typeof(checked) == "undefined") {
							checked = true;
						}
						stakeValues[$(this).attr("id")] = $(this).find("div.slip-stake input[type='text']").val() + "_" + checked;
						inputFlag = true;
					}
				});
				// if we pushed something to object, store a variable
				if (inputFlag) {
					return uWin.api.storeValue("stakeValues", stakeValues);
				}
			}
		});

    });
} (jQuery);
