/** 
* @author: View: Patricia Adamsson patricia.adamsson@cloudnine.se
* Created: 2010-04-01
*/

"use strict";
(function() {
    var window = this,
		$ = jQuery,
		model,
		view;

    view = {
        indexer: 0,
        init: function() {
            if ($('#fullWidthCol .aliasBox').length) {
                view.toggleAlias();
            }
            if ($('#privacyWrap').length) {
                view.memberPolicy();
            }
            if ($('#mainCol a.opnOlay').length) {
                view.openEditBlogEntry();
            }
            if ($('#mainCol a#askExpert').length) {
                view.openAskExpert();
                view.loadTiny();
            }
            if ($('#oldPw').length) {
                view.passwordCheck();
                view.doPwCheck();
            }
            if ($('#tbContent').length) {
                view.loadTiny();
            }
            if ($('.mceEditor').length) {
                view.loadTiny();
            }
            if ($('#txtContent').length) {
                view.loadTiny();
            }
            if ($(".content").length) {
                view.loadTiny();
            }
        },

        loadTiny: function loadTiny() {
            tinyMCE.init({
                mode: "specific_textareas",
                editor_selector: "mceEditor",
                theme: "advanced",
                plugins: "paste, media, advlink",
                theme_advanced_buttons1: 'bold,italic,underline,separator,outdent,indent,separator,undo,redo,link,unlink,|,cut,copy,paste,pastetext,removeformat,image, media',
                theme_advanced_buttons2: "",
                theme_advanced_buttons3: "",
                theme_advanced_toolbar_location: "top",
                theme_advanced_toolbar_align: "left",
                theme_advanced_statusbar_location: "bottom",
                convert_urls: false,
                theme_advanced_resizing: false
            });
        },

        /**
        * Toggle alias
        * Listens for the alias checkox (newMember.aspx) to be checked. If checked, show box
        */
        toggleAlias: function toggleAlias() {
            var checkbox = $('#fullWidthCol .hideNshow input[type=checkbox]'),
				toToggle1 = $('#fullWidthCol .aliasBox'),
				doCheck = function doCheck() {
				    if (checkbox.is(':checked')) {
				        toToggle1.show();
				    }
				    else {
				        toToggle1.hide();
				    }
				};

            doCheck();

            checkbox.click(function() {
                doCheck();
            });
        },

        /**
        * Toggle member information 
        * Loads the member page into a div if clicked
        */
        memberPolicy: function memberPolicy() {
            var privacy = $('#privacyWrap .privacyBtn'),
				toToggle2 = $('#memberPolicy'),
				theHref = privacy.attr('href');

            privacy.click(function(e) {
                e.preventDefault();
                if ($('#memberPolicy').text() === '') {
                    toToggle2.load(theHref + ' #mainCol .standard div', '', function() {
                        toToggle2.animate({
                            height: 'toggle'
                        }, 400);
                    });
                } else {
                    toToggle2.slideToggle('slow');
                }
            });
        },

        buildOverlay: function buildOverlay() {
            $('body').prepend('<div id="oLay"></div>');
            $('#oLay').css('height', ($(document).height() * 1.05));
            $('#oLay').css('opacity', 0).fadeTo('medium', 0.4);
        },

        hideOverlay: function hideOverlay() {
            $('#oLayplHolder').remove();
            $('#oLay').remove();
        },

        hideOverlayByClick: function hideOverlayByClick() {
            $('#openInLayer input.cancelBtn').click(function(e) {
                e.preventDefault();
                view.hideOverlay();
            });
        },

        hideOverlayByKeypress: function hideOverlayByClick() {
            $(document).keyup(function(e) {
                if (e.keyCode === 27 && $('#oLayplHolder').length) {
                    view.hideOverlay();
                }
            });
        },

        /**
        * Overlay - step 4
        * Handles the AJAX response 
        * Updates the page behind the overlay and closes the overlay
        * @param {Array} data	JSON data loaded from server
        */
        updateBlogEntry: function updateBlogEntry(data) {
            var txtInput = $('#openInLayer input[type="text"]'),
				errorMsg = $('#openInLayer fieldset');

            if (data.Status.status === 'fail') {
                if (('#openInLayer p.error').length) {
                    $('#openInLayer p.error').remove();
                    errorMsg.before('<p class="error">' + data.Status.message + '</p>');
                }
                txtInput.addClass('error');
            }

            if (data.Status.status === 'ok') {
                $('#openInLayer p.error').remove();
                txtInput.removeClass('error');
                $('#mainCol h2.editBlogH2').text(data.Value.titleValue);
                $('#mainCol span.blogContent').empty(); // clear previous content
                $('#mainCol p.editblogTxt').html(data.Value.contentValue);
                view.hideOverlay();
            }
        },

        /**
        * Same as above 
        */
        updateQuestionFeed: function updateQuestionFeed(data) {
            var txtInput = $('#openInLayer input[type="text"]'),
				txtArea = $('#openInLayer textarea'),
				errorMsg = $('#openInLayer fieldset');

            if (data.Status.status === 'fail') {
                if (('#openInLayer p.error').length) {
                    $('#openInLayer p.error').remove();
                    errorMsg.before('<p class="error">' + data.Status.message + '</p>');
                }
                if (txtInput.val().length === 0) {
                    txtInput.removeClass('error');
                    txtInput.addClass('error');
                } else if (txtInput.val().length > 0) {
                    txtInput.removeClass('error');
                }
                if (txtArea.val().length === 0) {
                    txtArea.removeClass('error');
                    txtArea.addClass('error');
                } else if (txtArea.val().length > 0) {
                    txtArea.removeClass('error');
                }
            }

            if (data.Status.status === 'ok') {
                $('#openInLayer fieldset').remove();
                $('#openInLayer p.error').remove();
                $('#openInLayer h1').text(data.Status.message);

                setTimeout(function() {
                    $('#oLay').fadeOut(2200, function() {
                        $(this).remove();
                    });
                    $('#oLayplHolder').fadeOut(2200, function() {
                        $(this).remove();
                    });
                }, 4200);
            }
        },

        /**
        * Overlay - step 3
        * POSTs an AJAX request and calls the callback function 'updateBlogEntry'
        * Positions the box. Loads a page into the box and does the AJAX post
        * @param {string} theHref	Determines what href is to be loaded
        * @param {int} theTop	Sets the top position of the box
        * @param {int} theLeft	Sets the left position of the box		
        * @param {int} popUpW	Height of popup
        * @param {int} popUpH	Width of popup
        * @param {string} source	Determines which variables to use
        */
        loadNewPage: function editBlogEntry(theTop, theLeft, theHref, popUpW, popUpH, source) {
            $('#oLayplHolder').css({ top: theTop, left: theLeft, height: popUpH, width: popUpW }).load(theHref, '', function() {

                view.hideOverlayByClick();

                if (source === 'editBlogEntry') {
                    $('#openInLayer .post').click(function() {
                        var title = $('#openInLayer .blogEntryTitle').val(),
							content = tinyMCE.activeEditor.getContent(),
							entryId = parseInt($('#openInLayer .entryId').val(), 10);
                        model.addToQueue(false, ['SaveBlogEntry', { entryId: entryId, title: title, content: content}], view.updateBlogEntry);
                    });
                }
                if (source === 'askQuestion') {
                    $('#openInLayer .post').click(function() {
                        var title = $('#openInLayer .title').val(),
							content = tinyMCE.activeEditor.getContent(),
							userId = parseInt($('#openInLayer .userId').val(), 10);
                        model.addToQueue(false, ['AskQuestion', { userId: userId, title: title, content: content}], view.updateQuestionFeed);
                    });
                }
            });
        },

        /**
        * Overlay - step 2
        * Builds the overlay based on the params that's been sent it. Calculates the position of the box
        * @param {string} source	Determines what function to call
        * @param {string} href2BOpen	Determines what href is to be loaded
        * @param {int} popUpW	Height of popup
        * @param {int} popUpH	Width of popup
        */
        loadOverlay: function loadOverlay(source, href2BOpen, popUpW, popUpH) {
            $('body').prepend('<div id="oLayplHolder"></div>');

            view.buildOverlay();
            view.hideOverlayByKeypress();

            var scrollTop = 0, //$(window).scrollTop(),
				theHref = href2BOpen + ' #openInLayer',
				theLeft = ($(window).width() / 2) - (popUpW / 2) + 'px',
				theTop = (popUpH > ($(window).height() - 20)) ? (10 + scrollTop) + "px" : (($(window).height() / 2) - (popUpH / 2) + scrollTop) + "px";

            view.loadNewPage(theTop, theLeft, theHref, popUpW, popUpH, source);
        },

        /**
        * Overlay - step 1
        * Calls the function 'loadOverlay'
        * Sends the params to the overlay function
        */
        openEditBlogEntry: function openEditBlogEntry() {
            $('#mainCol a.opnOlay').click(function(e) {
                e.preventDefault();
                var href2BOpen = $(this).attr('href'),
				popUpW = 430,
				popUpH = 390,
				source = 'editBlogEntry';

                view.loadOverlay(source, href2BOpen, popUpW, popUpH);
                view.loadTinyEditorForBlog();
            });
        },

        // Load tiny editor for askexpert since it is called through ajax
        loadTinyEditor: function loadTinyEditor() {
            // indexer to only try 5 times
            if ($(".content").length == 0 && view.indexer < 5) {
                view.indexer++;
                setTimeout(function() {
                    loadTinyEditor();
                }, 1000);
            }
            else {
                view.loadTiny();
                view.indexer = 0;
            }
        },

        loadTinyEditorForBlog: function loadTinyEditorForBlog() {
            // indexer to only try 5 times
            if ($(".blogEntryContent").length == 0 && view.indexer < 5) {
                view.indexer++;
                setTimeout(function() {
                    loadTinyEditorForBlog();
                }, 1000);
            }
            else {
                view.loadTiny();
                view.indexer = 0;
            }
        },

        openAskExpert: function openAskExpert() {
            $('#askExpert').click(function(e) {
                e.preventDefault();
                var href2BOpen = $(this).attr('href'),
					popUpW = 450,
					popUpH = 400,
					source = 'askQuestion';

                view.loadOverlay(source, href2BOpen, popUpW, popUpH);
                view.loadTinyEditor();
            });
        },

        /**
        * If password input is empty, disable the new password input, otherwise enable
        */
        passwordCheck: function passwordCheck() {
            var newPws = $('#fullWidthCol .newPw');

            if ($('#oldPw input[type="password"]').val() === '') {
                newPws.attr('disabled', 'disabled');
            } else {
                newPws.removeAttr("disabled");
            }
        },

        doPwCheck: function doPwCheck() {
            $('#oldPw input[type="password"]').keyup(function() {
                view.passwordCheck();
            });
        }
    };

    model = {
        /**
        * Handles the response from jQuery ajax object
        * @param {Array} data	JSON data loaded from server.
        * @param {String} queueId	ID of current queue, could also be bool False it no que is used.
        */
        handleResponse: function(data, queueId) {
            if (data.d.ResponseStatus !== 200) {
                this.handleError(data.d.ResponseMessage);
                return false;
            }

            if (typeof queueId === 'function') {
                queueId(data.d.ResponseData[0]);
                //this.que.tmpCallback(data.d.ResponseData[0].Value);
            } else {
                var i = 0,
                    l = data.d.ResponseData.length,
					x;

                for (x in this.queue[queueId]) {
                    if (this.queue[queueId][x]) {
                        for (i = 0; i < l; i += 1) {
                            if (data.d.ResponseData[i].CommandName.toLowerCase() === x.toLowerCase()) {
                                this.queue[queueId][x].callback(data.d.ResponseData[i]);
                            }
                        }
                    }
                }

                model.resetQueue(queueId);
            }
        },
        /**
        * Holds queue objects. Each queue should have a unique name and contains properties with correspondant names of the name of webservice to be called
        */
        queue: {
            queue1: {
                GetTwitter: false,
                GetFriends: false
            },

            queue2: {
                AddAccount: false,
                AddSubscriber: false
            }
        },
        /**
        * Add new Queue Item to que based on queId. If que is full. Trigger the JSON request. ie. 
        * USAGE: model.addToQueue('queue1', ['AddStuff', { name: 'stuff' }], view.removeStuff)
        * 
        * @param {String} queueId	ID of current queue, 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
        */
        addToQueue: function(queueId, payload, callback) {
            var queuePayload,
				i,
				queueObj = { Name: payload[0], Params: [] };

            for (i in payload[1]) {
                queueObj.Params.push({ Name: i, Value: payload[1][i] });
            }

            if (!queueId) {
                this.queue.tmpCallback = callback;

                this.addToAjaxQueue({ request: { Commands: [queueObj]} }, callback);
                return false;
            } else if (this.queue[queId][payload[0]]) {
                return false;
            }

            if (!queueId in this.queue || !payload[0] in this.queue[queueId]) {
                this.handleError('No queueId with the name ' + queueId + ' or the queueItem ' + payload[0] + ' is not in the queue ' + queueId);
            }

            this.queue[queueId][payload[0]] = {};
            this.queue[queueId][payload[0]].payload = queueObj;
            this.queue[queueId][payload[0]].callback = callback;

            if (this.isQueueReady(queueId)) {
                queuePayload = this.getQueuePayload(queueId);
                this.addToAjaxQueue(queuePayload, queueId);
            }
        },
        /**
        * Check if queue is ready to be triggered.
        * @param {String} queueId	ID of current queue.
        * @return {Boolean}	Returns true if queue is ready.
        */
        isQueueReady: function(queueId) {
            var isReady = true,
				i;

            for (i in this.queue[queueId]) {
                if (!this.queue[queueId][i]) {
                    isReady = false;
                    break;
                }
            }

            return isReady;
        },
        /**
        * Get current queues payload as and Array.
        * @param {String} queueId	ID of current queue.
        * @return {Array}	Payload array with main webservice methods as first argument.
        */
        getQueuePayload: function(queueId) {
            var payloadArray = [],
				i;

            for (i in this.queue[queueId]) {
                if (this.queue[queueId][i]) {
                    payloadArray.push(this.queue[queueId][i].payload);
                }
            }

            return { request: { Commands: payloadArray} };
        },
        /**
        * Resets the queue of current queueId.
        * @param {String} queueId	ID of current queue.
        */
        resetQueue: function(queueId) {
            var i;
            for (i in this.queue[queueId]) {
                if (this.queue[queueId][i]) {
                    this.queue[queueId][i] = false;
                }
            }
        },
        /**
        * Setup ajax properties for new ajax request.
        * @param {Array} payload	Array to be posted to webservice.
        * @param {String} queueId	ID of current queue.
        */
        addToAjaxQueue: function(payload, queueId) {
            var ajaxOptions = {
                url: '/Services/ClientDataTransferService.asmx/GetData',
                type: 'post',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify(payload),
                callback: queueId,
                success: function(data) {
                    var arg = [data, this.callback];
                    $.model.handleResponse.apply(model, arg);
                },
                error: model.handleError
            };

            this.doJsonPost(ajaxOptions);
        },

        /**
        * Triggers jQuery's ajax method and triggers handleResponse method passing loaded data and queId.
        * Uses jQuery queue method to prevent ajax request from being invoked in proper order.
        * @param {Object} ajaxOptions Object containing properties of ajax request.
        */
        doJsonPost: function(ajaxOptions) {
            $($.model).dequeue('ajaxRequests');
            $($.model).queue('ajaxRequests', function() {
                var onSuccess = ajaxOptions.success;
                ajaxOptions.success = function() {
                    if (onSuccess) {
                        onSuccess.apply(this, arguments);
                    }
                    $($.model).dequeue('ajaxRequests');
                };
                $.ajax(ajaxOptions);
            });
            $($.model).dequeue('ajaxRequests');
        },
        /**
        * Throws error from jQuery ajax method.
        */
        handleError: function(err) {
            throw new Error(err);
        }
    };

    $.extend({ view: view });
    $.extend({ model: model });

    $(document).ready(function() {
        $.runInit(view);
    });

} ());
