﻿/// <reference path="jquery-1.2.6.js" />
/// <reference path="ConsoleHelper.js" />
/// <reference path="QueryStringHelper.js" />
/// <reference path="JavascriptHelper.js" />
// Host we are connecting to
var host = 'localhost';
// Port we are connecting on
var port = 8080;
var loadPageXml = '<root type="LoadPage"><Token>{token}</Token><Language>{language}</Language></root>';
var createCakeXml = '<root type="CreateCake"><CreateCake imageNumber="{imageNumber}"></CreateCake></root>';
var consumableMediaActivationXml = '<root type="ConsumableMedia"><CreditsActivated /></root>';
var purchasCompleteXml = '<root type="ImageCredits"><PurchaseCompleted /></root>';

var socket;
var userToken = null;
var queuedPayload = new Array();
var connectionError = false;
var failOnConnectionError = false;

var socketHome = '#socket'
var reconnectTime = 7000;
var reconnectTimer;

function initApp(token) {
	///	<summary>
	///		Creates a connection to the app then sends along the user token.
	///     This connection is only closed when leaving the current page.
	///     The app uses this to determine if we are still connected.
	///     Any attempts to send data to socket server will be queued and sent
	///     once a connection is established even if there is a failure.
	///	</summary>
	///	<param name="token" type="String">
	///		User's asp.net session token.
	///	</param>
	///	<returns type="void" />
	userToken = token;

	if (socket == null) {
		socket = new jsXMLSocket();
		socket.onReady = socketOnReady;
		socket.onConnect = socketOnConnect;
		socket.onClose = socketOnClose;
		//socket.onData = socketOnData;
	}

	if (socket.target == undefined) {
		socket.setup(socketHome);
	}
}

function socketOnReady() {
	window.log("Socket ready, attempting to connect");
	socket.connect(host, port);
	window.log('Connecting to ' + host + ':' + port + '... ');
}

function socketOnConnect(success, error) {
	clearInterval(reconnectTimer);
	reconnectTimer = -1;
	if (success) {
		window.log("Connected.");
		TINY.box.hide();
		connectionError = false;

		//First thing to do whenever we connect is to send the token
		sendToken(token);

		//Try to send the queue
		sendQueue();
	} else {
		window.log("Connection failed: ".format(error));
		connectionError = true;
		checkConnectionError();
	}
}

function socketOnClose() {
	window.log('Server disconnected.');
	startReconnectTimer();
	TINY.box.show($('#OverlayDisconnect').html(), 0, 557, 375, 1);
}

function startReconnectTimer() {
	window.log('Starting reconnect timer...');
	reconnectTimer = setInterval(reconnect, reconnectTime);
}

function socketOnData() {
	window.log(data);

	//TODO
}

function reconnect() {
	window.log('Attempting reconnect.');
	if (socket == null) {
		socket = new jsXMLSocket();
		socket.onReady = socketOnReady;
		socket.onConnect = socketOnConnect;
		socket.onClose = socketOnClose;
		//socket.onData = socketOnData;
	}

	if (socket.target == undefined) {
		socket.setup(socketHome);
	} else {
		socketOnReady();
	}
}

function sendToken(token) {
	var sendTokenPayload = loadPageXml.replace('{token}', userToken).replace('{language}', languageID);
	sendOrQueue(sendTokenPayload, false);
}

function CreateCake(imageNumber) {
	if (socket == null || socket.target == undefined || !socket.connected || connectionError) {
		showConnectionErrorMessage();
	} else {
		if (userToken == null) {
			// User isn't logged in
			CreateCake_error();
			return;
		}
		if (imageNumber == undefined) {
			imageNumber = "";
		}

		var xml = createCakeXml.replace('{imageNumber}', imageNumber);
		sendOrQueue(xml, true);
	}
}

function sendAppMediaCreditsRedeemed() {
	///<summary>
	/// Notifies app that media credits have been redeemed
	///</summary>
	///	<returns type="void" />
	sendOrQueue(consumableMediaActivationXml);
}

function sendAppImageCreditsPurchased() {
	///<summary>
	/// Notifies app that either image credits or a terms subscription has been purchased
	///</summary>
	///	<returns type="void" />
	sendOrQueue(purchasCompleteXml);
}

function sendOrQueue(payload, failOnConnectionError_) {
	///	<summary>
	///		Either sends the payload to the socket server or queues it to be sent once connected.
	///	</summary>
	///	<param name="payload" type="String">
	///		String to be sent
	///	</param>
	///	<param name="failOnConnectionError_" type="Boolean">
	///		(Optional) Show an error message if a connection can not be made.  Default false.
	///	</param>
	///	<returns type="void" />

	//Set default value
	failOnConnectionError_ = (failOnConnectionError_) ? failOnConnectionError_ : false;

	if (failOnConnectionError_) {
		failOnConnectionError = true;
		window.log("Setting failOnConnectionError: " + failOnConnectionError);
	}

	if (socket != null && socket.target != undefined && socket.connected || connectionError) {
		sendData(payload, failOnConnectionError_);
	} else {
		var obj = new Object();
		obj.data = payload;
		window.log("Adding to queue - data: {0}".format(obj.data));
		queuedPayload.push(obj);
	}
}

function sendQueue() {
	window.log("Sending entire queue");
	var obj;
	while (queuedPayload.length > 0) {
		obj = queuedPayload.shift();
		sendData(obj.data);
	}
}

function checkConnectionError() {
	if (connectionError && failOnConnectionError) {

		var statusMsg = "Status - connectionError: {0}; failOnConnectionError: {1}";
		window.log(statusMsg.format(connectionError, failOnConnectionError));

		showConnectionErrorMessage();

		return true;
	}
	else {
		return false;
	}
}

function sendData(data, failOnConnectionError) {
	window.log("Sending: " + data);
	if (!checkConnectionError()) {
		try {
			socket.send(data);
		} catch (e) {
			window.log(e);
			if (failOnConnectionError) {
				showConnectionErrorMessage();
			}
		}
	} else {
		//Start listening for the app again
		startReconnectTimer();
	}
}

function showConnectionErrorMessage() {
	window.log("***Connection error***");
	TINY.box.show($('#OverlaySocket').html(), 0, 557, 375, 1);
}
