// --------------------------------------------------------------------------------
// DOM (Document Object Model) access helpers 
// --------------------------------------------------------------------------------

function GetElementById(id) {
    //If id is an ASP.Net server control id, get it's corresponding clientId
    id = GetControlClientId(id);
    if (document.getElementById) {
        return document.getElementById(id);
    }
    else if (document.all) {
        return document.all[id];
    }
    else if (document.layers) {
        return document.layers[id];
    }
    return null;
}

function GetElementByName(name) {
    return document.forms[0].elements[name];
}

function GetElementByTagName(element, tagName) {
    while ((element != null) && (element.tagName != tagName)) {
        if (element.parentElement) {
            element = element.parentElement;
        }
        else {
            element = element.parentNode;
        }
    }
    return element;
}

function GetElementByClassName(element, name) {
    while ((element != null) && (element.className != name)) {
        element = element.parentElement;
    }
    return element;
}

function GetAttribute(element, name) {
    if (element.getAttribute) {
        return element.getAttribute(name);
    }
    else if (document.all) {
        return document.all[element.id][name];
    }
    else if (document.layers) {
        return document.layers[element.id][name];
    }
    return null;
}

// --------------------------------------------------------------------------------
// ASP.NET helpers
// --------------------------------------------------------------------------------

function GetContainerId(clientId, elementId) {
    elementId = "_" + elementId;
    return clientId.substr(0, clientId.indexOf(elementId));
}

function GetPropertiesArray(typeName, clientId, groupName) {
    var name = "";
    if (typeof groupName === "undefined") {
        groupName = "Properties";
    }
    if (typeof clientId === "undefined") {
        name = typeName + "_" + groupName;
    }
    else {
        name = typeName + "_" + clientId + "_" + groupName;
    }
    return window[name];
}

// N.B. Kept for backward compatibility
function DoPostBack(eventTarget, eventArgument) {
    Page_PostBack(eventTarget, eventArgument);
}

// do post-back, must be called after call to Page_ClientValidate()
function Page_PostBack(eventTarget, eventArgument) {
    // post-back if page validation is disabled or page is valid
    if (typeof Page_ClientValidate !== "function" || Page_IsValid) {
        if (typeof __doPostBack === "function") {
            __doPostBack(eventTarget, eventArgument);
        }
    }
}

function Page_SetSubmitOnce(value) {
    __pageSubmitOnce = value;
}

// must be called from onsubmit	event, after any page validation calls.
function Page_SubmitBlocked() {
    // check for existence of __pageSubmitted	(our custom	global variable)
    if (typeof __pageSubmitOnce !== "undefined" && __pageSubmitOnce) {
        if (typeof __pageSubmitted !== "undefined") {
            return true;
        }
        // flag page as submitted
        __pageSubmitted = true;
        return false;
    }
    return false;
}

function Page_UnblockSubmit() {
    // flag page as submittable
    delete __pageSubmitted;
    return false;
}

// Given a unique serverId, returns the corresponding clientId.
// Requires the control to be registered using PageUtility.RegisterControlClientIds().
// If the id isn't specified in the ServerIds[] array, then the passed id is returned.
// If a server control sits within a naming container, the clientid of the control will be different to the server side id.
// This method looks to see if the clientid was regsitered server side.
function GetControlClientId(serverId) {
    if (typeof ASPNETControlServerIds !== "undefined") {
        var serverIdIndex = ArrayIndexOf(ASPNETControlServerIds, serverId);
        if (serverIdIndex != -1) {
            return ASPNETControlClientIds[serverIdIndex];
        }
    }
    return serverId;
}

// --------------------------------------------------------------------------------
// Array helpers
// --------------------------------------------------------------------------------

function ArrayIndexOf(array, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i] === value) {
            return i;
        }
    }
    return -1;
}

// Array.splice()
function ArrayRemoveAt(array, index) {
    var tmp = new Array();
    for (var i = 0; i < array.length; i++) {
        if (i !== index) {
            tmp[tmp.length] = array[i];
        }
    }
    return tmp;
}

// --------------------------------------------------------------------------------
// Event helpers
// --------------------------------------------------------------------------------

function GetEventHandler(functionName, clientId, key) {
    var id = GetControlClientId(clientId);
    var fn = eval(functionName);
    var context = key;
    return function(ev) {
        if (!ev) ev = window.event;
        fn(ev, id, this, context);
    };
}

function RaiseEvent(element, eventType) {
    // raise change event
    if (document.createEventObject) {
        var ev = document.createEventObject();
        element.fireEvent(eventType, ev);
    } else if (document.createEvent) {
        var ev = document.createEvent("HTMLEvents");
        ev.initEvent(eventType.slice(2), true, true);
        element.dispatchEvent(ev);
    } else {
        try {
            element[eventType]();
        } catch (err) { }
    }
}

function CancelEvent(ev) {
    if (!ev) {
        ev = window.event;
    }
    if (ev.stopPropagation) {
        ev.stopPropagation();
        ev.preventDefault();
    }
    else {
        ev.cancelBubble = true;
        ev.returnValue = false;
    }
    return false;
}

function AttachEventHandler(element, eventType, handler) {
    if (element.addEventListener) {
        element.addEventListener(eventType.slice(2), handler, false);
    }
    else {
        element.attachEvent(eventType, handler);
    }
}

// Inserts a handler before existing handlers.
// onclick = use for button controls that causes client-side validation.
// onchange = use for input controls that has client-side validation.
function InsertEventHandler(element, eventType, handler) {
    var existing = element[eventType];
    if (typeof existing === "function") {
        var combined = function(ev) {
            if (!ev) ev = window.event;
            handler(ev);
            existing(ev);
        };
        element[eventType] = combined;
    }
    else {
        element[eventType] = handler;
    }
}

// Appends a click handler after existing handlers.
// onclick = use for button controls that causes client-side validation.
// onchange = use for input controls that has client-side validation.
function AppendEventHandler(element, eventType, handler) {
    var existing = element[eventType];
    if (typeof existing === "function") {
        var combined = function(ev) {
            if (!ev) ev = window.event;
            existing(ev);
            handler(ev);
        }
        element[eventType] = combined;
    }
    else {
        element[eventType] = handler;
    }
}

// For backward compatibility
function AddClickHandler(element, handler) {
    AppendEventHandler(element, "onclick", handler);
}

// For backward compatibility
function AddChangeHandler(element, handler) {
    AppendEventHandler(element, "onchange", handler);
}

function DefaultButtonHandler(ev, buttonId) {
    if (!ev) ev = window.event;
    if (buttonId.length > 0) {
        // disable default button activation
        if (buttonId === "Disable") {
            return CancelEvent(ev);
        }
        var button = GetElementById(buttonId);
        if (button != null) {
            var eventTarget = GetElementByName("__EVENTTARGET");
            if (eventTarget != null) {
                eventTarget.value = buttonId;
            }
            // cause onclick event
            button.click();
            // check if page validates
            if (typeof Page_ClientValidate === "function" && !Page_IsValid) {
                return CancelEvent(ev);
            }
        }
    }
    return true;
}

// use in onkeydown handlers to check for keys that generates "printable" characters.
function IsPrintableKey(keyCode) {
    // space
    if (keyCode == 32) return true;
    // 0-9
    if (keyCode > 47 && keyCode < 58) return true;
    // A-Z
    if (keyCode > 64 && keyCode < 91) return true;
    // keypad
    if (keyCode > 95 && keyCode < 112) return true;
    // symbols
    if (keyCode > 185 && keyCode < 193) return true;
    // symbols
    if (keyCode > 218 && keyCode < 224) return true;
    return false;
} 
