﻿/// <reference name="MicrosoftAjax.js"/>

Math.countCombinations = function (n, k) {
	if (k > n / 2)
		return Math.multiplyInTurn(k + 1, n) / Math.multiplyInTurn(1, n - k);
	else
		return Math.multiplyInTurn(n - k + 1, n) / Math.multiplyInTurn(1, k);
}
Math.multiplyInTurn = function (start, end) {
	var result = 1;
	for(var num = start; num <= end; num++)
		result *= num;
	return result;
}

Type.registerNamespace('BBWebMethods.Sportsbook');

/// <summary>
/// ContentUpdateInitiator class
/// </summary>
BBWebMethods.Sportsbook.ContentUpdateInitiator = function () {
	this._updateTokens = null;
	this._queryInterval = null;

	BBWebMethods.Common.WebScriptProxyHelper.ensureCorrectScheme(BlueBrown.Web.Services.SportsbookScriptService);

	this._serviceProxy = new BlueBrown.Web.Services.SportsbookScriptService();
	var succeededCallback = Function.createDelegate(this, this._on_succeeded);
	this._serviceProxy.set_defaultSucceededCallback(succeededCallback);
	var failedCallback = Function.createDelegate(this, this._on_failed);
	this._serviceProxy.set_defaultFailedCallback(failedCallback);

	this._queryUpdateCallback = Function.createDelegate(this, this.do_queryUpdate);
	this._timeoutId = null;

	this._numErrors = 0;
}
BBWebMethods.Sportsbook.ContentUpdateInitiator.prototype = {
	setTokens: function (updateTokens, queryInterval) {
		this._updateTokens = updateTokens;
		this._queryInterval = queryInterval;
	},

	start: function () {
		if (this._queryInterval)
			this._timeoutId = setTimeout(this._queryUpdateCallback, this._queryInterval);
	},

	stop: function () {
		clearTimeout(this._timeoutId);
	},

	do_queryUpdate: function () {
		if (this._updateTokens)
			this._serviceProxy.IsContentChanged(this._updateTokens);
	},

	_on_succeeded: function (result, userContext, methodName) {
		if (result) {
			bb_ContentUpdate(this._updateTokens);
		}
		this.start();
	},

	_on_failed: function (error) {
		this._numErrors++;
		if (this._numErrors < 10)
			this.start();
		else
			location.reload();
	}
}
BBWebMethods.Sportsbook.ContentUpdateInitiator.registerClass('BBWebMethods.Sportsbook.ContentUpdateInitiator');

/// <summary>
/// BetSlipWinnings class
/// </summary>
BBWebMethods.Sportsbook.BetSlipWinnings = function (inputIds, stakeId, winningsId) {
	this._inputTextBoxIds = inputIds;
	this._stakeLabel = $get(stakeId);
	this._winningsLabel = $get(winningsId);

	this._priceCount = 0;
	this._prices = [];
	this._costs = [];
	this._winnings = [];

	this._stakeLabel.innerHTML = '0.0';
	this._winningsLabel.innerHTML = '0.0';
	this._timeoutId = null;

	this._updateCallback = Function.createDelegate(this, this._on_update);
	this._keypressCallback = Function.createDelegate(this, this._on_scheduleUpdate);
	for (var idx = 0; idx < this._inputTextBoxIds.length; idx++) {
		var parts = this._inputTextBoxIds[idx].split(':');
		var textboxId = parts[0];
		var price = parseFloat(parts[1]);

		if (price != 0) {
			this._prices[textboxId] = price;
			this._priceCount++;
		}

		var textbox = $get(textboxId);
		this.update(textbox);
		$addHandler(textbox, 'change', this._updateCallback);
		$addHandler(textbox, 'keyup', this._keypressCallback);
	}
}
BBWebMethods.Sportsbook.BetSlipWinnings.FoldsMap = {
	'DOUBLES': 2,
	'TREBLES': 3,
	'FOUR_FOLD': 4,
	'FIVE_FOLD': 5,
	'SIX_FOLD': 6,
	'SEVEN_FOLD': 7,
	'EIGHT_FOLD': 8,
	'NINE_FOLD': 9,
	'TEN_FOLD': 10
};
BBWebMethods.Sportsbook.BetSlipWinnings.prototype = {
	update: function (inputBox) {
		var multiType = 'SINGLE';
		if (inputBox.getAttribute('multiplestype'))
			multiType = inputBox.getAttribute('multiplestype');
		switch (multiType) {
			case 'SINGLE':
				this._costs[inputBox.id] = this._getSafeStake(inputBox);
				this._winnings[inputBox.id] = this._getSingleWinnings(inputBox);
				break;
			case 'DOUBLES':
			case 'TREBLES':
			case 'FOUR_FOLD':
			case 'FIVE_FOLD':
			case 'SIX_FOLD':
			case 'SEVEN_FOLD':
			case 'EIGHT_FOLD':
			case 'NINE_FOLD':
			case 'TEN_FOLD':
				var n = this._priceCount;
				var k = BBWebMethods.Sportsbook.BetSlipWinnings.FoldsMap[multiType];
				var combs = Math.countCombinations(n, k);
				this._costs[inputBox.id] = this._getSafeStake(inputBox) * combs;
				this._winnings[inputBox.id] = this._getCombinationWinnings(inputBox, k);
				break;
			case 'ACCUMULATOR':
				this._costs[inputBox.id] = this._getSafeStake(inputBox);
				this._winnings[inputBox.id] = this._getAccumulatorWinnings(inputBox);
				break;
		}
		this._updateCost();
		this._updateWinnings();
	},

	_on_update: function (evt) {
		var inputBox = evt.target;
		this.update(inputBox);
	},

	_on_scheduleUpdate: function (evt) {
		if (this._timeoutId)
			clearTimeout(this._timeoutId);
		var callback = this._updateCallback;
		this._timeoutId = setTimeout(function () { callback(evt); }, 500);
	},

	_updateCost: function () {
		var cost = 0;
		for (var id in this._costs)
			cost += this._costs[id];
		this._stakeLabel.innerHTML = cost.localeFormat('n2');
	},

	_updateWinnings: function () {
		var winnings = 0;
		for (var id in this._winnings)
			winnings += this._winnings[id];
		this._winningsLabel.innerHTML = winnings.localeFormat('n2');
	},

	_getSingleWinnings: function (inputBox) {
		return this._prices[inputBox.id] * this._getSafeStake(inputBox);
	},
	_getCombinationWinnings: function (inputBox, k) {
		var prices = new Array();
		var i = 0;
		for (var id in this._prices) {
			prices[i++] = this._prices[id];
		}
		var combinations = new BBWebMethods.Sportsbook.Combinations(prices, k);

		var comb = combinations.next();
		var winnings = 0;
		while (comb) {
			var combinedPrice = 1;
			for (i = 0; i < comb.length; i++)
				combinedPrice *= comb[i];
			winnings += combinedPrice * this._getSafeStake(inputBox);
			comb = combinations.next();
		}
		return winnings;
	},
	_getAccumulatorWinnings: function (inputBox) {
		var combinedPrice = 1;
		for (var id in this._prices)
			combinedPrice *= this._prices[id];
		return combinedPrice * this._getSafeStake(inputBox);
	},

	_getSafeStake: function (inputBox) {
		try {
			var stake = Number.parseLocale(inputBox.value.trim());
			return isFinite(stake) ? stake : 0;
		} catch (Exception) {
			return 0;
		}
	}
}
BBWebMethods.Sportsbook.BetSlipWinnings.registerClass('BBWebMethods.Sportsbook.BetSlipWinnings');

/// <summary>
/// Combinations class
/// </summary>
BBWebMethods.Sportsbook.Combinations = function (elements, k) {
	this._elements = elements;
	this._k = k;
	this._maxIdx = elements.length - 1;
	this._indices = null;
}
BBWebMethods.Sportsbook.Combinations.prototype = {
	next: function () {
		if (!this._indices) {
			this._indices = new Array(this._k);
			for (var i = 0; i < this._k; i++)
				this._indices[i] = i;
		}
		else {
			var idx = this._k;
			for (var i = this._indices.length - 1; i >= 0; i--) {
				if (this._indices[i] < this._maxIdx - (this._k - 1 - i)) {
					idx = i;
					break;
				}
			}

			if (idx == this._k)
				return null;

			this._indices[idx]++;
			for (i = idx + 1; i < this._indices.length; i++)
				this._indices[i] = this._indices[i - 1] + 1;
		}

		var ret = new Array(this._k);
		for (i = 0; i < this._indices.length; i++)
			ret[i] = this._elements[this._indices[i]];
		return ret;
	}
}
BBWebMethods.Sportsbook.Combinations.registerClass('BBWebMethods.Sportsbook.Combinations');

/// <summary>
/// ElapsedTimeCounter class
/// </summary>
BBWebMethods.Sportsbook.ElapsedTimeCounter = function (elapsedTimeMillis, displayElementId) {
	this._startTime = new Date().getTime() - elapsedTimeMillis;
	this._displayElement = $get(displayElementId);

	this._intervalCallback = Function.createDelegate(this, this._on_interval);
	this._intervalId = null;
}
BBWebMethods.Sportsbook.ElapsedTimeCounter.prototype = {
	start: function () {
		this._intervalId = setInterval(this._intervalCallback, 1000);
	},

	_on_interval: function () {
		var elapsed = (new Date().getTime() - this._startTime);

		var mins = Math.floor(elapsed / (1000 * 60));
		elapsed -= mins * (1000 * 60);
		var secs = Math.floor(elapsed / 1000);

		var minsText = mins >= 10 ? mins.toString() : '0' + mins.toString();
		var secsText = secs >= 10 ? secs.toString() : '0' + secs.toString();
		this._displayElement.innerHTML = minsText + ':' + secsText;
	}
}
BBWebMethods.Sportsbook.ElapsedTimeCounter.registerClass('BBWebMethods.Sportsbook.ElapsedTimeCounter');

/// <summary>
/// ElapsedTimeCountdown class
/// </summary>
BBWebMethods.Sportsbook.ElapsedTimeCountdown = function (countdownSecs, displayElementId, showFullTime) {
	this._countdownSecs = countdownSecs;
	this._displayElement = $get(displayElementId);
	this._showFullTime = showFullTime;

	this._updateDisplayElement();

	this._intervalCallback = Function.createDelegate(this, this._on_interval);
	this._intervalId = null;
}
BBWebMethods.Sportsbook.ElapsedTimeCountdown.prototype = {
	start: function () {
		this._intervalId = setInterval(this._intervalCallback, 1000);
	},

	_on_interval: function () {
		this._countdownSecs--;

		this._updateDisplayElement();

		if (this._countdownSecs <= 0) {
			clearInterval(this._intervalId);
		}
	},

	_updateDisplayElement: function () {
		if (this._showFullTime) {
			var mins = Math.floor(this._countdownSecs / 60);
			var secs = this._countdownSecs % 60;

			var minsText = mins >= 10 ? mins.toString() : '0' + mins.toString();
			var secsText = secs >= 10 ? secs.toString() : '0' + secs.toString();
			this._displayElement.innerHTML = minsText + ':' + secsText;
		} else
			this._displayElement.innerHTML = this._countdownSecs.toString();
	}
}
BBWebMethods.Sportsbook.ElapsedTimeCountdown.registerClass('BBWebMethods.Sportsbook.ElapsedTimeCountdown');

if (Sys && Sys.Application) {
	Sys.Application.notifyScriptLoaded();
}

