/*
 * $Id: betslip.js,v 1.28 2011-06-27 13:35:02 pmiller Exp $
###################################################################################################
#                                                                                                 #
#   SLIPBETS cookie structure:                                                                    #
#                                                                                                 #
#   Where there is a single bet stored:                                                           #
#   saxgame|cost|plan|sels|incl                                                                   #
#                                                                                                 #
#   incl (included) refers to whether there is a tick next to the bet on the betslip.             #
#                                                                                                 #
#   Where there is more than 1 bet the cookie structure is of the form:                           #
#   saxgame#1|cost#1|plan#1|sels#1|incl#1_saxgame#2|cost#2|plan#2|sels#2|incl#2                   #
#                                                                                                 #
###################################################################################################
*/



// Betslip object. Properties can be added in the same fashion as SA_Betslip where necessary.
SA_Betslip = function() {

	// To hold data about the betslip.

}

SA_Betslip.addToSlipTimeout = null;

// Generic initialisation code for the betslip.
SA_betslip_init = function() {

	SA_betslip_obj = new SA_Betslip();

	// Initialise betslip contents according to cookies the customer may have.
	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsUpdateBetSlip&"+SA_get_no_cache_param(),
		'callback': SA_betslipUpdateCallback,
		'debug'   : true
	} );

}



// Switch bet inclusion.
SA_Betslip.prototype.switchInclusion = function(bet_num) {

	// Switch the values to what is currently stated.
	var included;
	if (document.getElementById('bs_bet_'+bet_num).checked == true) {
		included = '1';
	} else {
		included = '-';
	}

	// Make request.
	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsSwitchInclusion&bet_num="+bet_num+"&included="+included+"&"+SA_get_no_cache_param(),
		'callback': SA_betslipSwitchInclusionCallback,
		'debug'   : true
	} );



}


// Kick off for slip placement.
// This is invoked from betslip submission.
SA_Betslip.prototype.startBetProcess = function() {

	// Strategy based on login status.
	if (SA_IS_GUEST) {
		showPanelNoEvent($("#panelLoginJoin"), close);
	} else {
		SA_betslipBetPlaceGateway();
	}

}



// Place bets on slip.
SA_Betslip.prototype.placeBets = function() {

	var num_bets = document.getElementById('bs_bet_count').value;
	// Shouldn't happen - sanity check.
	if (num_bets == 0) {
		alert("No bets to place.");
		return;
	}

	// Place the bets.
	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsPlaceSelectSlipBets&"+SA_get_no_cache_param(),
		'callback': SA_betslipPlacedResultsCallback,
		'debug'   : true,
		'timeoutmsecs'    : SA_REQUEST_TIMEOUT,
		'timeoutcallback' : function(){
						// This code will be executed if a timeout occurs. The contents of the modal panel will be replaced.
						showPanelNoEvent($("#panelPlaceBetsTimeout"), true);
						document.getElementById('betslip_report').innerHTML = "<h3 class='header'>" +
												      SA_XL('SA_BETSLIP_TIMOUT_ERR_HEADER') + 
												      "</h3><p class='BetSlipTimeout'>" + 
												      SA_XL('SA_BETSLIP_TIMOUT_ERR_BODY') + 
												      "</p>";
						var modal = $.modal.impl;
					
						modal.d.container.prepend($(modal.o.closeHTML).addClass(modal.o.closeClass));
					
						modal.unbindEvents();
						modal.bindEvents();
				    }
	} );

}

// Stores the previous request arguments so we can go back to where we were.
SA_betslip_old_get_state = null;
SA_betslip_old_coupons = null;

// Generate editable coupon.
// This is invoked from the comp link on the betslip.
SA_Betslip.prototype.editBet = function(saxgame_id,bet_num) {

	if (!SA_betslip_old_coupons) {
		SA_betslip_old_coupons = SA_coupon_ids.join(" ");
	}

	if (!SA_betslip_old_get_state) {
		SA_betslip_old_get_state = new Object();
		SA_betslip_old_get_state.criteria = SA_moreCouponsFetchParams.criteria;
		SA_betslip_old_get_state.value    = SA_moreCouponsFetchParams.value;
	}

	$("#SA_MoreCouponsButton").hide();
	$("#SA_BackToCouponsButton").show();

	// Show the relevant coupon.
	SA_get_coupons_by_bet_num(bet_num);

	// Close
	SA_switchBetslip();

}



// Update bet number on coupon button.
SA_Betslip.prototype.updateBetslipCount = function() {

	// Get the count.
	var bet_count = this.checkBetSlipCount();

	// Write out value.
	document.getElementById('bs_bet_count').value = bet_count;

}




// Check current betslip count value.
SA_Betslip.prototype.checkBetSlipCount = function(count_disabled) {

	var cookie_contents = getCookie(SA_BETSLIP_COOKIE_NAME);
	if (cookie_contents == "" || cookie_contents == null) {
		return 0;
	}

	// Count separators.
	var bet_count = 0;
	var bets = cookie_contents.split(SA_BETSLIP_SEPARATOR);
	for (var i = 0; i < bets.length; i++) {
		// Check to see if the inclusion is 1
		// if it is, increment the counter
		var bet_properties_array = bets[i].split(SA_BET_PROPERTY_SEPARATOR);
		if (bet_properties_array[5] == "1" || count_disabled) {
			bet_count++;
		}
	}

	return bet_count;

}


// Wipe the contents of the betslip cookie.
SA_Betslip.prototype.clearBetSlip = function() {

	// Update the betslip.
	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsDeleteSlipCookie",
		'callback': SA_betslipUpdateCallback,
		'debug'   : true
	} );

	// Close the empty betslip.
	document.getElementById('parent_betslip_container').className = betslip_close_state;

	// Update total stake displayed.
	SA_betslip_obj.calculateTotalStake();

}



// Delete a specific selection from the betslip. Works on the basis of a bet iterator id since
// there could be multiple bets with the same selections on the same competition. This provides
// uniqueness.
SA_Betslip.prototype.deleteBetSlipSelection = function(bet_num) {

	// Update the betslip.
	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsDeleteSlipBatch&bet_nums="+bet_num+"&"+SA_get_no_cache_param(),
		'callback': SA_betslipAddDelCallback,
		'debug'   : true
	} );

	var total_num = SA_betslip_obj.checkBetSlipCount();

	// If the deleted selection was not the last bet the bets need renumbering.
	if (bet_num + 1 != total_num) {
		for (var i = bet_num; i < total_num; i++) {
			var next_i = i + 1;
			document.getElementById('bs_bet_'+i).id = 'bs_bet_'+next_i;
		}
	}

}



// Delete specified bets from slip.
SA_Betslip.prototype.deletePlacedFromBetSlip = function () {

	var num_bets = document.getElementById('bet_attempt_count').value;
	var bet_nums = Array();
	var prefix = "bet_place_status_";

	// Determine which bets are marked to delete.
	// Also, delete those which failed because comp was closed.
	var j = 0;
	for (var i = 0; i < num_bets; i++) {
		var element = document.getElementById(prefix + i);
		var reason  = document.getElementById(prefix + 'code_' + i);
		if ((element && element.value == 1) || (reason && reason.value == 'CLOSED')) {
			bet_nums[j] = i;
			j++;
		}
	}

	// Comma separated string of bets to delete.
	var bet_nums = bet_nums.join(",");

	var r = SA_singleton_request_broker.instance();
	r.send( {
		'priority': r.COUPONS_PRI,
		'method'  : 'GET',
		'url'     : "?action=GoPoolsDeleteSlipBatch&bet_nums="+bet_nums+"&"+SA_get_no_cache_param(),
		'callback': SA_betslipUpdateCallback,
		'debug'   : true
	} );

	SA_betslip_obj.calculateTotalStake();

}



// Calculate the stake based on items on betslip that are included.
SA_Betslip.prototype.calculateTotalStake = function () {

	// Extract the stakes currently in the cookie.
	var total_stake = parseFloat(0.00);
	var do_calc     = 1;

	// Some browsers throw an error if we do the split below on an empty var
	var cookie_contents = getCookie(SA_BETSLIP_COOKIE_NAME);

	if (cookie_contents == null) {
		do_calc = 0;
	}

	// Extract all the stakes for the bets in the cookie.
	if (do_calc) {
		var bet_array            = cookie_contents.split(SA_BETSLIP_SEPARATOR);
		var bet_properties_array = Array();
		var stake_array          = Array();
	

		// bet_properties_array:
		//   saxgame_id|stake|num_subs|plan|selections
		for (var i = 0; i < bet_array.length; i++) {
			bet_properties_array = bet_array[i].split(SA_BET_PROPERTY_SEPARATOR);
			stake    = bet_properties_array[1];
			num_subs = bet_properties_array[2];
			stake_array[i] = stake * num_subs;
		}
	}

	// Exit now if nothing on betslip.
	var num_bets = document.getElementById('bs_bet_count').value;
	if (num_bets == 0) {
		do_calc = 0;
	}

	// Sum the stakes for the bets that are included.
	if (do_calc) {
		var num_bets = cookie_contents.split(SA_BETSLIP_SEPARATOR).length;
		// Add to total stake only where bet is included.
		for (var i = 0; i < num_bets; i++) {
			if (document.getElementById('bs_bet_'+i).checked) {
				total_stake = total_stake + parseFloat(stake_array[i]);
			}
		}
	}

	document.getElementById('total_stake').innerHTML = total_stake.toFixed(2);
	document.getElementById('bs_bet_value').innerHTML = '(&pound;' + total_stake.toFixed(2) + ')';

}



// Gateway proc to place bets.
SA_betslipBetPlaceGateway = function() {

	// Close the betslip.
	document.getElementById('parent_betslip_container').className = betslip_close_state;

	// Show the progress panel.
	showPanelNoEvent($("#panelPlaceBets"), false);

	// Delay for a couple of seconds for smoother transition to report.
	var thread_id = setTimeout("SA_betslip_obj.placeBets();",2000);

}



// Callback function for bet placement.
SA_betslipPlacedResultsCallback = function (xmlhttp) {

	// Get response.
	var response = xmlhttp.responseText;

	// Deal with, predominantly, timeout errors.
	if (response == 'ERROR') {
		// technical error
		//showPanelNoEvent(GoPoolsGetErrorPanel);
	}

	document.getElementById('betslip_report').innerHTML = response;

	// Get rid of those included items.
	SA_betslip_obj.deletePlacedFromBetSlip();

	var modal = $.modal.impl;

	modal.d.container.prepend($(modal.o.closeHTML).addClass(modal.o.closeClass));

	modal.unbindEvents();
	modal.bindEvents();

	if (updateAccountBalances) {
		updateAccountBalances();
	}
	SA_refreshCouponBetCounts();

}


// Callback function for betslip update.
SA_betslipUpdateCallback = function(xmlhttp) {

	var response = xmlhttp.responseText;

	document.getElementById('betslip_container').innerHTML = response;

	// Adjust to reflect status.
	SA_betslip_obj.updateBetslipCount();
	SA_betslip_obj.calculateTotalStake();

}

// Wrapper for the addDelCallback function
SA_betsAddToSlipCallback = function(xmlhttp) {
	SA_betslipAddDelCallback(xmlhttp);

	if(SA_Betslip.addToSlipTimeout) clearTimeout(SA_Betslip.addToSlipTimeout);
	SA_Betslip.addToSlipTimeout = setTimeout(SA_closeBetslip,SA_ADDTOSLIP_TIMEOUT);
}

// Callback for add to slip.
SA_betslipAddDelCallback = function(xmlhttp) {

	var response = xmlhttp.responseText;

	if(SA_betslip_checkAJAXError(response)) return;

	document.getElementById('betslip_container').innerHTML = response;

	// Adjust to reflect status.
	SA_betslip_obj.updateBetslipCount();

	SA_betslip_obj.calculateTotalStake();

	var total_num = SA_betslip_obj.checkBetSlipCount();
	// Collapse betslip with no selections.
	if (total_num == 0) {
		SA_switchBetslip();
	} else {
		SA_openBetslip();
	}
}

// Checks to see if an AJAX response is an error message
SA_betslip_checkAJAXError = function(response) {

	if (response.split('|')[0] == "ERROR") {
		/* Note that the AJAX error reply will have the format:
			"ERROR"|GEN_BETSLIP_ERR|err_msg
			where 
				GEN_BETSLIP_ERR is a translation code and
				err_msg is a more refined description of the mesage (currently not displayed)
			
		*/
		showPanelNoEvent($("#panelSlipOpsErr"), true);
		return true;
	}

	return false;
}

// Callback for inclusion switch.
SA_betslipSwitchInclusionCallback = function(xmlhttp) {

	// Determine new stake level.
	SA_betslip_obj.updateBetslipCount();
	SA_betslip_obj.calculateTotalStake();

}



// Open the betslip on command.
function SA_openBetslip () {

	if (document.getElementById('parent_betslip_container').className == betslip_close_state) {
		document.getElementById('parent_betslip_container').className = betslip_open_state;
	}

	// User invoked rather than onload. This way we can be certain the betslip is fully loaded befor
	// accessing items within it.
	SA_betslip_obj.calculateTotalStake();

}


// Close the betslip on command.
function SA_closeBetslip () {

	if (document.getElementById('parent_betslip_container').className == betslip_open_state) {
		document.getElementById('parent_betslip_container').className = betslip_close_state;
	}

}

// Switch open/close of betslip.
function SA_switchBetslip () {

	if (document.getElementById('parent_betslip_container').className == betslip_close_state) {
		document.getElementById('parent_betslip_container').className = betslip_open_state;
	} else {
		document.getElementById('parent_betslip_container').className = betslip_close_state;
	}

	// User invoked rather than onload. This way we can be certain the betslip is fully loaded befor
	// accessing items within it.
	SA_betslip_obj.calculateTotalStake();

}

// Populate selections on coupon when editing.
SA_Betslip.prototype.populateSelections = function(saxgame_id,bet_num,num_cols,num_balls) {

	// Get the cookie contents.
	var cookie_contents = getCookie(SA_BETSLIP_COOKIE_NAME);
	if (cookie_contents == "" || cookie_contents == null) {
		alert('Unable to find cookie');
		return;
	}

	var bets_array = cookie_contents.split(SA_BETSLIP_SEPARATOR);
	var bet;
	// There is only 1 bet in the cookie.
	if (bets_array.length == 0) {
		bet = cookie_contents;
	} else {
		bet = bets_array[bet_num];
	}

	if (bet == "" || bet == null) {
		alert('Unable to find bet');
		return;
	}

	// Extract required bet information.
	var bet_properties = bet.split(SA_BET_PROPERTY_SEPARATOR);
	var saxgame_id     = bet_properties[0];
	var selections     = bet_properties[4];

	var cpn_obj = SA_coupons['cpn_'+saxgame_id];

	if (saxgame_id == "" || saxgame_id == null || selections == "" || saxgame_id == null) {
		alert('Unable to find selections for bet');
		return;
	}
	
	// Tick selections stored in cookie.
	var selection_arr = Array();
	var selection_arr = selections.split(SA_SEPARATOR_BET_SELECTIONS);

	_validateTCHCoupon(bet_properties);

	var row = 0;
	var col = 0;

	// Foreach ball possibly selected
	for (var i = 0; i < num_balls; i++) {
		// If it is stored in the seleciton array
		if (SA_arrayContains(selection_arr,i)) {
			// Tick it
			cpn_obj.buttonClick(row,col);
			//document.getElementById('DATA_'+saxgame_id+'_'+row+'_'+col).checked = true;
		}

		// Advance row and cols for data format.
		if ((i + 1) % num_cols == 0) {
			row++;
			col = 0;
		} else {
			col++;
		}
	}

}

// Helper function for TCH plan validation
_validateTCHCoupon = function(bet_properties) {

	if (!$('#cpn_' + bet_properties[0]).hasClass('TCH')) return;

	var saxgame_id = bet_properties[0];
	var plan_id    = bet_properties[3];

	var cpn_obj = SA_coupons['cpn_' + bet_properties[0]];

	// switch to the correct plan
	cpn_obj.switchPlan(plan_id,true);

	// Uncheck all plan radios
	$('#cpn_' + saxgame_id + ' .planRadios input:radio').attr('checked', false);

	// If present, check only the one that is in the betstring
	if ( $('#plan-' + plan_id + '-' + saxgame_id + '-fixtures').length > 0 )
		$('#plan-' + plan_id + '-' + saxgame_id + '-fixtures').attr('checked', true);
}

// Helper method for populateSelections.
function SA_arrayContains (array,element) {

	for (var i = 0; i < array.length; i++) {
		adjusted_selection = array[i] - 1;
		if (adjusted_selection == element) {
			return true;
		}
	}

	return false;

}



// Removes ( and ) from the given string
function SA_strip_parentheses (string) {

	var parentheses_exp = /[()]/g;
	return string.replace(parentheses_exp, "");

}


// Generates a string of the form:
// nocache=0.4837258245245
// For use in a get request, to avoid caching in IE
SA_get_no_cache_param = function () {

	return "nocache="+Math.random();

}

