﻿var widgetConfigOptions = {
    enableShowHide: true,
    showHideVisibleImageUrl: '/images/arrow_grey_down.png',
    showHideHiddenImageUrl: '/images/arrow_grey_right.png',
    ajaxControllerUrl: '/home/AjaxController.aspx',
    ajaxLoaderImageUrl: '/images/ajaxLoader.gif',
    layoutController: 'LayoutProcessor'
};

// We need to be quite precise with "#content div.widgetRow li." to prevent naming
// collisions with Widget Library widgets.
var tknWidgetSelectorFilter = '#content div.widgetRow li.';

var listenObj = new Object();

function hookUpWidgets() {
    $("#header").css("z-index", 60);
    /* Yea yea, it shouldn't be necessary to SET css properties by js, but it is - thanks IE 7 */
    if (widgetConfigOptions.enableShowHide) {
        createShowHideButton();
        minMaxPanels('#content .showHideArrow');
    }
    initialiseEditButton('#content .edit', "noCallBackFunction");
    $(".widgetRow .col").sortable({
        connectWith: [".widgetRow .col"],
        handle: "h2 span",
        placeholder: "placeholder",
        tolerance: "intersect",
        revert: "true",
        start: function(e, ui) {
            widgetMove(ui.helper.attr("class"), "Start");
            ui.helper.addClass("small");
            ui.helper.css("z-index", 99);
            $("#header").css("z-index", 0);
            $(".placeholder").css("padding-top", ui.helper.height());
            $(".placeholder").css("margin-bottom", "20px");

        },
        beforeStop: function(e, ui) {
            ui.helper.removeClass("small");
            ui.helper.addClass("droppedElement");
            widgetMove(ui.helper.attr("class"), "Stop");
        },
        stop: function() {
            saveWidgetLayoutState($(".droppedElement").parent());
            $(".droppedElement").removeClass("droppedElement");
            generateHeights(100, ".widgetRow", ".col", ".widget", 20);
        }
    });

    if (widgetConfigOptions.enableShowHide) {
        //showHideWidget();
    }

    generateHeights(100, ".widgetRow", ".col", ".widget", 20);

    $('li.showConfiguration').each(
    	function() {
    	    ajaxLoadEditPanel($(this), 'noCallBackFunction');
    	    $(this).removeClass('showConfiguration');
    	    var targetOffset = $(this).offset().top;
    	    $('html,body').animate({ scrollTop: targetOffset }, 1000);

    	    return false;
    	});
}

String.prototype.normalize_space = function() {
    // Replace repeated spaces, newlines and tabs with a single space
    return this.replace(/^\s*|\s(?=\s)|\s*$/g, "");
}


/*  functions for individual widgets  
This is only working at present for my experience on the profile page which has rich text areas
in the edit section, which need reset after being moved
*/
function widgetMove(className, functionName) {
    widgetName = className.split(" ");
    if (eval('typeof(' + widgetName[1] + functionName + ')') == 'function') {
        eval(widgetName[1] + functionName + "()");
    }
}


/* Initialise The Edit Button - adds the JS onclick function to the required edit button */
function initialiseEditButton(buttonToInitialise, callback) {
    //Initial hide of editPanels on page load
    $(buttonToInitialise).parents(".widget").children('div.editPanel').hide();

    //show and hide of 2 panels
    $(buttonToInitialise).click(function() {
        var widget = $(this).parents(".widget");
        var configPanel = widget.children('div.editPanel');
        if (configPanel.length == 0) // then ajax it in baby!
        {
            ajaxLoadEditPanel(widget, callback);
        }
        else {
            editPanelsShowHide(widget);
            editButtonCallback(callback)
        }

        return false;
    });
}

function editButtonCallback(callback) {
    if (callback != 'noCallBackFunction') {
        try {
            var functionList = callback.split(",");
            for (i = 0; i < functionList.length; i++) {
                eval(functionList[i].trim());
            }
        } catch (er) { }
    }
}

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}

/*  Widget edit panels such as My ELearning have a delete only option for list items.
This allows them to give the impression of having deleted options without talking to the backend */

function removeCheckBoxes(widgetClass) {
    $(widgetClass + " .editPanel input:checkbox").addClass("hide");
    $(widgetClass + " .editPanel ul").addClass("removeFromHomePage");
}

function showAllCheckBoxes(widgetClass) {
    $(widgetClass + " .editPanel .removeFromHomePage li").removeClass("hide");
}


function ajaxLoadEditPanel(widget, callback) {
    var widgetId = widget.attr('class').split(' ')[1];
    var url = widgetConfigOptions.ajaxControllerUrl + '?w=' + widgetId + '&c=configOnly';
    //if(d1 == null)
    //d1 = new Date();
    $.ajax({
        url: url,
        cache: false,
        beforeSend: function() {
            $(tknWidgetSelectorFilter + widgetId + '').children("h2").append("<img src='" + widgetConfigOptions.ajaxLoaderImageUrl + "' alt='loading... ' id='editLoader' />")
        },
        success: function(html) {
            var jsHtml = $(html);
            var link = jsHtml.find('#sslRedirectUrl');
            if (link.length > 0) {
                window.location = link.text();
            }
            else {
                processEditResponse(jsHtml, widgetId, true);

                // Show config
                editPanelsShowHide(widget);

                $('#editLoader').remove();
            }
        },
        complete: function() {
            editButtonCallback(callback);
        }
    });
}

function processEditResponse(html, widgetId, hideOnInsert) {
    // Inject config into page 	
    //var d1 = new Date();
    //var jqHtml = $(html);

    var ajaxConfigPanel = html.find('div.editPanel');
    $('.' + widgetId + ' div.editPanel').remove();

    if (hideOnInsert) {
        ajaxConfigPanel.hide();
    }

    //$('.' + widgetId + ' div.boxContent').before(ajaxConfigPanel.parent().html());
    $('.' + widgetId + ' div.boxContent').before(ajaxConfigPanel);
    $('.' + widgetId + ' div.editPanel').append(html.find('input#__VIEWSTATE'));

    // Remove onclick events rendered by ASP.NET!
    $('.' + widgetId + ' input.button').removeAttr('onclick');

    // Init JS for config
    if (eval('typeof(' + widgetId + 'InitConfig)') == 'function') {
        eval(widgetId + 'InitConfig();');
    }
    var d2 = new Date();
    //if(d1 != null)
    //alert("start: " +  d1.getMinutes() + ":" + d1.getSeconds() + " end: " + d2.getMinutes() + ":" + d2.getSeconds() + " process");
}

/*  SHOW  /  HIDE EDIT PANEL */
function editPanelsShowHide(parent) {
    var state = parent.children('.showHideArrow').attr('alt');
    if (state == 'open') {
        parent.children('.editPanel').slideToggle("slow");
    }
    else {
        parent.children('.boxContent').slideToggle("slow");
        parent.children('.editPanel').slideToggle("slow");
    }
}

function createShowHideButton() {
    $(tknWidgetSelectorFilter + 'widget').each(function() {
        if ($(this).hasClass('collapsed')) {
            $(this).children('h2').append("<img src='" + widgetConfigOptions.showHideVisibleImageUrl + "' alt='close' class='showHideArrow' />");
        }
        else {
            $(this).children('h2').append("<img src='" + widgetConfigOptions.showHideHiddenImageUrl + "' alt='open' class='showHideArrow' />");
        }

        applyMinMaxPanelState($(this).children('h2').children('img.showHideArrow'), false);
    });
}

// MINIMIZE OR MAXIMISE WIDGET CONTENT
function minMaxPanels(panels) {
    $(panels).unbind("click");
    //Show Hide of the content
    $(panels).click(
	function() {
	    applyMinMaxPanelState($(this), true);
	});
}

function applyMinMaxPanelState(arrowImg, saveState) {
    var widget = arrowImg.parents(".widget");

    var editPanel = widget.children('.editPanel');
    editPanel.hide();

    var url = '';
    var widgetId = widget.attr('class').split(' ')[1];
    var state = arrowImg.attr('alt');

    if (widget.parents('.widgetLayout').length > 0) {
        var widgetLayout = widget.parents('.widgetLayout')[0].id;

        if (state == "close") {
            arrowImg.attr({
                src: "/images/arrow_grey_right.png",
                alt: "open"
            });

            if (saveState) {
                widget.children('.boxContent').slideUp("slow");
            }
            else {
                widget.children('.boxContent').hide();
            }

            url = widgetConfigOptions.ajaxControllerUrl + '?p=' + widgetConfigOptions.layoutController + '&a=saveCollapse&l=' + widgetLayout + '&layout=' + widgetId;
        }
        else {
            if (saveState) {
                widget.children('.boxContent').slideDown("slow");
            }
            else {
                widget.children('.boxContent').show();
            }

            arrowImg.attr({
                src: "/images/arrow_grey_down.png",
                alt: "close"
            });

            url = widgetConfigOptions.ajaxControllerUrl + '?p=' + widgetConfigOptions.layoutController + '&a=saveExpand&l=' + widgetLayout + '&layout=' + widgetId;
        }

        // Save State
        if (saveState) {
            $.ajax({
                url: url,
                cache: false,
                success: function(html) {
                    //alert("'" + childrenList + "' are now in " + getWidgetDropLocation(holder));
                }
            });
        }
    }
}

//SHOW HIDE #CONTENT WIDGET
function showHideWidget() {
    if ($('#mainTabs').hasClass('collapsed')) {
        $('#searchMain').after('<img src="/images/widget_show.png" alt="show content" class="showHideContent"/>');

        $('.showHideContent').animate({ top: '32em' });
        $('.editWidgets').animate({ top: '32em' });
        $('#mainTabs').hide();
        $('#content').hide();
    }
    else {
        $('#searchMain').after('<img src="/images/widget_hide.png" alt="hide content" class="showHideContent"/>');
    }

    $('img.showHideContent').unbind("click");
    $('img.showHideContent').click(function() {
        var state = $(this).attr('alt');
        var url = '';

        if (state == "hide content") {
            $('#content').slideUp('slow');

            $(this).attr({
                src: "/images/widget_show.png",
                alt: "show content"
            });

            $(this).animate({ top: '32em' });
            $('.editWidgets').animate({ top: '32em' });
            $('#mainTabs').hide('slow');
            url = widgetConfigOptions.ajaxControllerUrl + '?p=' + widgetConfigOptions.layoutController + '&a=saveHide';
        }
        else {
            $('#content').slideDown('slow');

            $(this).attr({
                src: "/images/widget_hide.png",
                alt: "hide content"
            });

            $(this).animate({ top: '36em' });
            $('.editWidgets').animate({ top: '36em' });
            $('#mainTabs').show('slow');
            url = widgetConfigOptions.ajaxControllerUrl + '?p=' + widgetConfigOptions.layoutController + '&a=saveShow';
        }

        // Save State
        $.ajax({
            url: url,
            cache: false
        });
    });
}

function saveWidgetLayoutState(holder) {
    var childrenList = '';
    var widgetLayout = holder.parents('.widgetLayout')[0].id;

    holder.children('.widget').each(function(i) {
        if (childrenList.length > 0)
            childrenList = childrenList + "|";

        childrenList = childrenList + $(this).attr('class').split(' ')[1];
    });

    var url = widgetConfigOptions.ajaxControllerUrl + '?p=' + widgetConfigOptions.layoutController + '&a=saveLayout&l=' + widgetLayout + '&layout=' + getWidgetDropLocation(holder) + ',' + childrenList;

    $.ajax({
        url: url,
        cache: false,
        success: function(html) {
            //alert("'" + childrenList + "' are now in " + getWidgetDropLocation(holder));
        }
    });
}

function getWidgetDropLocation(holder) {
    if (holder == null) {
        return '';
    }

    if (holder.parent().attr('class') != 'widgetLayout') {
        return getWidgetDropLocation(holder.parent()) + '|' + holder.parent().children("ul").index(holder);
    }
    else {
        return holder.parent().children("ul").index(holder);
    }
}

/* Sets a minimum height on ALL columns within a container based on the heights of the elements within the column
*/
function generateHeights(min, container, column, elem, offset) {
    $(container).each(function() {
        var current = 0;
        var setSize = min;
        var currentContainerList = $(this).children(column);

        $(this).children(column).each(function() {// for each column within a given container
            $(this).children(elem).each(function() {
                // for each element within the given column

                current = current + Number($(this).height()) + Number(offset); // add the elements height to current

            });
            if (Number(current) > Number(setSize)) {
                setSize = current;
            }
            current = 0;
        });

        setHeights(currentContainerList, setSize);
    });
}

function setHeights(currentContainerList, size) {
    $(currentContainerList).each(function() {

        $(this).css("min-height", size + "px");
        if ((jQuery.browser.msie) && (Number(jQuery.browser.version) < 7)) {
            $("#content").height(size + "px");
        }
    });
}

/* Listener Functionality 
uses an object (listenObj) which widgets can register with
the widget registers with the object, passing a uid and a function to be called
registerListenEvent(uid, function);
events such as onclick, on change etc can then call the object with a uid and run all of the functions 
associated with that uid in an abstracted manner.
This means that an event can say "I have happened" without being aware of which widgets need to know.
*/
function registerListenEvent(id, func) {
    if (typeof listenObj[id] != 'function') {
        listenObj[id] = func;
    }
    else {
        var oldListenObj = listenObj[id];
        listenObj[id] = function() {
            oldListenObj();
            func();
        }
    }
}

function callListenEvent(id) {
    listenObj[id]();
}

function initialiseRemoveButton(widgetId) {
    $(tknWidgetSelectorFilter + widgetId + ' .editPanel input.removeButton').click(function() {
        var url = widgetConfigOptions.ajaxControllerUrl + '?w=' + widgetId + '&c=contentOnly&a=remove';
        var inputs = [];

        $.ajax({
            type: 'POST',
            cache: false,
            data: inputs.join('&'),
            url: url,
            success: function(html) {
                $(tknWidgetSelectorFilter + widgetId).remove();
            }
        });
    });
}

function initialiseSaveButton(widgetId) {

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel input.saveButton').click(function() {
        sendEditForm(widgetId, true);
    });
}

//function initialiseSaveButton(widgetId, reloadForm)
//{
//    $(tknWidgetSelectorFilter + widgetId + ' .editPanel input.saveButton').click(function()
//    {
//	    sendEditForm(widgetId, reloadForm);
//	});
//}

function initialiseCancelButton(widgetId) {
    $(tknWidgetSelectorFilter + widgetId + ' .editPanel input.cancelButton').click(function() {
        editPanelsShowHide($(tknWidgetSelectorFilter + widgetId));
        location.reload();
    });
}
var firstTimeLoaded = false;
function GetContentOnly(widgetId) {
    var url = widgetConfigOptions.ajaxControllerUrl + '?w=' + widgetId + '&c=contentOnly';
    $.ajax({
        type: 'POST',
        cache: false,
        url: url,
        beforeSend: function () {
            $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').show();
            $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').append("<img src='" + widgetConfigOptions.ajaxLoaderImageUrl + "' alt='loading... ' id='innerEditLoader' />");            
        },
        success: function (html) {

            // check if successful save
            var jqHtml = $(html);

            var ajaxContentPanel = jqHtml.find('div.boxContent');
            var ajaxEditPanel = jqHtml.find('div.editPanel');

            //processEditResponse(jqHtml, widgetId, false);
            //editPanelsShowHide($(tknWidgetSelectorFilter + widgetId + ''));

            if (ajaxEditPanel.length > 0) // Saved Failed
            {
                processEditResponse(html, widgetId, false);
            }
            else // Successful
            {
                $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').empty();
                $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').replaceWith(ajaxContentPanel.hide());
                $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').show();
            }
        }

    });
}

var d1;
function sendEditForm(widgetId, reloadForm) {

    //d1 = new Date();
    // Post form
    var url = widgetConfigOptions.ajaxControllerUrl + '?w=' + widgetId + '&c=contentOnly&a=save';

    // :input is a macro that grabs all input types, select boxes
    // textarea, etc.  Then I'm using the context of the form from 
    // the initial '#contactForm' to narrow down our selector
    var inputs = [];
    $(tknWidgetSelectorFilter + widgetId + ' .editPanel :checkbox').each(function() {
        if ($(this).attr('checked'))
            inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).attr('checked')));
    });

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel :radio').each(function() {
        if ($(this).attr('checked'))
            inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).attr('value')));
    });

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel :text').each(function() {
        inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).val()));
    });

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel textarea').each(function() {
        // Ignore TinyMCE enabled textareas
        if ($(this).attr('class') != 'richText') {
            inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).val()));
        }
    });

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel select').each(function() {
        inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).val()));
    });

    $(tknWidgetSelectorFilter + widgetId + ' .editPanel textarea:hidden, ' + tknWidgetSelectorFilter + widgetId + ' .editPanel input[@type=text]:hidden').each(function() {
        // Use TinyMCE API for TinyMCE enabled textareas (which are sent in hidden form field by TinyMCE)
        if ($(this).attr('class') == 'richText') {
            var value = tinyMCE.get($(this).attr('id')).getContent();
            inputs.push($(this).attr('name') + '=' + encodeURIComponent(value));
        }
        else {
            inputs.push($(this).attr('name') + '=' + encodeURIComponent($(this).val()));
        }
    });

    $.ajax({
        type: 'POST',
        cache: false,
        data: inputs.join('&'),
        url: url,
        success: function (html) {

            // check if successful save
            var jqHtml = $(html);

            var ajaxContentPanel = jqHtml.find('div.boxContent');
            var ajaxEditPanel = jqHtml.find('div.editPanel');

            //processEditResponse(jqHtml, widgetId, false);
            //editPanelsShowHide($(tknWidgetSelectorFilter + widgetId + ''));

            if (ajaxEditPanel.length > 0) // Saved Failed
            {
                processEditResponse(html, widgetId, false);
            }
            else // Successful
            {
                $(tknWidgetSelectorFilter + widgetId + ' div.boxContent').replaceWith(ajaxContentPanel.hide());
                if (reloadForm) {
                    var url = widgetConfigOptions.ajaxControllerUrl + '?w=' + widgetId + '&c=configOnly';

                    $.ajax({
                        url: url,
                        cache: false,
                        beforeSend: function () {
                            $(tknWidgetSelectorFilter + widgetId + '').children(".edit").before("<img src='" + widgetConfigOptions.ajaxLoaderImageUrl + "' alt='loading... ' id='editLoader' />")
                        },
                        success: function (html) {
                            var jqHtml1 = $(html); 
                            processEditResponse(jqHtml1, widgetId, false); 
                            editPanelsShowHide($(tknWidgetSelectorFilter + widgetId + '')); 
                            $('#editLoader').remove();
                        }
                    });
                }
                else {
                    editPanelsShowHide($(tknWidgetSelectorFilter + widgetId + ''));
                }

                if (eval('typeof(' + widgetId + 'InitConfig)') == 'function') {
                    eval(widgetId + 'InitContent();');
                }
            }
        }

    });

    //var d2 = new Date();
    //alert("start: " +  d1.getMinutes() + ":" + d1.getSeconds() + " end: " + d2.getMinutes() + ":" + d2.getSeconds() + " save");

}

function hookUpSearchProvider() {

    //$('.col .SearchProviderWidget .boxInner a').click(function() {
        //var hrefValue = $('this').parent().children('hiddenAddToBrowser').attr('value');
        //window.external.AddSearchProvider(this.href); return false;
        //window.external.AddSearchProvider(hrefValue); return false;

    //});

}

//----- Images Widget Functionality -----//
jQuery.hookUpImageWidget = function() {
    $(document).ready(function() {
        var IMAGE_TRANSITION_TIME = 5000;
        var AUTO_TRANSITION_SPEED = 500;
        var MANUAL_TRANSITION_SPEED = 150;

        $('.ImageWidget').each(function() {
            var currentTransitionSpeed = AUTO_TRANSITION_SPEED;
            var imageChangeTimer;
            var currentImage;
            var transitionInProgress = false;

            var totalImages = $(this).find('div.boxContent div.boxInner > ul > li').length;

            if (totalImages > 1) {
                currentImage = $(this).find('div.boxContent div.boxInner > ul > li:visible');

                imageChangeTimer = setTimeout(function() {
                    changeImage(true);
                }, IMAGE_TRANSITION_TIME);

                $(this).find('.PagingLinks a').click(function(e) {
                    e.preventDefault();

                    clearTimeout(imageChangeTimer);
                    currentTransitionSpeed = MANUAL_TRANSITION_SPEED;

                    if ($(this).parent().hasClass('Previous')) {
                        changeImage(false);
                    }
                    else {
                        changeImage(true);
                    }
                });
            }

            function changeImage(isForward) {
                if (!transitionInProgress) {
                    transitionInProgress = true;

                    var nextImage = isForward ? currentImage.next() : currentImage.prev();

                    if (nextImage.length == 0) {
                        nextImage = isForward ? currentImage.parent().find('li:first') : currentImage.parent().find('li:last');
                    }

                    var nextElementHeight = nextImage.height();
                    var currentElementHeight = currentImage.height();

                    if (nextElementHeight > currentElementHeight) {
                        //currentImage.parent().parent().height(nextElementHeight);
                    }

                    currentImage.find('a img').fadeOut(currentTransitionSpeed, function() {
                        currentImage.hide();
                        nextImage.find('a img').hide();
                        nextImage.show();

                        nextImage.find('a img').fadeIn(currentTransitionSpeed, function() {
                            //currentImage.parent().parent().height(nextElementHeight);

                            currentImage = nextImage;

                            transitionInProgress = false;
                            currentTransitionSpeed = AUTO_TRANSITION_SPEED;

                            imageChangeTimer = setTimeout(function() {
                                changeImage(true);
                            }, IMAGE_TRANSITION_TIME);
                        });
                    });
                }
            }
        });

    });
};

