/*global jQuery*/
"use strict";
(function() {
    var window = this,
		$ = jQuery,
		model,
		view;

    view = {
        init: function() {
            if ($("#gMap").length) {
                $.kff.tableFix();
                model.addToQue(false, ['GetCoords', { pageId: parseInt($('#currentPageId').val(), 10)}], $.kff.kffMap);
            }
            else if ($("#pId").length) {
                model.addToQue(false, ['GetCoords', { pageId: parseInt($('#currentPageId').val(), 10)}], $.kff.kffMapList);
            }
        }
    };

    model = {
        /**
        * Handles the response from jQuery ajax object
        * @param {Array} data	JSON data loaded from server.
        * @param {String} queId	ID of current que, could also be bool False if no que is used.
        */
        handleResponse: function(data, queId) {
            if (data.d.ResponseStatus !== 200) {
                this.handleError(data.d.ResponseMessage);
                return false;
            }

            if (!queId) {
                this.que.tmpCallback(data.d.ResponseData[0].Value);
            } else {
                var i = 0,
                    l = data.d.ResponseData.length,
					x;

                for (x in this.que[queId]) {
                    if (this.que[queId][x]) {
                        for (i = 0; i < l; i += 1) {
                            if (data.d.ResponseData[i].CommandName.toLowerCase() === x.toLowerCase()) {
                                this.que[queId][x].callback(data.d.ResponseData[i].Value);
                            }
                        }
                    }
                }

                model.resetQue(queId);
            }
        },
        /**
        * Holds que objects. Each que should have a unique name and contains properties with correspondant names of the name of webservice to be called
        */
        que: {
            que1: {
                GetTwitter: false,
                GetFriends: false
            },

            que2: {
                AddAccount: false,
                AddSubscriber: false
            }
        },
        /**
        * Add new Que Item to que based on queId. If que is full. Trigger the JSON request. ie. 
        * USAGE: model.addToQue('que1', ['AddStuff', { name: 'stuff' }], view.removeStuff)
        * 
        * @param {String} queId	ID of current que, cloud also be bool False it no que is used.
        * @param {Array} payload	Array containg Webservie name and arguments ie. ['DoStuff',  { name : 'lorem ipsum' }]
        * @param {Function} callback	Callback method
        */
        addToQue: function(queId, payload, callback) {
            var quePayload,
				i,
				queObj = { Name: payload[0], Params: [] };

            for (i in payload[1]) {
                queObj.Params.push({ Name: i, Value: payload[1][i] });
            }

            if (!queId) {
                this.que.tmpCallback = callback;

                this.doJsonPost({ request: { Commands: [queObj]} }, false);
                return;
            } else if (this.que[queId][payload[0]]) {
                return false;
            }

            if (typeof this.que[queId] === 'undefined' || typeof this.que[queId][payload[0]] === 'undefined') {
                this.handleError('No queId with the name ' + queId + ' or the queItem ' + payload[0] + ' is not in the que ' + queId);
            }

            this.que[queId][payload[0]] = {};
            this.que[queId][payload[0]].payload = queObj;
            this.que[queId][payload[0]].callback = callback;

            if (this.isQueReady(queId)) {
                quePayload = this.getQuePayload(queId);
                this.doJsonPost(quePayload, queId);
            }
        },
        /**
        * Check if que is ready to be triggered.
        * @param {String} queId	ID of current que.
        * @return {Boolean}	Returns true if que is ready.
        */
        isQueReady: function(queId) {
            var isReady = true,
				i;

            for (i in this.que[queId]) {
                if (!this.que[queId][i]) {
                    isReady = false;
                    break;
                }
            }

            return isReady;
        },
        /**
        * Get current ques payload as and Array.
        * @param {String} queId	ID of current que.
        * @return {Array}	Payload array with main webservice methods as first argument.
        */
        getQuePayload: function(queId) {
            var payloadArray = [],
				i;

            for (i in this.que[queId]) {
                if (this.que[queId][i]) {
                    payloadArray.push(this.que[queId][i].payload);
                }
            }

            return { request: { Commands: payloadArray} };
        },
        /**
        * Resets the que of current queId.
        * @param {String} queId	ID of current que.
        */
        resetQue: function(queId) {
            var i;
            for (i in this.que[queId]) {
                if (this.que[queId][i]) {
                    this.que[queId][i] = false;
                }
            }
        },
        /**
        * Triggers jQuery's ajax method and triggers handleResponse method passing loaded data and queId.
        * @param {Array} payload	Array to be posted to webservice.
        * @param {String} queId	ID of current que.
        */
        doJsonPost: function(payload, queId) {
            $.ajax({
                url: '/Services/ClientDataTransferService.asmx/GetData',
                type: 'post',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify(payload),
                callback: queId,
                success: function(data) {
                    var arg = [data, this.callback];
                    model.handleResponse.apply(model, arg);
                },
                error: model.handleError
            });
        },
        /**
        * Throws error from jQuery ajax method.
        */
        handleError: function(err) {
            throw new Error(err);
        }
    };

    $.extend({ view: view });

    $(document).ready(function() {
        $.runInit($.view);
    });

} ());