﻿

/**
* Copyright (c)2005-2007 Matt Kruse (javascripttoolbox.com)
* 
* Dual licensed under the MIT and GPL licenses. 
* This basically means you can use this code however you want for
* free, but don't claim to have written it yourself!
* Donations always accepted: http://www.JavascriptToolbox.com/donate/
* 
* Please do not link to the .js files on javascripttoolbox.com from
* your site. Copy the files locally to your server instead.
* 
*/
/* ******************************************************************* */
/*   UTIL FUNCTIONS                                                    */
/* ******************************************************************* */
var Util = { '$VERSION': 1.07 };

// Util functions - these are GLOBAL so they
// look like built-in functions.


/****************************************************************/

// Check whether string s is empty.
function isEmpty(s) {
    return ((s == null) ||
				(s.length == 0) ||
				(s == undefined) ||
				(s == '')
			);
}

function isNull(val) {
    return isEmpty(val);
}

/****************************************************************/

function isWhitespace(s) {
    // Is s empty?
    if (isEmpty(s)) return true;

    // is s a string?
    if (!isString(s)) return false;

    if (s.match(/[\s\r\n\t]/)) return true;
    return false;
}


// Determine if an object is an array
function isArray(o) {
    return (o != null && typeof (o) == "object" && typeof (o.length) == "number" && (o.length == 0 || defined(o[0])));
};
// Determine if an object is a string
function isString(o) {
    return (o != null && typeof (o) == "string");
};
// Determine if an object is an Object
function isObject(o) {
    return (o != null && typeof (o) == "object" && defined(o.constructor) && o.constructor == Object && !defined(o.nodeName));
};

// Determine if a reference is defined
function defined(o) {
    return (typeof (o) != "undefined");
};

// Iterate over an array, object, or list of items and run code against each item
// Similar functionality to Perl's map() function
function forEach(func) {
    var results = [];
    if (typeof (func) == "string") {
        func = new Function('$_', func);
    }

    for (var i = 1; i < arguments.length; i++) {
        var o = arguments[i];
        if (isArray(o)) {
            for (var j = 0; j < o.length; j++) {
                results[results.length] = func(o[j]);
            }
        }
        else {
            if (isObject(o)) {
                for (var j in o) {
                    results[results.length] = func(o[j]);
                }
            }
            else {
                results[results.length] = func(o);
            }
        }
    }
    return results;
};

// Set default values in an object if they are undefined
function setDefaultValues(o, values) {
    if (!defined(o) || o == null) {
        o = {};
    }
    if (!defined(values) || values == null) {
        return o;
    }
    for (var val in values) {
        if (!defined(o[val])) {
            o[val] = values[val];
        }
    }
    return o;
};

/* ******************************************************************* */
/*   DEFAULT OBJECT PROTOTYPE ENHANCEMENTS                             */
/* ******************************************************************* */
// These functions add useful functionality to built-in objects
Array.prototype.contains = function(o) {
    var l = this.length;
    if (!l) { return false; }
    for (var i = 0; i < l; i++) {
        if (o == this[i]) {
            return true;
        }
    }
};

/* ******************************************************************* */
/*   DOM FUNCTIONS                                                     */
/* ******************************************************************* */
var DOM = (function() {
    var dom = {};

    // Get a parent tag with a given nodename
    dom.getParentByTagName = function(o, tagNames) {
        if (o == null) { return null; }
        if (isArray(tagNames)) {
            tagNames = map("return $_.toUpperCase()", tagNames);
            while (o = o.parentNode) {
                if (o.nodeName && tagNames.contains(o.nodeName)) {
                    return o;
                }
            }
        }
        else {
            tagNames = tagNames.toUpperCase();
            while (o = o.parentNode) {
                if (o.nodeName && tagNames == o.nodeName) {
                    return o;
                }
            }
        }
        return null;
    };

    // Remove a node from its parent
    dom.removeNode = function(o) {
        if (o != null && o.parentNode && o.parentNode.removeChild) {
            // First remove all attributes which are func references, to avoid memory leaks
            for (var i in o) {
                if (typeof (o[i]) == "function") {
                    o[i] = null;
                }
            }
            o.parentNode.removeChild(o);
            return true;
        }
        return false;
    };

    // Get the outer width in pixels of an object, including borders, padding, and margin
    dom.getOuterWidth = function(o) {
        if (defined(o.offsetWidth)) {
            return o.offsetWidth;
        }
        return null;
    };

    // Get the outer height in pixels of an object, including borders, padding, and margin
    dom.getOuterHeight = function(o) {
        if (defined(o.offsetHeight)) {
            return o.offsetHeight;
        }
        return null;
    };

    // Resolve an item, an array of items, or an object of items
    dom.resolve = function() {
        var results = new Array();
        var i, j, o;
        for (var i = 0; i < arguments.length; i++) {
            var o = arguments[i];
            if (o == null) {
                if (arguments.length == 1) {
                    return null;
                }
                results[results.length] = null;
            }
            else
                if (typeof (o) == 'string') {
                if (document.getElementById) {
                    o = document.getElementById(o);
                }
                else
                    if (document.all) {
                    o = document.all[o];
                }
                if (arguments.length == 1) {
                    return o;
                }
                results[results.length] = o;
            }
            else
                if (isArray(o)) {
                for (j = 0; j < o.length; j++) {
                    results[results.length] = o[j];
                }
            }
            else
                if (isObject(o)) {
                for (j in o) {
                    results[results.length] = o[j];
                }
            }
            else
                if (arguments.length == 1) {
                return o;
            }
            else {
                results[results.length] = o;
            }
        }
        return results;
    };


    dom.$ = dom.resolve;

    return dom;
})();

/* ******************************************************************* */
/*   CSS FUNCTIONS                                                     */
/* ******************************************************************* */
var CSS = (function() {
    var css = {};

    // Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
    css.rgb2hex = function(rgbString) {
        if (typeof (rgbString) != "string" || !defined(rgbString.match)) { return null; }
        var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
        if (result == null) { return rgbString; }
        var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
        var hex = "";
        var digits = "0123456789abcdef";
        while (rgb != 0) {
            hex = digits.charAt(rgb & 0xf) + hex;
            rgb >>>= 4;
        }
        while (hex.length < 6) { hex = '0' + hex; }
        return "#" + hex;
    };

    // Convert hyphen style names like border-width to camel case like borderWidth
    css.hyphen2camel = function(property) {
        if (!defined(property) || property == null) { return null; }
        if (property.indexOf("-") < 0) { return property; }
        var str = "";
        var c = null;
        var l = property.length;
        for (var i = 0; i < l; i++) {
            c = property.charAt(i);
            str += (c != "-") ? c : property.charAt(++i).toUpperCase();
        }
        return str;
    };

    // Determine if an object or class string contains a given class.
    css.hasClass = function(obj, className) {
        if (!defined(obj) || obj == null || !RegExp) { return false; }
        var re = new RegExp("(^|\\s)" + className + "(\\s|$)");
        if (typeof (obj) == "string") {
            return re.test(obj);
        }
        else if (typeof (obj) == "object" && obj.className) {
            return re.test(obj.className);
        }
        return false;
    };

    // Add a class to an object
    css.addClass = function(obj, className) {
        if (typeof (obj) != "object" || obj == null || !defined(obj.className)) { return false; }
        if (obj.className == null || obj.className == '') {
            obj.className = className;
            return true;
        }
        if (css.hasClass(obj, className)) { return true; }
        obj.className = obj.className + " " + className;
        return true;
    };

    // Remove a class from an object
    css.removeClass = function(obj, className) {
        if (typeof (obj) != "object" || obj == null || !defined(obj.className) || obj.className == null) { return false; }
        if (!css.hasClass(obj, className)) { return false; }
        var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
        obj.className = obj.className.replace(re, ' ');
        return true;
    };

    // Fully replace a class with a new one
    css.replaceClass = function(obj, className, newClassName) {
        if (typeof (obj) != "object" || obj == null || !defined(obj.className) || obj.className == null) { return false; }
        css.removeClass(obj, className);
        css.addClass(obj, newClassName);
        return true;
    };

    // Get the currently-applied style of an object
    css.getStyle = function(o, property) {
        if (o == null) { return null; }
        var val = null;
        var camelProperty = css.hyphen2camel(property);
        // Handle "float" property as a special case
        if (property == "float") {
            val = css.getStyle(o, "cssFloat");
            if (val == null) {
                val = css.getStyle(o, "styleFloat");
            }
        }
        else if (o.currentStyle && defined(o.currentStyle[camelProperty])) {
            val = o.currentStyle[camelProperty];
        }
        else if (window.getComputedStyle) {
            val = window.getComputedStyle(o, null).getPropertyValue(property);
        }
        else if (o.style && defined(o.style[camelProperty])) {
            val = o.style[camelProperty];
        }
        // For color values, make the value consistent across browsers
        // Convert rgb() colors back to hex for consistency
        if (/^\s*rgb\s*\(/.test(val)) {
            val = css.rgb2hex(val);
        }
        // Lowercase all #hex values
        if (/^#/.test(val)) {
            val = val.toLowerCase();
        }
        return val;
    };
    css.get = css.getStyle;

    // Set a style on an object
    css.setStyle = function(o, property, value) {
        if (o == null || !defined(o.style) || !defined(property) || property == null || !defined(value)) { return false; }
        if (property == "float") {
            o.style["cssFloat"] = value;
            o.style["styleFloat"] = value;
        }
        else if (property == "opacity") {
            o.style['-moz-opacity'] = value;
            o.style['-khtml-opacity'] = value;
            o.style.opacity = value;
            if (defined(o.style.filter)) {
                o.style.filter = "alpha(opacity=" + value * 100 + ")";
            }
        }
        else {
            o.style[css.hyphen2camel(property)] = value;
        }
        return true;
    };
    css.set = css.setStyle;

    // Get a unique ID which doesn't already exist on the page
    css.uniqueIdNumber = 1000;
    css.createId = function(o) {
        if (defined(o) && o != null && defined(o.id) && o.id != null && o.id != "") {
            return o.id;
        }
        var id = null;
        while (id == null || document.getElementById(id) != null) {
            id = "ID_" + (css.uniqueIdNumber++);
        }
        if (defined(o) && o != null && (!defined(o.id) || o.id == "")) {
            o.id = id;
        }
        return id;
    };

    return css;
})();

/* ******************************************************************* */
/*   EVENT FUNCTIONS                                                   */
/* ******************************************************************* */

var Event = (function() {
    var ev = {};

    // Resolve an event using IE's window.event if necessary
    // --------------------------------------------------------------------
    ev.resolve = function(e) {
        if (!defined(e) && defined(window.event)) {
            e = window.event;
        }
        return e;
    };

    // Add an event handler to a function
    // Note: Don't use 'this' within functions added using this method, since
    // the attachEvent and addEventListener models differ.
    // --------------------------------------------------------------------
    ev.add = function(attachTo, eventName, fn, capture) {
        if (isString(attachTo)) {
            attachTo = DOM.resolve(attachTo);
        }

        if (attachTo != null) {
            if (attachTo.addEventListener) {
                attachTo.addEventListener(eventName, fn, capture);
                return true;
            }
            else {
                if (attachTo.attachEvent) {
                    attachTo.attachEvent("on" + eventName, fn);
                    return true;
                }
            }
        }
        else {
            debugger;
            alert('sorry, I can not find an object named "' + attachTo + '"');
        }
        return false;
    };

    // Get the mouse position of an event
    // --------------------------------------------------------------------
    // PageX/Y, where they exist, are more reliable than ClientX/Y because 
    // of some browser bugs in Opera/Safari
    ev.getMouseX = function(e) {
        e = ev.resolve(e);
        if (defined(e.pageX)) {
            return e.pageX;
        }
        if (defined(e.clientX)) {
            return e.clientX + Screen.getScrollLeft();
        }
        return null;
    };
    ev.getMouseY = function(e) {
        e = ev.resolve(e);
        if (defined(e.pageY)) {
            return e.pageY;
        }
        if (defined(e.clientY)) {
            return e.clientY + Screen.getScrollTop();
        }
        return null;
    };

    // Stop the event from bubbling up to parent elements.
    // Two method names map to the same function
    // --------------------------------------------------------------------
    ev.cancelBubble = function(e) {
        e = ev.resolve(e);
        if (typeof (e.stopPropagation) == "function") { e.stopPropagation(); }
        if (defined(e.cancelBubble)) { e.cancelBubble = true; }
    };
    ev.stopPropagation = ev.cancelBubble;

    // Prevent the default handling of the event to occur
    // --------------------------------------------------------------------
    ev.preventDefault = function(e) {
        e = ev.resolve(e);
        if (typeof (e.preventDefault) == "function") { e.preventDefault(); }
        if (defined(e.returnValue)) { e.returnValue = false; }
    };

    return ev;
})();

/* ******************************************************************* */
/*   SCREEN FUNCTIONS                                                  */
/* ******************************************************************* */
var Screen = (function() {
    var screen = {};

    // Get a reference to the body
    // --------------------------------------------------------------------
    screen.getBody = function() {
        if (document.body) {
            return document.body;
        }
        if (document.getElementsByTagName) {
            var bodies = document.getElementsByTagName("BODY");
            if (bodies != null && bodies.length > 0) {
                return bodies[0];
            }
        }
        return null;
    };

    // Get the amount that the main document has scrolled from top
    // --------------------------------------------------------------------
    screen.getScrollTop = function() {
        if (document.documentElement && defined(document.documentElement.scrollTop) && document.documentElement.scrollTop > 0) {
            return document.documentElement.scrollTop;
        }
        if (document.body && defined(document.body.scrollTop)) {
            return document.body.scrollTop;
        }
        return null;
    };

    // Get the amount that the main document has scrolled from left
    // --------------------------------------------------------------------
    screen.getScrollLeft = function() {
        if (document.documentElement && defined(document.documentElement.scrollLeft) && document.documentElement.scrollLeft > 0) {
            return document.documentElement.scrollLeft;
        }
        if (document.body && defined(document.body.scrollLeft)) {
            return document.body.scrollLeft;
        }
        return null;
    };

    // Util function to default a bad number to 0
    // --------------------------------------------------------------------
    screen.zero = function(n) {
        return (!defined(n) || isNaN(n)) ? 0 : n;
    };

    // Get the width of the entire document
    // --------------------------------------------------------------------
    screen.getDocumentWidth = function() {
        var width = 0;
        var body = screen.getBody();
        if (document.documentElement && (!document.compatMode || document.compatMode == "CSS1Compat")) {
            var rightMargin = parseInt(CSS.get(body, 'marginRight'), 10) || 0;
            var leftMargin = parseInt(CSS.get(body, 'marginLeft'), 10) || 0;
            width = Math.max(body.offsetWidth + leftMargin + rightMargin, document.documentElement.clientWidth);
        }
        else {
            width = Math.max(body.clientWidth, body.scrollWidth);
        }
        if (isNaN(width) || width == 0) {
            width = screen.zero(self.innerWidth);
        }
        return width;
    };

    // Get the height of the entire document
    // --------------------------------------------------------------------
    screen.getDocumentHeight = function() {
        var body = screen.getBody();
        var innerHeight = (defined(self.innerHeight) && !isNaN(self.innerHeight)) ? self.innerHeight : 0;
        if (document.documentElement && (!document.compatMode || document.compatMode == "CSS1Compat")) {
            var topMargin = parseInt(CSS.get(body, 'marginTop'), 10) || 0;
            var bottomMargin = parseInt(CSS.get(body, 'marginBottom'), 10) || 0;
            return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, screen.zero(self.innerHeight));
        }
        return Math.max(body.scrollHeight, body.clientHeight, screen.zero(self.innerHeight));
    };

    // Get the width of the viewport (viewable area) in the browser window
    // --------------------------------------------------------------------
    screen.getViewportWidth = function() {
        if (document.documentElement && (!document.compatMode || document.compatMode == "CSS1Compat")) {
            return document.documentElement.clientWidth;
        }
        else if (document.compatMode && document.body) {
            return document.body.clientWidth;
        }
        return screen.zero(self.innerWidth);
    };

    // Get the height of the viewport (viewable area) in the browser window
    // --------------------------------------------------------------------
    screen.getViewportHeight = function() {
        if (!window.opera && document.documentElement && (!document.compatMode || document.compatMode == "CSS1Compat")) {
            return document.documentElement.clientHeight;
        }
        else if (document.compatMode && !window.opera && document.body) {
            return document.body.clientHeight;
        }
        return screen.zero(self.innerHeight);
    };

    return screen;
})(); var Sort = (function() {
    var sort = {};
    sort.AlphaNumeric = function(a, b) {
        if (a == b) { return 0; }
        if (a < b) { return -1; }
        return 1;
    };

    sort.Default = sort.AlphaNumeric;

    sort.NumericConversion = function(val) {
        if (typeof (val) != "number") {
            if (typeof (val) == "string") {
                val = parseFloat(val.replace(/,/g, ''));
                if (isNaN(val) || val == null) { val = 0; }
            }
            else {
                val = 0;
            }
        }
        return val;
    };

    sort.Numeric = function(a, b) {
        return sort.NumericConversion(a) - sort.NumericConversion(b);
    };

    sort.IgnoreCaseConversion = function(val) {
        if (val == null) { val = ""; }
        return ("" + val).toLowerCase();
    };

    sort.IgnoreCase = function(a, b) {
        return sort.AlphaNumeric(sort.IgnoreCaseConversion(a), sort.IgnoreCaseConversion(b));
    };

    sort.CurrencyConversion = function(val) {
        if (typeof (val) == "string") {
            val = val.replace(/^[^\d\.]/, '');
        }
        return sort.NumericConversion(val);
    };

    sort.Currency = function(a, b) {
        return sort.Numeric(sort.CurrencyConversion(a), sort.CurrencyConversion(b));
    };

    sort.DateConversion = function(val) {
        // inner util function to parse date formats
        function getdate(str) {
            // inner util function to convert 2-digit years to 4
            function fixYear(yr) {
                yr = +yr;
                if (yr < 50) { yr += 2000; }
                else if (yr < 100) { yr += 1900; }
                return yr;
            };
            var ret;
            // YYYY-MM-DD
            if (ret = str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
                return (fixYear(ret[1]) * 10000) + (ret[2] * 100) + (+ret[3]);
            }
            // MM/DD/YY[YY] or MM-DD-YY[YY]
            if (ret = str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
                return (fixYear(ret[3]) * 10000) + (ret[1] * 100) + (+ret[2]);
            }
            return 99999999; // So non-parsed dates will be last, not first
        };
        return getdate(val);
    };

    sort.Date = function(a, b) {
        return sort.Numeric(sort.DateConversion(a), sort.DateConversion(b));
    };

    return sort;
})();

function toggleVisible(obj) {
    if (isString(obj))
        obj = DOM.resolve(obj);

    if (obj)	// make sure we got it
    {
        if (defined(obj.style)) {
            var hidn = false;
            if (defined(obj.style.display))
                if (obj.style.display == 'none')
                hidn = true;

            if (defined(obj.style.visibility))
                if (obj.style.visibility == 'hidden')
                hidn = true;

            if (hidn) show(obj);
            else hide(obj);
        }
    }
    else {
        debugger;

        alert('sorry, I can not find an object named "' + obj + '"');
    }
}

function hide(obj) {
    if (isString(obj))
        obj = DOM.resolve(obj);

    if (obj)	// make sure we got it
    {
        if (defined(obj.style)) {
            if (defined(obj.style.display))
                obj.style.display = 'none'; 	// turn it off
            if (defined(obj.style.visibility))
                obj.style.visibility = 'hidden';
        }
    }
    else {
        debugger;
        alert('sorry, I can not find an object named "' + obj + '"');
    }
}

function show(obj) {
    if (isString(obj))
        obj = DOM.resolve(obj);
    if (obj)	// make sure we got it
    {
        if (defined(obj.style)) {
            if (defined(obj.style.display))
                obj.style.display = 'block'; 	// turn it off
            if (defined(obj.style.visibility))
                obj.style.visibility = 'visible';
        }
    }
    else {
        debugger;
        alert('sorry, I can not find an object named "' + obj + '"');
    }
}

function SetCookie(name, value, expires, path, domain, secure) {
    // set time, it's in milliseconds
    var today = new Date();
    today.setTime(today.getTime());

    /*
    if the expires variable is set, make the correct 
    expires time, the current script below will set 
    it for x number of days, to make it for hours, 
    delete * 24, for minutes, delete * 60 * 24
    */
    if (expires) {
        expires = expires * 1000 * 60 * 60 * 24;
    }
    var expires_date = new Date(today.getTime() + (expires));

    document.cookie = name + "=" + escape(value) +
	((expires) ? ";expires=" + expires_date.toGMTString() : "") +
	((path) ? ";path=" + path : "") +
	((domain) ? ";domain=" + domain : "") +
	((secure) ? ";secure" : "");
}

// this function gets the cookie, if it exists
function GetCookie(name) {
    var start = document.cookie.indexOf(name + "=");
    var len = start + name.length + 1;
    if ((!start) &&
	(name != document.cookie.substring(0, name.length))) {
        return null;
    }
    if (start == -1) return null;
    var end = document.cookie.indexOf(";", len);
    if (end == -1) end = document.cookie.length;
    return unescape(document.cookie.substring(len, end));
}

// this deletes the cookie when called
function DeleteCookie(name, path, domain) {
    if (GetCookie(name)) document.cookie = name + "=" +
	((path) ? ";path=" + path : "") +
	((domain) ? ";domain=" + domain : "") +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

function LaunchWindow(url, title, width, height) {
    var params = new String();
    params = 'width=' + width;
    params += ',height=' + height;
    if (!window) alert("error!");
    else {
        window.open(url);
    }
}

function Swap(left, right) {
    var temp = left;
    left = right;
    right = temp;
}



function ShowHideDiv(id) {
    if (document.getElementById(id)) {
        obj = document.getElementById(id);
        if (obj.style.display == "none") {
            obj.style.display = "";
        }
        else {
            obj.style.display = "none";
        }
    }
}