                    
 
function PopupOpening(sender, args)
 {
     Telerik.Web.UI.Calendar.Popup.zIndex = 100100;
 }
 



// overlabel
						  						   

(function($){

$.fn.overlabel = function() {
    this.each(function() {
        var $label = $(this),
            $input = $('#' + $label.attr('for'));

        $label
            .addClass('overlabel')
            .bind('click', function(event) {
                $input.focus();
            });

        $input
            .bind('focus blur', function(event) {
                $label.css('display', (event.type == 'blur' && !$input.val() ? '' : 'none'));
            }).trigger('blur');
    });
};

})(jQuery);

$(document).ready(function(){
// select labels for text inputs, assuming the label is directly before the input
$('.overlabelbox input[type=text]').prev('label').overlabel();
});


// end overlabel


$(document).ready(function(){				   
	
	$(".dropdownMenu").hoverIntent(
  function() { $(this).children(".dropdown").show("fast"); },
  function() { $(this).children(".dropdown").hide("fast"); }
);
	
		$(".dropdownMenu > a").click(function(event) {
  event.preventDefault();
});	
	 







    $(function () {
        var wizard = $(".modal");

        // :first selector is optional if you have only one tabs on the page
        $(".css-tabs").tabs(".css-panes > div.tab-pane");


        // get handle to the tabs API
        var api = $(".css-tabs", wizard).data("tabs");

   // "previous tab" button
        $("a.prev", wizard).click(function () {
            api.prev();
        });

        // "next tab" button
        $("a.next", wizard).click(function () {
            api.next();
        });


    });

});


/// <reference name="MicrosoftAjax.debug.js" />

window.onload = function() {
    // Disable the Back Button and Back Space Key Press
    //INNO.Benny we do not need this any more with the new Friendly URL system in place
    //window.history.forward(1);

    // Ensure the page is enabled
    EnablePage();
}

// Validates that the entry has a length > 0.  Used by the CustomRequiredFieldValidator
function ValidateLength(sender, args) {
    // Check whether or not this entry has data
    var isValidEntry = args.Value.length > 0;
    if (isValidEntry == false)
    // Entry was not valid, enable the page so that text entry can resume
        EnablePage();

    args.IsValid = isValidEntry;
}

// Validates that the entry is numeric.  Used by the CustomNumericFieldValidator
function ValidateNumeric(sender, args) {
    // Define numeric RegEx
    //This is anchor regex 
    //  ^   # anchor at the start
    //  -?  # allow a negative for the first character
    //  [\d,]* # allow any number of digits and commas
    //  (\.\d+)?    # allow a period with at least one digit after it
    //  $   # anchor at the end
    var numericRegex = /^-?[\d,]*(\.\d+)?$/;

    // Check text entry
    if (!args.Value.match(numericRegex)) {
        // Entry was not valid, enable the page so that text entry can resume
        EnablePage();
        args.IsValid = false;
    }
    else {
        args.IsValid = true;
    }
}

// Enables the page
function EnablePage() {
    // Get the Posting Div
    var postingDiv = document.getElementById('posting');
    // Reduce the size of the posting div
    postingDiv.style.height = '0px';
    postingDiv.style.width = '0px';
}

// Disables the page
function DisablePage() {
    // Get the Posting Div
    var postingDiv = document.getElementById('posting');
    // Increate the size of the posting div	
    postingDiv.style.height = '100%';
    postingDiv.style.width = '100%';
}

// Presents the user with a confirm message.  
function ConfirmDelete(message) {
    var answer = confirm(message);
    if (answer != 0) {
        DisablePage();
        return true;
    }
    else {
        return false;
    }
}

// Refreshes an image
function refreshImage(controlID, destination) {
    var image = document.getElementById(controlID);
    image.src = destination;
}

// Refreshes a Camera 
function RefreshCamera(controlID, destination, interval) {
    var time = new Date();
    setTimeout('refreshImage("' + controlID + '","' + destination + '?' + time + '");', interval * 1000);
}

//  Limits text entry depending on the maxlimit
function limitTextEntry(field, maxlimit) {
    if (field.value.length > maxlimit) {
        field.value = field.value.substring(0, maxlimit);
    }
}


// Parses and returns an array represending the Querystring   
function parseQuerystring() {
    var params = new Array();
    var querystring = location.search.substring(1);
    var pairs = querystring.split('&');

    for (var i in pairs) {
        var nameValuePair = pairs[i].split('=');
        params[nameValuePair[0]] = nameValuePair[1];
    }
    return params;
}



// r.a.d.ComboBox Methods 

// Enables the ComboBox
function OnClientItemsRequestedEventHandler(combobox) {
    combobox.Enabled = true;
}

// Clears and Disables the ComboBox
function OnClientItemsRequestingEventHandler(combobox) {
    combobox.Enabled = false;
    combobox.Items = [];
    document.getElementById(combobox.DropDownID).innerHTML = "";
}


// r.a.d.Window Methods

// This code is used to provide a reference to the radwindow "wrapper"
function GetRadWindow() {
    var radWindow = null;
    if (window.radWindow) {
        //Will work in Moz in all cases, including clasic dialog
        radWindow = window.radWindow;
    }
    else if (window.frameElement.radWindow) {
        //IE (and Moz az well)
        radWindow = window.frameElement.radWindow;
    }

    return radWindow;
}

function CloseOnReload() {
    GetRadWindow().close();
}

// Forces the parent page to PostBack to the Web Server
function ForceParentPagePostBack() {
    var window = GetRadWindow().BrowserWindow;
    window.__doPostBack('ForcedPostBack', '');
}

// Refreshes the parent page, equilavent to an F5
function RefreshParentPage() {
    GetRadWindow().BrowserWindow.location.reload();
}

// Opens a radWindow for a specific Lookup, indicated by the lookupID
function OpenSearchWindow(lookupID, height, width) {
    try {
        // Open the radWindow
        var radSearchWindow = window.radopen("Search.aspx?MyLookupID=" + lookupID, "rwLookup");

        // Size the radWindow
        radSearchWindow.setSize(width, height);

        // Move the radWindow to the upper left of the screen
        radSearchWindow.MoveTo(50, 50);
    }
    catch (error) {
        alert(error.message);
    }
}

function FocusOnRow(rowID) {
    var focusElement = $get(rowID);
    if (focusElement) {
        Telerik.Web.UI.Grid.ScrollIntoView(focusElement);
    }
}

//EditableGridManager -------------------------------------------------------------------------------
//Only one editableGridManager is ever created
var $egm = EditableGridManager = function(lookupIframeElemID, lookupURL) {
    this.lookupIframeElemID = lookupIframeElemID;
    this.lookupURL = lookupURL;

    this.grids = new Object();

    this.lookupManager = null;
    this.isLookupWindowLoadedDelegateSet = false;

    //The WebForm_InitCallback is not needed and so we override the method to speed up the process of updating especially in IE
    WebForm_InitCallback = function() { };
}

EditableGridManager.prototype = {
    LookupWindowLoaded: function() {
        if (this.lookupManager != null) {
            this.lookupManager.OnLookupLoaded();

            this.lookupManager = null;
        }
    },

    GetContainerElement: function(elem) {
        var containerElem = elem;

        while (containerElem != null) {
            if ("id" in containerElem && containerElem.id.indexOf("___") != -1) {
                break;
            }
            else {
                containerElem = containerElem.parentNode;
            }
        }

        if (containerElem != null) {
            return new EditableGridManager.ContainerElement(containerElem);
        }
        else {
            return null;
        }
    },

    CreateLookupManager: function(elem) {
        var containerElem = this.GetContainerElement(elem);

        if (containerElem != null) {
            var rowPrefix = containerElem.GetRowPrefix();
            var columnName = containerElem.GetColumnName();
            var rowIndex = containerElem.GetRowIndex();

            var grid = this.GetGrid(containerElem.ID());

            if (grid.GetColumn(columnName).HasALookup()) {
                if (this.isLookupWindowLoadedDelegateSet == false) {
                    GetRadWindowManager().add_pageLoad(Function.createDelegate(this, this.LookupWindowLoaded));
                    this.isLookupWindowLoadedDelegateSet = true;
                }

                this.lookupManager = grid.CreateLookupManager(this.lookupIframeElemID, this.lookupURL, rowPrefix, columnName, rowIndex);
                this.lookupManager.OpenLookupWindow();
                grid.LoadValidationForARow(rowIndex);
            }
        }
    },

    GetGrid: function(elemID) {
        for (var gridID in this.grids) {
            if (elemID.indexOf(gridID) > -1) {
                return this.grids[gridID];
            }
        }

        return null;
    },

    AddGrid: function(gridClientID, pageSiteControlID, gridLayoutPosition) {
        var grid = new EditableGridManager.EditableGrid(gridClientID, pageSiteControlID, gridLayoutPosition);

        this.grids[gridClientID] = grid;

        return grid;
    }
}

//Static methods for EditableGridManager

//A lazy loader that returns the EditableGridManager singleton
EditableGridManager.getInstance = function() {
    if (EditableGridManager._instance == null) {
        //Replace method definitions with better definitions
        Telerik.Web.UI.GridSelection.prototype._click = EditableGridManager._click;
        EditableGridManager._instance = new EditableGridManager("rwLookup", "EditableGridSearch.aspx");
    }

    return EditableGridManager._instance;
}

EditableGridManager.ShowLookup = function(elem) {
    EditableGridManager.getInstance().CreateLookupManager(elem);

    return false;
}

EditableGridManager.RegisterGridInformation = function(gridClientID, pageSiteControlID, gridLayoutPosition) {
    return EditableGridManager.getInstance().AddGrid(gridClientID, pageSiteControlID, gridLayoutPosition);
}

EditableGridManager.OnGridCreated = function(grid) {
    var editableGrid = EditableGridManager.getInstance().GetGrid(grid.ClientID);
    if (editableGrid != null) {
        editableGrid.GridCreated(grid);
    }
}

EditableGridManager.Delete = function(gridClientID) {
    EditableGridManager.getInstance().GetGrid(gridClientID).Delete();

    return false;
}

EditableGridManager.Update = function(gridClientID) {
    EditableGridManager.getInstance().GetGrid(gridClientID).Update();

    return false;
}
//End EditableGridManager -------------------------------------------------------------------------------

//ContainerElement --------------------------------------------------------------------------------------
//A wrapper for a container element
EditableGridManager.ContainerElement = function(elem) {
    this.elem = elem;
}

EditableGridManager.ContainerElement.prototype = {
    GetRowPrefix: function() {
        return this.elem.id.split("___")[0] + "_";
    },

    GetColumnName: function() {
        return this.elem.id.split("___")[1].split("__")[0];
    },

    GetRowIndex: function() {
        return this.elem.id.split("___")[1].split("__")[1];
    },

    IsNewRow: function() {
        return this.GetRowIndex() == "-1";
    },

    ID: function() {
        return this.elem.id;
    }
}
//End ContainerElement ----------------------------------------------------------------------------------

//EditableGrid ----------------------------------------------------------------------------------
//Manages the bulk processing related to an editable grid
EditableGridManager.EditableGrid = function(id, pageSiteControlID, gridLayoutPosition) {
    this._id = id;
    this.pageSiteControlID = pageSiteControlID;
    this.gridLayoutPosition = gridLayoutPosition;

    this._isNewRowSelected = false;

    this._columns = new Array();
    
    this.relatedValidatorsTemplates = new Array();
}

EditableGridManager.EditableGrid.prototype = {
    get_id: function() {
        return this._id;
    },

    get_serverID: function() {
        var ids = this._id.split("_");

        return ids[ids.length - 1];
    },

    get_gridControl: function() {
        return $find(this._id);
    },

    get_columns: function() {
        return this._columns;
    },

    get_insertRow: function() {
        var gridControl = this.get_gridControl();

        if (gridControl) {
            var tableHeaderViewElement = gridControl.get_masterTableViewHeader().get_element();

            //The assumption is that the insert row is the last row in the master table view header
            var headRows = tableHeaderViewElement.tHead.rows;

            if (headRows.length >= 1) {
                return headRows[headRows.length - 1];
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    },

    set_IsNewRowSelected: function(value) {
        this._isNewRowSelected = value;

        if (value) {
            this.get_gridControl().get_masterTableView().clearSelectedItems();
        }
    },

    get_IsNewRowSelected: function(value) {
        return this._isNewRowSelected;
    },

    RegisterValidatorTemplate: function(validatorTemplate) {
        Array.add(this.relatedValidatorsTemplates, new EditableGridManager.ValidatorTemplate(validatorTemplate));
    },

    //Using ajax this will get called every time we update the contents
    GridCreated: function(sender, args) {
        var grid = sender;

        grid.add_gridDestroying(Function.createDelegate(this, this.GridDestroying));

        var gridElement = grid.get_element();
        var gridElementID = gridElement.id;
        //These handlers get cleared by the grid automatically on AJAX postbacks
        $addHandler(gridElement, "click", Function.createDelegate(this, this.GridClick));
        $addHandler(gridElement, "keydown", Function.createDelegate(this, this.OnKeyDown));

        var masterTableViewElement = grid.get_masterTableView().get_element();
        var insertRow = this.get_insertRow();

        var focusDelegate = Function.createDelegate(this, this.OnFocus);

        if (masterTableViewElement.attachEvent) {
            masterTableViewElement.attachEvent("onfocusin", focusDelegate);
            if (insertRow) {
                insertRow.attachEvent("onfocusin", focusDelegate);
            }
        }
        else {
            masterTableViewElement.addEventListener("focus", focusDelegate, true);
            if (insertRow) {
                insertRow.addEventListener("focus", focusDelegate, true);
            }
        }

        //In order for $clearHandlers to work later we need to setup the elements with the handlers
        masterTableViewElement._events = {};
        insertRow._events = {};
        masterTableViewElement._events["focus"] = [{ handler: focusDelegate, browserHandler: focusDelegate}]
        insertRow._events["focus"] = [{ handler: focusDelegate, browserHandler: focusDelegate}]

        if (insertRow) {
            var focusElem = this.FocusFirstFocusableElement(insertRow.cells);
            focusElem.focus();
        }
        else {
            var rows = this.get_gridControl().get_masterTableView().get_element().tBodies[0].rows;
            if (rows.length > 0) {
                var focusElem = this.FocusFirstFocusableElement(rows[0]);
                focusElem.focus();
            }
        }
    },

    FocusFirstFocusableElement: function(elements) {
        for (var i = 0; i < elements.length; i++) {
            if (elements[i].focus && elements[i].tagName == "INPUT") {
                return elements[i];
            }
            else if (elements[i].childNodes.length > 0) {
                var returnElement = this.FocusFirstFocusableElement(elements[i].childNodes);
                if (returnElement != null) {
                    return returnElement;
                }
            }
        }
    },

    GridDestroying: function(sender, args) {
        var gridControl = sender;

        $clearHandlers(gridControl.get_masterTableView().get_element());

        var insertRow = this.get_insertRow();
        if (insertRow) {
            $clearHandlers(insertRow);
        }

        Array.clear(this.relatedValidatorsTemplates);
    },

    IsAParentElement: function(parent, element) {
        return isParent(parent, element);

        function isParent(parent, element) {
            if (element.parentNode) {
                if (element.parentNode == parent)
                    return true;
                else
                    return isParent(parent, element.parentNode);
            }
            else
                return false;
        }
    },

    GridClick: function(sender) {
        var insertRow = this.get_insertRow();

        if (insertRow) {
            var isNewRowSelected = this.IsAParentElement(insertRow, sender.target);
            if (isNewRowSelected != this.get_IsNewRowSelected()) {
                this.set_IsNewRowSelected(isNewRowSelected);
            }
        }
    },

    OnFocus: function(ev) {
        if (ev == null) {
            ev = event;
        }

        var target;

        if (ev.srcElement) {
            target = ev.srcElement;
        }
        else {
            target = ev.target;
        }

        Array.forEach(this.relatedValidatorsTemplates, registerValidatorsIfNeeded, this);

        function registerValidatorsIfNeeded(relateValidatorTemplate) {
            var validationInfo = relateValidatorTemplate.GetElementValidationInfo(target.id);

            if (validationInfo != null && !validationInfo.get_ValidatedElementHasBeenSetup()) {
                relateValidatorTemplate.SetupValidation(validationInfo);
            }
        }
    },

    OnKeyDown: function(sender) {
        if (sender.keyCode == 115 || (sender.keyCode == 83 && sender.ctrlKey) || (sender.keyCode == 68 && sender.ctrlKey)) /* F4 lookup/ ctrl + s/ ctrl + d */{
            try { //Prevent browsers from performing their default action
                sender.rawEvent.keyCode = -1;
            }
            catch (e) {
            }

            sender.preventDefault();
        }

        if (sender.keyCode == 115) /* F4 lookup */{
            EditableGridManager.getInstance().CreateLookupManager(sender.target);
        }

        var containerElem;

        if (sender.keyCode == 27) /* Escape key to revert row*/{
            containerElem = EditableGridManager.getInstance().GetContainerElement(sender.target);

            if (containerElem != null) {
                Array.forEach(this.get_columns(), getColumnControlManager, this);
            }
        }

        function getColumnControlManager(column) {
            column.Revert(containerElem.IsNewRow(), containerElem.GetRowPrefix());
        }

        if (sender.keyCode == 83 && sender.ctrlKey) /* ctrl + s to do update */{
            this.Update();
        }

        if (sender.keyCode == 68 && sender.ctrlKey) /* ctrl + d to do delete */{
            this.Delete();
        }
    },

    LoadValidationForARow: function(rowIndex) {
        Array.forEach(this.relatedValidatorsTemplates, registerValidatorsIfNeeded, this);

        function registerValidatorsIfNeeded(relatedValidatorTemplate) {
            var validatorInfo = relatedValidatorTemplate.get_ValidationGroupValidatorInfoDictionary()[this.get_serverID() + "_" + rowIndex];

            if (validatorInfo != null && !validatorInfo.get_ValidatedElementHasBeenSetup()) {
                relatedValidatorTemplate.SetupValidation(validatorInfo);
            }
        }
    },

    //Creates a lookup manager by collecting information about the row and opens a lookup
    //by sending the row information in the url of the lookup page
    CreateLookupManager: function(lookupIframeElemID, lookupURL, rowPrefix, columnName, rowIndex) {
        var dataGridColumnID = this.GetColumn(columnName).get_columnID();
        var newRow = rowIndex == "-1";

        var urlParametersBuilder = new Array();
        Array.add(urlParametersBuilder, String.format("?DataGridColumnID={0}&PageSiteControlID={1}&DefaultDataGridPosition={2}&IsANewRecord={3}", dataGridColumnID, this.pageSiteControlID, this.gridLayoutPosition, newRow));

        var columnControlManagers = new Array();

        Array.forEach(this.get_columns(), getColumnControlManager, this);

        function getColumnControlManager(column) {
            Array.add(columnControlManagers, column.GetValueControlManager(newRow, rowPrefix));
        }

        var columnsAddedToQueryString = new Array();

        Array.forEach(columnControlManagers, getAssociatedColumnValues, this);

        function getAssociatedColumnValues(columnControlManager) {
            var columnName = columnControlManager.get_associatedColumnName();

            if (columnName != null) {
                Array.add(urlParametersBuilder, String.format("&{0}={1}", escape(columnName), escape(columnControlManager.GetAssociatedValue())));

                Array.add(columnsAddedToQueryString, columnName);
            }
        }

        Array.forEach(columnControlManagers, getColumnValues, this);

        function getColumnValues(columnControlManager) {
            var columnName = columnControlManager.get_columnName();

            if (columnName != null && !Array.contains(columnsAddedToQueryString, columnName)) {
                Array.add(urlParametersBuilder, String.format("&{0}={1}", escape(columnName), escape(columnControlManager.GetValue())));

                Array.add(columnsAddedToQueryString, columnName);
            }
        }

        if (!newRow) {
            var clientKeyNames = this.get_gridControl().get_masterTableView().get_clientDataKeyNames();
            var keyValues = this.get_gridControl()._clientKeyValues[rowIndex];

            Array.forEach(clientKeyNames, getKeyValues, this);
        }

        //The function needs to be outside the if statement to evaluate correctly
        function getKeyValues(clientKeyName) {
            if (!Array.contains(columnsAddedToQueryString, clientKeyName)) {
                Array.add(urlParametersBuilder, String.format("&{0}={1}", escape(clientKeyName), escape(keyValues[clientKeyName])));
            }
        }

        var urlParameters = urlParametersBuilder.join("");

        return new EditableGridManager.LookupManager(lookupIframeElemID, this, rowPrefix, lookupURL + urlParameters);
    },

    //Used when loading the page to load related information about the column
    //Must return the grid so that we can continue to call grid methods
    AddColumn: function(columnName, columnID, changesAllowedOnAdd, changesAllowedOnUpdate, hasALookup, getDelegate, setDelegate, revertDelegate) {
        var column = new EditableGridManager.Column(columnName, columnID, changesAllowedOnAdd, changesAllowedOnUpdate, getDelegate, setDelegate, revertDelegate);
        column.set_hasALookup(hasALookup);

        Array.add(this._columns, column);

        return this;
    },

    //Used when loading the page to load related information about the column
    //Must return the grid so that we can continue to call grid methods
    AddColumnWithAssociatedColumn: function(columnName, columnID, changesAllowedOnAdd, changesAllowedOnUpdate, hasALookup, associatedColumnName, getDelegate, setDelegate, revertDelegate) {
        var column = new EditableGridManager.Column(columnName, columnID, changesAllowedOnAdd, changesAllowedOnUpdate, getDelegate, setDelegate, revertDelegate);
        column.set_hasALookup(hasALookup);
        column.set_associatedColumnName(associatedColumnName);

        Array.add(this._columns, column);

        return this;
    },

    //Returns EditableGridManager.Column if in grid
    GetColumn: function(columnName) {
        var returnColumn;

        Array.forEach(this._columns, getColumn, this);

        function getColumn(column) {
            if (column.get_columnName() == columnName) {
                returnColumn = column;
            }
        }

        return returnColumn;
    },

    BuildValidationGroupArray: function(validationGroup) {
        var validators = new Array();

        Array.forEach(this.relatedValidatorsTemplates, buildValidationGroupArray, this);

        function buildValidationGroupArray(validatorTemplate) {
            var validationGroupDictionary = validatorTemplate.get_ValidatorValidationGroupDictionary();

            if (validationGroup in validationGroupDictionary) {
                Array.add(validators, validationGroupDictionary[validationGroup]);
            }
        }

        return validators;
    },

    Update: function() {
        var validationPassed = true;
        var allValidators = Page_Validators;
        var allValidationSummaries = Page_ValidationSummaries;

        //Microsoft's built in validation doesn't allow for validation to be called on multiple validation groups
        //without clearing the results of each validation group.
        //Therefore what we do is fake the validation into performing validation on one validation group at a time
        //without overriding the results of the other validation groups.

        //Step 1 is to build a dictionary of validator summary arrays base on their validation group
        var validatorGroupSummaries = new Object();

        Array.forEach(Page_ValidationSummaries, validatorSummariesLoop);

        function validatorSummariesLoop(validatorSummary) {
            if (validatorGroupSummaries[validatorSummary.validationGroup] == null) {
                validatorGroupSummaries[validatorSummary.validationGroup] = new Array();
            }

            Array.add(validatorGroupSummaries[validatorSummary.validationGroup], validatorSummary);
        }

        //Step 2 is to loop through all the rows that are being validated and validate
        var rows = this.get_gridControl().get_masterTableView().get_element().tBodies[0].rows;

        //Start at -1 which is the insert row
        for (var i = -1; i < rows.length; i++) {
            //The validation group name was built on the server control ID and the row index.
            var validationGroup = this.get_serverID() + "_" + i;

            //We temporarily replace the validators for the page with only the validators that pertain to this validation group
            var validators = this.BuildValidationGroupArray(validationGroup);
            if (validators.length > 0) {
                Page_Validators = validators;

                //We do the same thing with the summaries
                Page_ValidationSummaries = validatorGroupSummaries[validationGroup];

                //Now when we validate, only validators within our validation group are checked.
                if (!Page_ClientValidate(validationGroup)) {
                    validationPassed = false;
                }
            }
        }

        //We now make sure that our valiators are set back to what they are supposed to be.
        Page_Validators = allValidators;
        Page_ValidationSummaries = allValidationSummaries;

        if (validationPassed) {
            //We need to perform insert in order to make the grid act correctly on the server side.
            this.get_gridControl().get_masterTableView().fireCommand("UpdateAll", "");
        }
    },

    Delete: function() {
        var selectedIndexes = this.get_gridControl()._selectedIndexes;

        if (selectedIndexes.length > 0 && confirm("Are you sure you wish to delete the selected row?")) {
            this.get_gridControl().get_masterTableView().fireCommand("DeleteWithoutRebinding", selectedIndexes[0]);
        }
    }
}
//End EditableGrid -------------------------------------------------------------------------------

//Column -------------------------------------------------------------------------------
//Contains information about each column in the grid and provides methods for updating/getting/reverting a cell value
EditableGridManager.Column = function(columnName, columnID, changesAllowedOnAdd, changesAllowedOnUpdate, getDelegate, setDelegate, revertDelegate) {
    this._columnName = columnName;
    this._columnID = columnID;
    this.getDelegate = getDelegate;
    this.setDelegate = setDelegate;
    this.revertDelegate = revertDelegate;
    this.changesAllowedOnAdd = changesAllowedOnAdd;
    this.changesAllowedOnUpdate = changesAllowedOnUpdate;

    this._associatedColumnName = null;
    this._hasALookup = false;
}

EditableGridManager.Column.prototype = {
    get_columnName: function() {
        return this._columnName;
    },

    get_columnID: function() {
        return this._columnID;
    },

    set_associatedColumnName: function(value) {
        this._associatedColumnName = value;
    },

    get_associatedColumnName: function() {
        return this._associatedColumnName;
    },

    set_hasALookup: function(value) {
        this._hasALookup = value;
    },

    GetValueControlManager: function(isNewRow, rowPrefix) {
        var controlManager = new EditableGridManager.ControlManager(this._columnName, this._associatedColumnName);

        this.ExecuteDelegate(this.getDelegate, controlManager, isNewRow, rowPrefix);

        return controlManager;
    },

    SetValue: function(isNewRow, rowPrefix, value, associatedValue) {
        var controlManager = new EditableGridManager.ControlManager(this._columnName, this._associatedColumnName);
        controlManager.SetValue(value);
        controlManager.SetAssociatedValue(associatedValue);

        this.ExecuteDelegate(this.setDelegate, controlManager, isNewRow, rowPrefix);
    },

    Revert: function(isNewRow, rowPrefix) {
        var controlManager = new EditableGridManager.ControlManager(this._columnName, this._associatedColumnName);
        
        this.ExecuteDelegate(this.revertDelegate, controlManager, isNewRow, rowPrefix);
    },

    ExecuteDelegate: function(delegate, controlManager, isNewRow, rowPrefix) {
        if (isNewRow) {
            delegate(controlManager, this.changesAllowedOnAdd, rowPrefix);
        }
        else {
            delegate(controlManager, this.changesAllowedOnUpdate, rowPrefix);
        }
    },

    HasALookup: function() {
        return this._hasALookup;
    }
}
//End Columm -------------------------------------------------------------------------------

//Control Manager -------------------------------------------------------------------------------
//A simple object used in getting/setting/reverting column information
EditableGridManager.ControlManager = function(columnName, associatedColumnName) {
    this._columnName = columnName;
    this._associatedColumnName = associatedColumnName;
}

EditableGridManager.ControlManager.prototype = {
    get_columnName: function() {
        return this._columnName;
    },

    get_associatedColumnName: function() {
        return this._associatedColumnName;
    },

    GetValue: function() {
        return this.value;
    },

    GetAssociatedValue: function() {
        return this.associatedValue;
    },

    SetValue: function(value) {
        this.value = value;
    },

    SetAssociatedValue: function(associatedValue) {
        this.associatedValue = associatedValue;
    }
}
//End Control Manager -------------------------------------------------------------------------------

//Lookup Manager -------------------------------------------------------------------------------
//Handles the transfer of values from the lookup iframe back to a row
EditableGridManager.LookupManager = function(lookupIframeElemID, grid, rowPrefix, url) {
    this.lookupIframeElemID = lookupIframeElemID;
    this.grid = grid;
    this.rowPrefix = rowPrefix;
    this.url = url;

    this.radLookupWindow = null;
}

EditableGridManager.LookupManager.prototype = {
    OpenLookupWindow: function() {
        this.radLookupWindow = window.radopen(this.url, this.lookupIframeElemID);

        // Size the radWindow
        this.radLookupWindow.setSize(600, 600);

        // Move the radWindow to the upper left of the screen
        this.radLookupWindow.MoveTo(50, 50);
    },

    OnLookupLoaded: function() {
        this.radLookupWindow.GetContentFrame().contentWindow.EditableGridManager.LookupManagerForLookup = this;
    },

    UpdateValue: function(returnColumnName, associatedColumnName, rowKeyValues, updateColumnName) {
        var newValue = rowKeyValues[returnColumnName];
        var newAssociatedValue = null;

        var updateColumn = this.grid.GetColumn(updateColumnName);

        var updateAssociatedColumnName = updateColumn.get_associatedColumnName();

        if (updateAssociatedColumnName != null) {
            newAssociatedValue = rowKeyValues[associatedColumnName];

            var updateAssociatedColumn = this.grid.GetColumn(updateAssociatedColumnName);

            if (updateAssociatedColumn != null) {
                updateAssociatedColumn.SetValue(true, this.rowPrefix, newAssociatedValue, null);
            }
        }

        this.grid.GetColumn(updateColumnName).SetValue(true, this.rowPrefix, newValue, newAssociatedValue);

        this.radLookupWindow.Close();
    },

    CloseWindow: function() {
        this.radLookupWindow.Close();
    }
}

//This static variable allows is set in  LookupManager.OnLookupLoaded so that when a user selects a value from the lookup
//we can call EditableGridManager.LookupManagerForLookup.UpdateValue from EditableGridManager.UpdateValue within the iframe
EditableGridManager.LookupManagerForLookup = null;

EditableGridManager.UpdateValue = function(returnColumnName, associatedColumnName, gridClientID, radioButtonsGroupName, updateColumnName) {

    //May return null/element/array
    var radioButtons = document.forms[0][radioButtonsGroupName];
    var selectedRadioButton = null;

    if (radioButtons) {
        if (radioButtons.checked) {
            selectedRadioButton = radioButtons;
        }
        else {
            for (var i = 0; i < radioButtons.length; i++) {
                if (radioButtons[i].checked) {
                    selectedRadioButton = radioButtons[i];
                }
            }
        }
    }

    if (selectedRadioButton) {
        var el = selectedRadioButton;

        var grid = $find(gridClientID);
        while (el && (el.parentNode.parentNode.parentNode != grid.get_element() && el.parentNode.parentNode.parentNode != grid._gridDataDiv && !Array.contains(grid.get_detailTables(), $find(el.parentNode.parentNode.id)))) {
            el = el.parentNode;
        }

        if (el) {
            var rowID = el.id.split("__")[1];
        }

        var rowKeyValues = grid._clientKeyValues[rowID];

        EditableGridManager.LookupManagerForLookup.UpdateValue(returnColumnName, associatedColumnName, rowKeyValues, updateColumnName);
    }
    else {
        alert("Please select an option.");
    }

    return false;
}

EditableGridManager.CloseWindow = function() {
    EditableGridManager.LookupManagerForLookup.CloseWindow();
}

//We hijack this function to allow to add validators based on validator templates
EditableGridManager.UpdateValidatorOnLoad = function() {
    if (window.ValidatorOnLoad) {
        //We override the validator methods since they have been optimized and ValidatorOnLoad does some processing to copy
        ValidatorOnLoad = EditableGridManager.ValidatorOnLoad;
        ValidatorHookupEvent = EditableGridManager.ValidatorHookupEvent;
    }
}

EditableGridManager.ValidatorTemplate = function(validatorTemplateElem) {
    this.validatorTemplateElem = validatorTemplateElem;
    this.validatorsInfo = null;
    this.validatedElements = null;

    this.validatorProperties = null;

    this.insertValidatorInfo = null;

    this.validationGroupValidatorInfoDictionary = null;

    this.validatorValidationGroupDictionary = new Object();
}

EditableGridManager.ValidatorTemplate.prototype = {
    dispose: function() {
        for (var property in this.validatorValidationGroupDictionary) {
            this.validatorValidationGroupDictionary[property] = null;
        }

        Array.clear(this.get_validatorInfoArray());

        this.validatorTemplateElem = null;
    },

    get_RelatedGrid: function() {
        return this.validatorTemplateElem.RelatedGrid;
    },

    get_validatorInfoArray: function() {
        return window[String.format("{0}_Validators", this.validatorTemplateElem.id)];
    },

    get_ValidatorInfo: function() {
        if (this.validatorsInfo == null) {
            this.validatorsInfo = new Array();
            var validatorInfoArray = this.get_validatorInfoArray();

            Array.forEach(validatorInfoArray, validatorInfoBuilderLoop, this);
        }

        function validatorInfoBuilderLoop(validatorInfo) {
            var validatorInfo = new EditableGridManager.ValidatorInfo(this.validatorTemplateElem.ValidatorSuffix, this.validatorTemplateElem.ControlToValideSuffix, validatorInfo.id, validatorInfo.vg);

            if (validatorInfo.isInsertRowValidator()) {
                this.insertValidatorInfo = validatorInfo;
            }

            Array.add(this.validatorsInfo, validatorInfo);
        }

        return this.validatorsInfo;
    },

    get_ValidatedElementsValidatorInfoDictionary: function() {
        if (this.validatedElements == null) {
            this.validatedElements = new Object();

            Array.forEach(this.get_ValidatorInfo(), validatorInfoLoop, this);
        }

        function validatorInfoLoop(validatorInfo) {
            this.validatedElements[validatorInfo.get_ControlToValidateID()] = validatorInfo;
        }

        return this.validatedElements;
    },

    get_ValidatorValidationGroupDictionary: function() {
        return this.validatorValidationGroupDictionary;
    },

    get_ValidationGroupValidatorInfoDictionary: function() {
        if (this.validationGroupValidatorInfoDictionary == null) {
            this.validationGroupValidatorInfoDictionary = new Object();

            Array.forEach(this.get_ValidatorInfo(), buildDictionary, this);
        }

        function buildDictionary(validatorInfo) {
            this.validationGroupValidatorInfoDictionary[validatorInfo.get_ValidationGroup()] = validatorInfo;
        }

        return this.validationGroupValidatorInfoDictionary;
    },

    RegisterValidatorProperties: function(validatorElem, validationInfo) {
        if (this.validatorProperties == null) {
            this.validatorProperties = new Array();

            for (var validatorElementProperty in this.validatorTemplateElem) {
                if (validatorElementProperty != "RelatedGrid" && validatorElementProperty != "ValidatorSuffix" && validatorElementProperty != "dispose" && validatorElementProperty != "ControlToValideSuffix" && !(validatorElementProperty in validatorElem)) {
                    Array.add(this.validatorProperties, validatorElementProperty);
                }

                if (validatorElementProperty == "evaluationfunction") {
                    this.validatorTemplateElem.evaluationfunction = window[this.validatorTemplateElem.evaluationfunction];
                }
            }
        }

        //Copy the properties over from the template
        for (var i = 0; i < this.validatorProperties.length; i++) {
            var propertyToUpdate = this.validatorProperties[i];
            validatorElem[propertyToUpdate] = this.validatorTemplateElem[propertyToUpdate];
        }

        validatorElem.controltovalidate = validationInfo.get_ControlToValidateID();
        validatorElem.validationGroup = validationInfo.get_ValidationGroup();

        this.validatorValidationGroupDictionary[validatorElem.validationGroup] = validatorElem;
    },

    GetElementValidationInfo: function(elemID) {
        var validationInfoDictionary = this.get_ValidatedElementsValidatorInfoDictionary();
        if (elemID in validationInfoDictionary) {
            return validationInfoDictionary[elemID];
        }
        else {
            return null;
        }
    },

    SetupValidation: function(validatorInfo) {
        var validatorElem = $get(validatorInfo.get_ValidatorID());

        this.RegisterValidatorProperties(validatorElem, validatorInfo);

        ValidatorHookupControlID(validatorElem.controltovalidate, validatorElem);

        validatorInfo.set_ValidatedElementHasBeenSetup(true);
    }
}

EditableGridManager.ValidatorInfo = function(validatorTemplateSuffix, validatorTemplateControlToValideSuffix, validatorIDPrefix, validationGroup) {
    this.validatorID = validatorIDPrefix + validatorTemplateSuffix;
    this.controlToValidate = validatorIDPrefix + validatorTemplateControlToValideSuffix;
    this.validationGroup = validationGroup;

    this.validatedElementHasBeenSetup = false;
}

EditableGridManager.ValidatorInfo.prototype = {
    get_ValidatorID: function() {
        return this.validatorID;
    },

    get_ControlToValidateID: function() {
        return this.controlToValidate;
    },

    get_ValidationGroup: function() {
        return this.validationGroup;
    },

    get_ValidatedElementHasBeenSetup: function() {
        return this.validatedElementHasBeenSetup;
    },

    set_ValidatedElementHasBeenSetup: function(value) {
        this.validatedElementHasBeenSetup = value;
    },

    isInsertRowValidator: function() {
        return this.validationGroup.split("_")[1] == "-1";
    }
}


//We add validators to the client that act as a template. The validator contains information on what elements actually need to have validation
//applied to them and this is where we handle creating those validators.
EditableGridManager.ValidatorOnLoad = function() {
    if (window.Page_Validators) {
        var validatorsToRemove = new Array();
        //var validatorsToAdd = new Array();

        Array.forEach(Page_Validators, validatorsLoop);

        //We no longer need the template validators so we remove them to prevent validation done on templates.
        Array.forEach(validatorsToRemove, validatorsToRemoveLoop);
    }

    ValidationSummaryOnSubmit = MyValidationSummaryOnSubmit;

    function validatorsLoop(validator) {
        if (validator.ValidatorTemplate) {
            //Removing the validator now will mess up looping through the validators therefore we add them to array to be removed after looping.
            Array.add(validatorsToRemove, validator);
            if (validator.RelatedGrid) {
                $egm.getInstance().GetGrid(validator.RelatedGrid).RegisterValidatorTemplate(validator);
            }
        }
    }

    function validatorsToRemoveLoop(validator) {
        Array.remove(Page_Validators, validator);
    }

    //This is where the old ValidatorOnLoad code begins
    if (typeof (Page_Validators) == "undefined")
        return;
    var i, val;
    for (i = 0; i < Page_Validators.length; i++) {
        val = Page_Validators[i];
        if (typeof (val.evaluationfunction) == "string") {
            val.evaluationfunction = window[val.evaluationfunction];
        }
        if (typeof (val.isvalid) == "string") {
            if (val.isvalid == "False") {
                val.isvalid = false;
                Page_IsValid = false;
            }
            else {
                val.isvalid = true;
            }
        } else {
            val.isvalid = true;
        }
        if (typeof (val.enabled) == "string") {
            val.enabled = (val.enabled != "False");
        }
        if (typeof (val.controltovalidate) == "string") {
            ValidatorHookupControlID(val.controltovalidate, val);
        }
        if (typeof (val.controlhookup) == "string") {
            ValidatorHookupControlID(val.controlhookup, val);
        }
    }
    Page_ValidationActive = true;
}

//optimize ValidatorHookupEvent
EditableGridManager.ValidatorHookupEvent = function(control, eventType, functionPrefix) {
    var ev;
    ev = control[eventType];
    if (typeof (ev) == "function") {
        ev = ev.toString();
        ev = ev.substring(ev.indexOf("{") + 1, ev.lastIndexOf("}"));
    }
    else {
        ev = "";
    }

    var func;
    if (navigator.appName.toLowerCase().indexOf('explorer') > -1) {
        func = new Function(functionPrefix + " " + ev);
    }
    else {
        func = new Function("event", functionPrefix + " " + ev);
    }
    control[eventType] = func;
}

/*click---------------------------------------------------------------------------------------*/
//This funciton didn't allow for nested elements. We modified it to so that the row change will happen on nested elements too.
EditableGridManager._click = function(e) {
    var el = (e.target) ? e.target : e.srcElement;
    if (!el.tagName) {
        return;
    }
    if (el.tagName.toLowerCase() == "label" && el.htmlFor) {
        return;
    }
    if (this._owner.ClientSettings.Selecting && this._owner.ClientSettings.Selecting.AllowRowSelect) {
        var _147 = (el.tagName.toLowerCase() == "input" && el.type.toLowerCase() == "checkbox" && (el.id && el.id.indexOf("SelectCheckBox") != -1));
        /* Note: This code was making it so that if the user clicked inside a text box in the editable grid,
        * the row that grid was on would not get selected. By removing this code it seems to now work without
        * added code to go up to the parent level. I'm not sure the reasoning behdind it but we still need to
        * override for this case. */

        /* Previous Code */
//        if ((el.tagName.toLowerCase() == "input" && !_147) || el.tagName.toLowerCase() == "select" || el.tagName.toLowerCase() == "option" || el.tagName.toLowerCase() == "button" || el.tagName.toLowerCase() == "a" || el.tagName.toLowerCase() == "textarea" || el.tagName.toLowerCase() == "img") {
//            return;
//        }
        /* End Previous Code */
        if (el.tagName.toLowerCase() != "tr") {
            el = Telerik.Web.UI.Grid.GetFirstParentByTagName(el, "tr");
        }
        var g = el;
        var h = false;
        while (el && Telerik.Web.UI.Grid.IsChildOf(el, this._owner.get_element())) {
            if (el.id && el.id.split("__").length == 2) {
                h = true;
                break
            }
            el = Telerik.Web.UI.Grid.GetFirstParentByTagName(el.parentNode, "tr")
        }
        if (!h) {
            el = g
        }
        if (el && (el.parentNode.parentNode.parentNode == this._owner.get_element() || el.parentNode.parentNode.parentNode == this._owner._gridDataDiv || Array.contains(this._owner.get_detailTables(), $find(el.parentNode.parentNode.id))) && el.id && el.id.split("__").length == 2) {
            if (this._owner.get_allowMultiRowSelection()) {
                if (e.shiftKey && this._owner._selectedItemsInternal[0]) {
                    var _148 = $get(this._owner._selectedItemsInternal[0].id);
                    if (_148) {
                        if (_148.rowIndex > el.rowIndex) {
                            for (var i = el.rowIndex; i < _148.rowIndex + 1; i++) {
                                var tr = _148.parentNode.parentNode.rows[i];
                                if (tr.id) {
                                    this._selectRowInternal(tr, e, true, false, true);
                                }
                            }
                        }
                        if (_148.rowIndex < el.rowIndex) {
                            for (var i = _148.rowIndex; i < el.rowIndex + 1; i++) {
                                var tr = _148.parentNode.parentNode.rows[i];
                                if (tr.id) {
                                    this._selectRowInternal(tr, e, true, false, true);
                                }
                            }
                        }
                    }
                    return;
                }
                this._selectRowInternal(el, e, _147, true, true);
            }
            else {
                this._selectRowInternal(el, e, false, false, true);
            }
        }
    }
    if (this._owner.ClientSettings && this._owner.ClientSettings.EnablePostBackOnRowClick && el) {
        if (el && el.tagName.toLowerCase() != "tr") {
            el = Telerik.Web.UI.Grid.GetFirstParentByTagName(el, "tr");
        }
        if (el && el.id != "" && el.id.split("__").length == 2) {
            var _14b = el.id.split("__")[1];
            var _14c = this._owner.ClientSettings.PostBackFunction;
            _14c = _14c.replace("{0}", this._owner.UniqueID);
            _14c = _14c.replace("{1}", "RowClick;" + _14b);
            setTimeout(function() { eval(_14c); }, 100);
        }
    }
}

Array.AddArrayToArray = function(arrayToAddToName, arrayToAdd) {
    if (typeof (window[arrayToAddToName]) === "undefined") {
        window[arrayToAddToName] = arrayToAdd;
    }
    else {
        Array.addRange(window[arrayToAddToName], arrayToAdd);
    }
}

MyValidationSummaryOnSubmit = function(validationGroup) {
    if (typeof (Page_ValidationSummaries) == "undefined")
        return;
    var summary, sums, s;
    for (sums = 0; sums < Page_ValidationSummaries.length; sums++) {
        summary = Page_ValidationSummaries[sums];
        summary.style.display = "none";

        var summaryContainer = summary.parentNode;
        while (summaryContainer) {
            if (summaryContainer.className == "ValidationSummary") {
                summaryContainer.style.display = "block";
                break;
            }

            summaryContainer = summaryContainer.parentNode;
        }

        if (summaryContainer) {
            summaryContainer.style.display = "none";
        }

        if (!Page_IsValid && IsValidationGroupMatch(summary, validationGroup)) {
            var i;
            if (summary.showsummary != "False") {
                summary.style.display = "";
                if (typeof (summary.displaymode) != "string") {
                    summary.displaymode = "BulletList";
                }
                switch (summary.displaymode) {
                    case "List":
                        headerSep = "<br>";
                        first = "";
                        pre = "";
                        post = "<br>";
                        end = "";
                        break;
                    case "BulletList":
                    default:
                        headerSep = "";
                        first = "<ul>";
                        pre = "<li>";
                        post = "</li>";
                        end = "</ul>";
                        break;
                    case "SingleParagraph":
                        headerSep = " ";
                        first = "";
                        pre = "";
                        post = " ";
                        end = "<br>";
                        break;
                }
                s = "";
                if (typeof (summary.headertext) == "string") {
                    s += summary.headertext + headerSep;
                }
                s += first;
                for (i = 0; i < Page_Validators.length; i++) {
                    if (!Page_Validators[i].isvalid && typeof (Page_Validators[i].errormessage) == "string") {
                        s += pre + Page_Validators[i].errormessage + post;

                    }
                }
                s += end;
                summary.innerHTML = s;

                if (summaryContainer) {
                    summaryContainer.style.display = "block";
                }
                
                window.scrollTo(0, 0);
            }
            if (summary.showmessagebox == "True") {
                s = "";
                if (typeof (summary.headertext) == "string") {
                    s += summary.headertext + "\r\n";
                }
                var lastValIndex = Page_Validators.length - 1;
                for (i = 0; i <= lastValIndex; i++) {
                    if (!Page_Validators[i].isvalid && typeof (Page_Validators[i].errormessage) == "string") {
                        switch (summary.displaymode) {
                            case "List":
                                s += Page_Validators[i].errormessage;
                                if (i < lastValIndex) {
                                    s += "\r\n";
                                }
                                break;
                            case "BulletList":
                            default:
                                s += "- " + Page_Validators[i].errormessage;
                                if (i < lastValIndex) {
                                    s += "\r\n";
                                }
                                break;
                            case "SingleParagraph":
                                s += Page_Validators[i].errormessage + " ";
                                break;
                        }
                    }
                }
                alert(s);
            }
        }
    }
}

// Open a link into a new window (may be a new tab depending on the browser)
function openLinkForceNewWindow(hyperlink) {
    var url = hyperlink.href.toString();

    // Don't popup a window if MAILTO as it would popup a blank page plus the email window
    if (url.toUpperCase().startsWith("MAILTO:"))
        return true; // return true to allow <A> to do its normal thing

    try {
        var newwindow = window.open(url, "weblink", "location=1,statusbar=1,menubar=1,toolbar=1,directories=1,resizable=1,scrollbars=1");

        // If for some reason the window is null, just return true
        if (window == null)
            return true;  // return true to allow <A> to do its normal thing

        return false;
    }
    catch (err) {
        // On errors default to the normal behavior of the <A> tag
        return true;  // return true to allow <A> to do its normal thing
    }
}

// Disables the enter key globally under certain conditions.  Prevents unexpected
// postbacks and default button clicks
function disableEnterKey(e) {
    var key;
    if (window.event)
        key = window.event.keyCode; //IE
    else
        key = e.which; //firefox

    // Disable for single line Text input fields only
    if (document.activeElement != null && document.activeElement.type == "text")
        return (key != 13);

    return true;
}

