﻿(function ($) {
    $.fn.pseTab = function (options) {
        var settings = {
            'wizard': false,
            'edit': true
        };
        return this.each(function () {
            if (options) {
                $.extend(settings, options);
            }
            var target = $(this);
            /* Add the ui-tabs-hide to all tabs to prevent flash of unstyled content */
            var panels = target.children('div');
            panels.addClass('ui-tabs-hide');
            panels.height(0);
            if (!settings.wizard) {
                /* Non-wizard mode */
                target.tabs({
                    /* Get the selected tab index from the cookie */
                    selected: getTabIndex(target, settings.wizard),
                    /* Install a handler for the select event and use it for:
                    1) Store the index in the cookie 
                    */
                    select: function (event, ui) {
                        setTabIndex(target, ui.index);
                        return true;
                    },
                    /* Install a handler for the show event and propagate it to the panel
                    such that it may resize if needed, attempt to set the focus on the
                    first input element of the panel */
                    show: function (event, ui) {
                        var panel = $(ui.panel);
                        activatePanel(panel, settings.edit);
                    }
                });
            }
            else {
                /* Wizard mode */
                target.tabs({
                    /* Get the selected tab index from the cookie */
                    selected: getTabIndex(target, settings.wizard),
                    /* Install a handler for the select event and use it for:
                    1) Prevent non-sequential forward navigation
                    2) Validate the fields on the current tab if moving forward
                    3) Store the index in the cookie 
                    */
                    select: function (event, ui) {
                        var curIndex = $(this).tabs('option', 'selected');
                        if (ui.index > curIndex && 1 < ui.index - curIndex) {
                            /* In wizard mode, user must navigate from one tab to the next */
                            return false;
                        }
                        if (ui.index > curIndex) {
                            /* Validate the fields on the current tab */
                            var form = $(this).parents('form:first');
                            var validator = form.validate();
                            var isValid = true;
                            var panel = $(panels[curIndex]).find('input[name], select[name]').not(':hidden').each(function () {
                                if (!validator.check(this)) {
                                    validator.element(this);
                                    isValid = false;
                                }
                            });
                            if (!isValid) {
                                var container = form.find('[data-valmsg-summary=true]'), list = container.find("ul");
                                if (list && list.length && validator.errorList.length) {
                                    list.empty();
                                    $.each(validator.errorList, function () {
                                        $("<li />").html(this.message).appendTo(list);
                                    });
                                    container.addClass('validation-summary-errors').removeClass('validation-summary-valid');
                                }
                                return false;
                            }
                        }
                        setTabIndex(target, ui.index);
                        return true;
                    },
                    /* Install a handler for the show event and propagate it to the panel
                    such that it may resize if needed */
                    show: function (event, ui) {
                        var panel = $(ui.panel);
                        activatePanel(panel, settings.edit);
                    }
                });
                /* Set up handlers on the next and previous buttons of the wizard */
                $('.wizard-next-button', target).bind('keydown click', function (event) {
                    if ((event.type == 'keydown' && !event.shiftkey && event.keyCode == 9) || event.type == 'click') {
                        target.tabs('select', target.tabs('option', 'selected') + 1);
                    }
                });
                $('.wizard-prev-button', target).bind('keydown click', function (event) {
                    if ((event.type == 'keydown' && event.shiftkey && event.keyCode == 9) || event.type == 'click') {
                        target.tabs('select', target.tabs('option', 'selected') - 1);
                    }
                });
                /* Set up handler for the save button */
                $('.wizard-save-button', target).click(function () {
                    var form = $(this).parents('form:first');
                    var validator = form.validate();
                    var isValid = true;
                    var panel = $(panels).find('input[name], select[name]').not(':hidden').each(function () {
                        if (!validator.check(this)) {
                            validator.element(this);
                            isValid = false;
                        }
                    });
                    if (!isValid) {
                        var container = form.find('[data-valmsg-summary=true]'), list = container.find("ul");
                        if (list && list.length && validator.errorList.length) {
                            list.empty();
                            $.each(validator.errorList, function () {
                                $("<li />").html(this.message).appendTo(list);
                            });
                            container.addClass('validation-summary-errors').removeClass('validation-summary-valid');
                        }
                        return false;
                    }
                    form.submit();
                });
            }
            /* Tab has been created, size the panels to take all the space available */
            var header = target.children('ul');
            panels.height(target.height() - header.outerHeight() - panels.outerHeight());
            /* Trigger the PSTabShow event on the first panel selected */
            $(panels[target.tabs('option', 'selected')]).trigger('PSTabShow');
            /* Disable UI components if edit mode is disabled */
            if (!settings.edit) {
                panels.find(':input:not(#FileUpload):not(#files)').attr('disabled', true).addClass('ui-state-disabled');
            }
        });
    };

    $.fn.pseDialog = function (options) {
        var settings = {
            'buttons': null,
            'modal': true,
            'resizable': true
        };
        return this.each(function () {
            if (options) {
                $.extend(settings, options);
            }
            var target = $(this);
            var height = target.height();
            var width = target.width();
            if (null == settings.buttons) {
                var form = $('form:first', target);
                if (form.length) {
                    $.extend(settings, { 'buttons': {
                        'OK': function () { form.submit(); },
                        'Dismiss': function () { target.dialog('close'); }
                    }
                    });
                }
                else {
                    $.extend(settings, { 'buttons': {
                        'Dismiss': function () { target.dialog('close'); }
                    }
                    });
                }
            }
            target.dialog({
                show: 'highlight',
                hide: 'explode',
                height: height,
                width: width,
                modal: settings.modal,
                resizable: settings.resizable,
                buttons: settings.buttons,
                close: function (event, ui) {
                    target.trigger('PSDialogClose');
                    $(this).remove();
                },
                open: function (event, ui) {
                    target.trigger('PSDialogOpen');
                }
            });

        });
    };
})(jQuery);

function getTabIndex(target, wizardMode) {
    if (!wizardMode) {
        var i, x, y, cookies = document.cookie.split(";");
        var tabName = target.attr('id') + '-tabIndex';
        for (i = 0; i < cookies.length; i++) {
            x = cookies[i].substr(0, cookies[i].indexOf("="));
            y = cookies[i].substr(cookies[i].indexOf("=") + 1);
            x = x.replace(/^\s+|\s+$/g, "");
            if (x == tabName) {
                return y;
            }
        }
        return 0;
    }
    else {
        return 0;
    }
}

function setTabIndex(target, value) {
    var date = new Date();
    date.setTime(date.getTime() + (10 * 60 * 1000)); //Expire this cookie 10 minutes after it is set
    var cookieValue = value + "; expires=" + date.toUTCString();
    document.cookie = target.attr('id') + '-tabIndex' + "=" + cookieValue;
}

function activatePanel(panel, editMode) {
    if (panel.is(':visible')) {
        if (editMode) {
            var firstInput = panel.find(':input:visible:enabled').first();
            if (firstInput) {
                firstInput.focus();
                firstInput.effect('highlight', null, 1000);
            }
        }
        panel.trigger('PSTabShow');
    }
}

function displayErrorSummary() {
    var summary = $('.validation-summary-errors');
    if (summary.length) {
        var parentForm = summary.parent();
        summary.dialog({
            position: [50, 50],
            close: function (event, ui) {
                $(this).dialog('destroy');
                $(this).addClass('validation-summary-valid').removeClass('validation-summary-errors');
                if (parentForm.length) {
                    $(this).appendTo(parentForm);
                }
            }
        });
    }
}

function adjustPercentages(controlArray, current) {
    /* Calculate the total, delta and the start index where adjustments
    should begin.  The array of controls is examined as a circular buffer
    adjusting the next control when necessary */
    var total = new Number(0);
    var start = new Number(0);
    for (target in controlArray) {
        var controlObject = controlArray[target];
        total += (null == controlObject) ? 0 : new Number(controlObject.value);
        start = (null != controlObject && current == controlObject) ? new Number(target) + 1 : start;
    }
    var delta = 100 - total;
    if (0 == delta) {
        return;
    }
    /* There is a delta, an adjustment is needed */
    for (index = 0; index < controlArray.length; index++) {
        controlObject = controlArray[start];
        if (null != controlObject) {
            controlValue = new Number(controlObject.value);
            if (0 > delta) {
                /* The current total is over 100 */
                if (controlValue > Math.abs(delta)) {
                    /* The current value is large enough to be reduced by the 
                    delta, percentages are now leveled */
                    controlObject.value = controlValue + delta;
                    break;
                }
                else {
                    /* The current value is not large enough to be reduced by
                    the delta, call the function again */
                    controlObject.value = 0;
                    return adjustPercentages(controlArray, controlObject);
                }
            }
            else {
                /* The current total is under 100, increased by required delta.
                percentages are now leveled */
                controlObject.value = controlValue + delta;
                break;
            }
        }
        start++;
        if (controlArray.length <= start) {
            /* Reached the end of the array, go to the first element */
            start = 0;
        }
    }
    return;
}
function drawChart(id) {
    var chartSection = $('#' + id);
    if (0 == chartSection.length) {
        return;
    }
    var chartTitle = chartSection.find('.ChartTitle').val();
    var chartType = chartSection.find('.ChartType').val();
    var chartWidth = chartSection.css('width');
    var chartHeight = chartSection.css('height');
    $.ajax({
        url: chartSection.find('.ChartURL').val(),
        dataType: 'JSON',
        data: { 'chartId': id },
        success: function (jsonData) {
            if (null == jsonData) {
                return;
            }
            var data = new google.visualization.DataTable(jsonData);
            var view = new google.visualization.DataView(data);
            var options;
            var chart = null;
            switch (chartType) {
                case 'Pie':
                    chart = new google.visualization.PieChart(chartSection.get(0));
                    break;
                case 'Bar':
                    chart = new google.visualization.BarChart(chartSection.get(0));
                    break;
                case 'Line':
                    chart = new google.visualization.LineChart(chartSection.get(0));
                    break;
                case 'Organization':
                    chart = new google.visualization.OrgChart(chartSection.get(0));
                    options = { allowCollapse: true, allowHtml: true };
                    break;
            }
            if (null != chart) {
                google.visualization.events.addListener(chart, 'ready', function () { chartSection.trigger('PSChartReady'); });
                chart.draw(data, $.extend(options, { title: chartTitle, width: chartWidth, height: chartHeight, legend: 'bottom', backgroundColor: { fill: 'none'} }));
                chartSection.data('DataView', view);
                chartSection.data('Chart', chart);
                google.visualization.events.addListener(chart, 'select', function () {
                    var selection = chart.getSelection();
                    if (null == selection || 0 == selection.length) {
                        chartSection.trigger('PSChartDeSelect');
                        return;
                    }
                    var row = 0;
                    var col = 0;
                    if (null != selection[0].row) {
                        row = selection[0].row;
                    }
                    if (null != selection[0].column) {
                        col = selection[0].column;
                    }
                    chartSection.trigger('PSChartSelect', data.getValue(row, col));
                });
            }
        }
    });
}

function displayMessagesDialog(data) {
    var messages = '';

    /* Must match the value of the PSConditionsLevels Enum */
    var PSConditionLevels_Error = 2;
    var PSConditionLevels_Warning = 1;

    for (var i = 0; i < data.details.length; ++i) {
        var iconClass = '';
        var msgClass = '';
        if (PSConditionLevels_Error == data.details[i].Item1) {
            msgClass = 'ui-state-error';
            iconClass = 'ui-icon ui-icon-cancel';
        }
        else if (PSConditionLevels_Warning == data.details[i].Item1) {
            msgClass = 'ui-state-highlight';
            iconClass = 'ui-icon ui-icon-alert';
        }
        else {
            iconClass = 'ui-icon ui-icon-info';
        }
        messages += '<div class="' + msgClass + '"><div class="' + iconClass + '" style="float: left;"></div>' + data.details[i].Item2 + '</div>';
    }
    var body = $('body');
    var detailsDlg = '\
<div id="change-state-details" class="ui-widget" style="height: ' + (body.height() / 2) + 'px; width: ' + (body.width() / 2) + 'px;">\
<div class="ui-state-error">' + data.header + '</div>\
<div class="ui-widget-content" style="margin: 1em;">' + messages + '</div>\
</div>\
';
    detailsDlg = $(detailsDlg);
    detailsDlg.appendTo(body);
    detailsDlg.pseDialog();
}

function pseInitialize() {
    /* Disable cache for ajax */
    $.ajaxSetup({ cache: false });
    /* Configure tool tips */
    $('input[title], select[title]').tipsy({ html: true, gravity: 'w', opacity: 0.9, fade: true });
    /* Configure links as buttons */
    $('a.pse-link-button').button();
    /* Handle styling for ui items using the ui-state-default class */
    $('.ui-state-default').hover(
            function () { $(this).addClass('ui-state-hover'); },
            function () { $(this).removeClass('ui-state-hover'); });
    /* Sizing */
    $('#pse-container').width($(window).width() * .95);
    $('#pse-container').height($(window).height() * .95);
    $(window).bind('resize', function () {
        $('#pse-container').width($(this).width() * .95);
        $('#pse-container').height($(this).height() * .95);
    }).resize();
    /* Error Displays */
    displayErrorSummary();
    $('#pse-content').live('DOMNodeInserted', function () {
        displayErrorSummary();
    });
    /* Disable validation for hidden elements */
    $.each($('form'), function (index, value) {
        var v = $(value).validate();
        v.settings.ignore = ':hidden';
    });
    /* Set up auto numeric types */
    $('.currency').autoNumeric({
        vMin: '0.00',
        vMax: '999.99',
        aSep: ''
    }).removeClass('currency');
    $('.decimal_2').autoNumeric({
        vMin: '0.00',
        vMax: '9999.99',
        aSep: ''
    }).removeClass('.decimal_2') ;
    $('.decimal_0').autoNumeric({
        vMin: '0',
        vMax: '9999',
        mDec: '0',
        aSep: ''
    }).removeClass('decimal_0');
}

function visualizationAPILoaded() {
    $('body').trigger('PSVisualizationAPILoaded');
}
function mapAPILoaded() {
    $('body').trigger('PSMapAPILoaded');
}
function loadMapAPI(f, a) {
    if ('undefined' == typeof google || 'undefined' == typeof google.visualization) {
        $('body').one('PSMapAPILoaded', function () { f(a); });
        google.load('maps', '3.5', { 'callback': mapAPILoaded, 'other_params': 'sensor=false' });
    }
    else {
        f(a);
    }
}
function loadVisualizationAPI(f, a) {
    if ('undefined' == typeof google || 'undefined' == typeof google.visualization) {
        $('body').one('PSVisualizationAPILoaded', function () { f(a); });
        google.load('visualization', '1.0', { 'callback': visualizationAPILoaded, 'packages': ['corechart', 'orgchart'] });
    }
    else {
        f(a);
    }
}
function pseLog(msg) {
    if (typeof console != 'undefined' && typeof console.log != 'undefined') {
        console.log(msg);
    }
}
jQuery.fn.center = function () {
    this.css('position', 'absolute');
    //var top = (($(window).outerHeight() - this.outerHeight()) / 2) + $(window).scrollTop();
    var top = (($(window).height() - this.outerHeight()) / 2);
    top = top > 1 ? top : 0;
    //var left = (($(window).outerWidth() - this.outerWidth()) / 2) + $(window).scrollLeft();
    var left = (($(window).width() - this.outerWidth()) / 2);
    left = left > 1 ? left : 0;
    this.css('top', top + 'px');
    this.css('left', left + 'px');
    return this;
}
function addContext(i, d, h) {
    var c = document.getElementById('pse-context-area');
    if ($('div', c).length) {
        $(c).accordion('destroy');
        $('.' + i, c).remove();
    }
    var n = $('<h3 class="' + i + '"><a href="#">' + h + '</a></h3><div class="pse-context-content ' + i + '">' + d + '</div>');
    $(c).append(n);
    accordion(c);
    $(c).accordion('activate', $('h3.' + i, c));
    $('div.pse-context-content', c).css({ 'padding-right': '1em', 'padding-left': '1em', 'font-size': '.9em' });
}
function addStatus(s) {
    var status = $('#pse-primary-status-area');
    status.html('<span style="margin-left: .5em; margin-top: .5em;">' + s + '</span>');
    status.addClass('ui-state-highlight');
    status.show('highlight', {}, 500, function () {
        setTimeout(function () {
            status.removeClass('ui-state-highlight').fadeOut();
        }, 2000);
    });
}

