﻿/*jslint white: true, browser: true, windows: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, immed: true */
/*globals $: false, jQuery: false */

// add exists() method to all jQuery objects.  Basically just syntactic sugar to help clarify intent
// Returns: true if object exists
// Usage: if( $("#myDynamicBox").exists() ) { //do something.. }
jQuery.fn.exists = function ()
{ 
    return jQuery(this).length > 0;
};
 

/* SUMMARY:
* Helper for constructing a request to a backend autosuggester 
* method, using POST and passing data.
* It bolds the matched part of each result in the array before returning the array.
* 
* PARAMS:
* request: the jQuery UI autocompleter 'request' object when setting the 'source:' property
* response: the jQuery UI autocompleter 'response' object when setting the 'source:' property
* url: the url of the server-side method to call
* limit: the maximum number of results to return
* returnInactiveAddresses: true if the query should include inactive addresses in the results
*
* RETURNS: nothing, it executes the response() function to give the list to the autocompleter
*/
function AutoCompleteRequest(request, response, url, limit, returnInactiveAddresses, module)
{
    var term = request.term;

    // optional parameters:
    if (limit === undefined) {
        limit = 12;
    }
    if (returnInactiveAddresses === undefined) {
        returnInactiveAddresses = false;
    }
    if (module === undefined) {
        module = "";
    }

    // retrieve list for autocompleter
    $.ajax({
        type: "POST",
        url: url,
        dataType: "json",
        data: { limit: limit, term: term, returnInactiveAddresses: returnInactiveAddresses, module: module },
        success: function (completeList) {
            var i,
                re,
                item,
                label,
                encodedLabel;

            // we want to bold matching parts of words in the dropdown but not in the input box
            for (i = 0; i < completeList.length; i += 1) {
                re = new RegExp(term, "gi");
                item = completeList[i];
                label = item.replace(re, "!!!!!!!$&@@@@@@@");
                encodedLabel = $("<div/>").text(label).html();
                encodedLabel = encodedLabel.replace(new RegExp("!!!!!!!", "gi"), "<strong>");
                encodedLabel = encodedLabel.replace(new RegExp("@@@@@@@", "gi"), "</strong>");
                completeList[i] =
                {
                    label: encodedLabel, // $& represents the matched value in js regexes
                    value: "<pre>" + $("<div/>").text(item).html() + "</pre>"
                };
            }

            // give list to autocompleter
            response(completeList);
        }
    });
}


function SetTableFieldId(row, rowNumber)
{
    var old = row.attr("id");
    row.attr("id", old.substring(0, old.lastIndexOf('_') + 1) + rowNumber);
    row.attr("name", row.attr("id"));
}


function ResetTableRow(row, rowNumber)
{
    row.find("input").each(function (i) 
    {
        SetTableFieldId($(this), rowNumber);
        if ($(this).attr("type") === "text") 
        {
            $(this).val("");
        }
        else if ($(this).attr("type") === "checkbox")
        {
            $(this).attr("checked", "");
        }
    });
    row.find("select").each(function (i)
    {
        $(this)[0].selectedIndex = 0;
        SetTableFieldId($(this), rowNumber);
    });
}


function AddTableRow(tableId, changedRow)
{
    var selector = "#" + tableId + " tbody>tr:last",
        lastRow = $(selector),
        newRow,
        rowNumber;
    if (changedRow.attr("id") === lastRow.attr("id"))
    {
        newRow = lastRow.clone(true);
        rowNumber = $("#" + tableId + " tbody").children().size();
        
        newRow.attr("id", tableId + "_r" + rowNumber);
        ResetTableRow(newRow, rowNumber);
        lastRow.find("input[type=button]:last").css("visibility", "visible");
        newRow.find("input[type=button]:last").css("visibility", "hidden");
        newRow.insertAfter(selector);
    }
}

function OnTableCellBlur(tableId, tableRow, val)
{
    if (val !== "") 
    {
        AddTableRow(tableId, tableRow);
    }
}

function WireTableCell(tableId, cellId)
{
    var selector = "#" + tableId + " tbody>tr";
    $(selector).each(function (i)
    {
        if (i > 0)
        {
            var ctl = $("#" + cellId + "_" + i);

            if (ctl.length > 0)
            {
                if ($("#" + cellId + "_" + i).is("select"))
                {
                    ctl.change(function () 
                    { 
                        AddTableRow(tableId, $(this).parent().parent()); 
                    });
                }
                else
                {
                    ctl.keydown(function () 
                    { 
                        OnTableCellBlur(tableId, $(this).parent().parent(), $(this).val()); 
                    });
                    
                    ctl.blur(function () 
                    { 
                        OnTableCellBlur(tableId, $(this).parent().parent(), $(this).val()); 
                    });
                }
            }
        }
    });
}


function DeleteTableRow(tableId, tableRow)
{
    tableRow.remove();
    $("#" + tableId + " tbody>tr").each(function (i)
    {
        $(this).attr("id", tableId + "_r" + i);
    });
}


function WireTableCellDelete(tableId, cellId)
{
    var selector = "#" + tableId + " tbody>tr";
    $(selector).each(function (i)
    {
        $("#" + cellId + "_" + i).click(function () 
        { 
            DeleteTableRow(tableId, $(this).parent().parent()); 
        });
        $("#" + cellId + "_" + i).css("visibility", "visible");
    });
    $("#" + tableId + " tbody>tr:last").find("input[type=button]:last").css("visibility", "hidden");
}


function ResetTable(tableId)
{
    $("#" + tableId).find('tr:gt(1)').remove();
    var lastRow = $("#" + tableId + " tbody>tr:last");
    ResetTableRow(lastRow, 1);
    lastRow.find("input[type=button]:last").css("visibility", "hidden");
}


function CopyTable(tableId, copyPrefix)
{
    ResetTable(tableId);
    var selector = "#" + tableId + " tbody>tr:last",
        done = false,
        lastRow,
        
        // needs to be a locally defined function so it can still be a closure and access done variable
        CopyTextAndCheckBoxes = function (i) 
        {
            var copyctl = $('#' + copyPrefix + $(this).attr('id'));
            if ($(this).attr("type") === "text" || $(this).attr("type") === "checkbox")
            {
                if (copyctl.length === 0)
                {
                    done = true;
                }
                else
                {
                    if ($(this).attr("type") === "text")
                    {
                        $(this).val(copyctl.attr('value'));
                    }
                    else if ($(this).attr("type") === "checkbox")
                    {
                        $(this).attr("checked", copyctl.attr('value'));
                    }
                    $(this).trigger("change");
                }
            }
        },
        
        // needs to be a locally defined function so it can still be a closure and access done variable
        CopyDropDownBoxes = function (i)
        {
            var copyctl = $('#' + copyPrefix + $(this).attr('id'));
            if (copyctl.length === 0)
            {
                done = true;
            }
            else
            {
                $(this).val(copyctl.attr('value'));
                $(this).trigger("change");
            }
        };
    
    while (!done)
    {
        lastRow = $(selector);
        lastRow.find("input").each(CopyTextAndCheckBoxes);
        lastRow.find("select").each(CopyDropDownBoxes);
    }
}


///////////////////////////////////////////////////////////////////////////////////////////
// Accordion Setup
///////////////////////////////////////////////////////////////////////////////////////////

//Work-around for this jQuery accordion bug: http://dev.jqueryui.com/ticket/4902
//Re-selecting the first displayed group in the accordion will force it to re-adjust that group's height
function FixAccordions()
{
    var accordions = $(".accordion"),
        accordion;
        
    accordions.each(function (index)
    {
        index = 0;
        var first_visible_section_activated = false;
        $(this).children("h4").each(function (index)
        {
            if (($(this).css("display") !== "none") && first_visible_section_activated === false)
            {
                accordion = $(this).parent();
                accordion.accordion('option', 'collapsible', true);
                accordion.accordion('option', 'animated', false);

                accordion.accordion('activate', false);
                accordion.accordion('activate', index);

                accordion.accordion('option', 'animated', 'slide');
                accordion.accordion('option', 'collapsible', false);
                first_visible_section_activated = true;
            }
        });
    });
}


$(document).ready(function ()
{
    $(".accordion").filter(":hidden").removeClass("accordion").addClass("noaccordion");

    //Create accordions: turn html structure into javascript accordion
    var accordions = $(".accordion").accordion({
        autoHeight: false,
        event: "mouseover"
    });

    //When new accordion group is opened, focus first input field in that group
    accordions.bind('accordionchange', function (event, ui)
    {
        ui.newContent.find("input:first").focus();
    });

    //Bind event to last field in each group: When user presses tab, then open the next group 
    accordions.each(function (index)
    {
        index = 0;  //otherwise index doesn't reset if there is more than one accordion
        $(this).children("div").each(function (index)
        {
            var accordion = $(this).parent();
            $(this).find("input:last").keydown(function (e)
            {
                if (e.shiftKey === false && e.ctrlKey === false && e.which === 9) //if key === Tab.  if person is tabbing backwards or ctrl + tabbing ; do nothing
                {
                    accordion.accordion("activate", index + 1);
                }
                else 
                { 
                    //if person is typing information in the field do nothing  
                } 
            });
        });
    });

    FixAccordions();  
});


var isHandlingValueChanged = false;

function OnValueChanged(data)
{
    isHandlingValueChanged = true;
    try {
        var groupVisibleChange = false,
        val;
        $.each(data, function (changeNumber, change) {
            var ctl = $("#" + change.Id);
            if (ctl.length <= 0) {
                return;
            }
            if (change.ChangeType === 0) {
                //Value
                if (ctl.attr("type") === "checkbox") {
                    if (change.Value === "True") {
                        ctl.attr("checked", "checked");
                    }
                    else {
                        ctl.attr("checked", "");
                    }
                }
                else {
                    ctl.val(change.Value);
                }
            }
            else if (change.ChangeType === 1) {
                //Field Visible
                if (change.Value === "True") {
                    ctl.parent().parent().css('display', 'block');
                }
                else {
                    ctl.parent().parent().css('display', 'none');
                }
            }
            else if (change.ChangeType === 2) {
                // Group Visible
                groupVisibleChange = true;
                if (change.Value === "True") {
                    $("#h_" + change.Id).css('display', 'block');
                    ctl.css('display', 'block');
                }
                else {
                    $("#h_" + change.Id).css('display', 'none');
                    ctl.css('display', 'none');
                }
            }
            else if (change.ChangeType === 3) {
                // Field Required
                if (change.Value === "True") {
                    $("#" + change.Id).css('display', 'inline');
                }
                else {
                    $("#" + change.Id).css('display', 'none');
                }
            }
            else if (change.ChangeType === 4) {
                // Select List
                val = $("#" + change.Id).css("width");
                $("#" + change.Id).html(change.Value);
                $("#" + change.Id).width(val); // IE7 changes the size, so we need to reset it
            }
            else if (change.ChangeType === 5) {
                // Read only
                if (change.Value === "True") {
                    $("#" + change.Id).attr("readOnly", true);
                }
                else {
                    $("#" + change.Id).attr("readOnly", false);
                }
            }
            ctl.trigger("change");
        });

        $("#updated").val("true");
        if (groupVisibleChange) {
            FixAccordions();
        }
    }
    finally {
        isHandlingValueChanged = false;
    }
}


function SetHint(ctl)
{
    if (ctl.val() === "")
    {
        ctl.addClass("hintText");
        ctl.val(ctl.attr("title"));
    }
}


function ClearHint(ctl)
{
    if (ctl.val() === ctl.attr("title"))
    {
        ctl.removeClass("hintText");
        ctl.val("");
    }
}


function ClearHints()
{
    $(":input[type=text]").each(function (i) 
    { 
        ClearHint($(this)); 
    });
}


function WireHints()
{
    $(":input[type=text]").each(function (i)
    {
        if ($(this).attr("title") !== "")
        {
            if ($(this).val() === "")
            {
                SetHint($(this));
            }
            $(this).blur(function () 
            { 
                SetHint($(this)); 
            });
            $(this).focus(function () 
            { 
                ClearHint($(this)); 
            });
        }
    });
}


function EnablePanel(id, enable)
{
    if (enable)
    {
        $("#" + id).find("*").each(function () 
        { 
            $(this).removeAttr("disabled"); 
        });
    }
    else
    {
        $("#" + id).find("*").each(function () 
        { 
            $(this).attr("disabled", true); 
        });
    }
}

function CurrencyToNumber(val)
{
    val = val.replace("$", "");
    val = val.replace(",", "");
    return parseFloat(val);
}

function NumberToCurrency(val)
{
    var number = val.toFixed(2),
        regex = /(\d+)(\d{3})/;

    //find the last group of 3 numbers before a decimal or comma, then add a comma before it.  repeat until done
    while (regex.test(number))
    {
        number = number.replace(regex, '$1,$2');
    }
    return "$" + number;
}


function AddFees()
{
    var total = 0;
    $("#fees tbody tr td:last-child>input:checked").each(function ()
    {
        $(this).parent().parent().find("td:nth-child(2)").each(function ()
        {
            total += CurrencyToNumber($(this).text());
        });
        $(this).parent().parent().find("td:nth-child(3)").each(function () {
            total -= CurrencyToNumber($(this).text());
        });
    }
      );
    $("#feeSelected_0_1").text(NumberToCurrency(total));
}


function SelectFees(checked)
{
    $("#fees tbody tr td:last-child input:checkbox:visible").each(function () 
    { 
        this.checked = checked; 
    });
    AddFees();
}

///////////////////////////////////////////////////////////////////////////////////////////
// Step Menu
///////////////////////////////////////////////////////////////////////////////////////////

//Turns an #step-menu into a list of steps based on the #currentStep that the form is on
//Specifically, this will insert step numbers, equalize the widths, and apply a few
//css classes which will change the colours and add background images
function InitializeStepMenu()
{
    var totalSteps = $('#step-menu li').size(),
        halfway = Math.ceil(totalSteps / 2),
        currentStepNumber = parseInt($("#currentTab").val(), 10),
        tooManySteps = 7,
        addRowSpacer = false,
        rowSpacer = 3,
        imgHeight = 56,
        halfOfImageWidth = 10,
        step;

    //If there are too many steps, make the menu twice as tall
    if (totalSteps >= tooManySteps)
    {
        $("#step-menu").height((imgHeight * 2) + rowSpacer);
    }

    $('#step-menu li').each(function (stepNumber)
    {
        step = $(this);

        //remove classes, "Step 1:", and transition images from steps
        step.removeClass();
        step.find(".step-arrow").remove();
        step.find(".step-tail").remove();
        step.find("span strong").remove();

        //Add "Step 1: " etc. to the step
        step.children("span").prepend("<strong>Step " + (stepNumber + 1) + ": </strong>");

        //Add the spans that hold the transition images
        step.append("<span class='step-arrow'>&nbsp;</span>");
        step.append("<span class='step-tail'>&nbsp;</span>");

        //Applying classes:
        if (stepNumber === currentStepNumber) 
        { 
            step.addClass("step-current"); 
        }
        else if (stepNumber < currentStepNumber) 
        { 
            step.addClass("step-complete"); 
        }
        else if (stepNumber > currentStepNumber) 
        { 
            step.addClass("step-incomplete"); 
        }
        else 
        { 
            /*something is wrong - don't add any classes*/ 
        }

        if (stepNumber === 0) 
        { 
            step.addClass("first-step"); 
        }
        else if (stepNumber === (totalSteps - 1)) 
        { 
            step.addClass("last-step"); 
        }
        else 
        { 
            /*everything is fine, this is normal*/ 
        }


        //Single-row handling: Make all steps equal widths that add up to 100%
        if (totalSteps < tooManySteps)
        {
            step.css('width', (100 / totalSteps) + "%");
        }
        //Multi-row handling:
        else
        {
            //set widths for first (top) row
            if (stepNumber < halfway) 
            { 
                step.css('width', (100 / halfway) + "%"); 
            }

            //set widths for second (bottom) row
            if (stepNumber >= halfway) 
            { 
                step.css('width', (100 / (totalSteps - halfway)) + "%"); 
            }

            //if this step is just before the halfway point, it will be the last on the old row
            if (stepNumber === (halfway - 1)) 
            { 
                step.addClass("last-step-on-old-row"); 
            }

            //if this step is the halfway point, it will be the first on the new row.  
            //We will want to start spacing out the new row from the old one
            if (stepNumber === halfway) 
            { 
                step.addClass("first-step-on-new-row"); 
                addRowSpacer = true; 
            }

            //add a top margin if this is the second row
            if (addRowSpacer) 
            { 
                step.css("margin-top", rowSpacer + "px"); 
            }

            //WARNING: These numbers are ONLY based off of the APPEARANCE OF THE PIXELS of the 
            //arrow and tail images and will need to change if the image contents ever change
            if (stepNumber === halfway) 
            { 
                step.css('margin-left', '16px'); 
                step.width(step.width() - 16); 
            }
            if (stepNumber === (totalSteps - 1)) 
            { 
                step.width(step.width() - 6);
            }
        }

        //even out widths of first and last steps on each line.  
        //(minus an extra pixel each to compensate for IE7)
        if (step.hasClass("first-step") || step.hasClass("first-step-on-new-row")) 
        { 
            step.width(step.width() + halfOfImageWidth - 1); 
        }
        if (step.hasClass("last-step") || step.hasClass("last-step-on-old-row")) 
        { 
            step.width(step.width() - halfOfImageWidth - 1); 
        }

    });
}


///////////////////////////////////////////////////////////////////////////////////////////
// Popup panel
///////////////////////////////////////////////////////////////////////////////////////////

// 0 means disabled; 1 means enabled;   
function CVPopup(id)
{
    this.ctlid = id;
}


//loading popup 
CVPopup.prototype.load = function ()
{
    //loads popup only if it is disabled
    $("#backgroundPopup").css({
        "opacity": "0.5"
    });
    $("#backgroundPopup").fadeIn("fast");
    $("#" + this.ctlid).fadeIn("fast");
    $("#isnewcontact").val("y");
};


CVPopup.prototype.disable = function ()
{
    //disables popup only if it is enabled
    $("#backgroundPopup").fadeOut("fast");
    $("#" + this.ctlid).fadeOut("fast");
    $("#isnewcontact").val("n");
};


CVPopup.prototype.center = function ()
{
    //request data for centering
    var windowWidth = document.documentElement.clientWidth,
        windowHeight = document.documentElement.clientHeight,
        popupHeight = $("#" + this.ctlid).height(),
        popupWidth = $("#" + this.ctlid).width();

    //centering
    $("#" + this.ctlid).css({
        "position": "fixed",
        "top": windowHeight / 2 - popupHeight / 2,
        "left": windowWidth / 2 - popupWidth / 2
    });
};

///////////////////////////////////////////////////////////////////////////////////////////
// Uploadify
///////////////////////////////////////////////////////////////////////////////////////////

//function called when the uploadify onComplete event is triggered (once for each file upload)
//if the file upload failed, highlight it red and display the error message received at the bottom
function UploadifyOnCompleteHandler(event, queueId, fileObj, response, data)
{
    if (response !== "1")
    {
        $('#fileUpload' + queueId + ' .percentage').text(' - IO Error');
        $('#fileUpload' + queueId).addClass('uploadifyError');

        if ($("#fileUploadQueueErrorMessage").exists() !== 1)
        {
            $("#fileUploadQueue").after("<div id='fileUploadQueueErrorMessage' class='warningText' style='margin:5px'></div>");
        }

        $("#fileUploadQueueErrorMessage").text(response);
    }
}

