/* Common.js */

/* ----------------------------------- Event Functions */

window.onload = function() {
	if (typeof (_onload) == "function")
		_onload();
}

function preventDefault(e) {
    if (!e)
        var e = window.event;

    if (typeof (e.preventDefault) != "undefined")
        e.preventDefault();
}

//usage:
//  addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
// - or - 
//  addLoadEvent(function() {
//    /* more code to run on page load */
//  });
function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    } else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
        }
    }
}



/* ---------------------------------- Bilingual Control Functions */

var _lang = "en";

function gotoPage(prefix) {
    getLanguage();

	location.href = (prefix == "index" && _lang == "en")
	    ? "index.shtml"
	    : prefix + "_" + _lang + ".shtml";
}

function changeLanguage(lang) {
	if (lang == "") lang = "en";
	createCookie("lang", lang, 365);
	setLanguage(lang);
	
	var s = document.URL.lastIndexOf("/");
	var e = document.URL.lastIndexOf("_");
	var thisPage = ( e > 0 ) 
	    ? document.URL.substring(s + 1, e)
	    : "index";

	gotoPage(thisPage);
}

function getLanguage() {
    var lang = readCookie("lang");
    if (lang == "") lang = "en";

    _lang = lang;
}

function setLanguage(lang) { 
	if (lang == "") lang = "en";

	document.getElementById("lang_en").className = "";
	document.getElementById("lang_es").className = "";
	if (document.getElementById("lang_" + lang))
	    document.getElementById("lang_" + lang).className = "sel";

	_lang = lang;
}

/* ----------------------------------- URL Parameter Function */

function fGetParameter(name) {
    var url = document.URL.replace("?", "&");
    var prefix = name.toLowerCase() + "=";
    var begin = url.toLowerCase().indexOf("&" + prefix);

    if (begin == -1)
        return "";

    var end = url.indexOf("&", begin + 1);
    if (end == -1)
        end = url.length;

    return fURLDecode(url.substring(begin + prefix.length + 1, end));
}

function fURLEncode(clearString) {
    var output = "";
    var x = 0;
    clearString = clearString.toString();
    var regex = /(^[a-zA-Z0-9_.]*)/;
    while (x < clearString.length) {
        var match = regex.exec(clearString.substr(x));
        if (match != null && match.length > 1 && match[1] != "") {
            output += match[1];
            x += match[1].length;
        } else {
            if (clearString[x] == " ")
                output += "+";
            else {
                var charCode = clearString.charCodeAt(x);
                var hexVal = charCode.toString(16);
                output += "%" + (hexVal.length < 2 ? "0" : "") + hexVal.toUpperCase();
            }
            x++;
        }
    }
    return output;
}

function fURLDecode(encodedString) {
    var output = encodedString;
    var binVal, thisString;
    var myregexp = /(%[^%]{2})/;
    while ((match = myregexp.exec(output)) != null
             && match.length > 1
             && match[1] != "") {
        binVal = parseInt(match[1].substr(1), 16);
        thisString = String.fromCharCode(binVal);
        output = output.replace(match[1], thisString);
    }
    return output.replace(/[+]/g, " ");
}

/* ----------------------------------- Cookie Functions */

function createCookie(name,value,days)
{
	var expires;
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		expires = "; expires="+date.toGMTString();
	}
	else expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name)
{
	createCookie(name,"",-1);
}

/* ----------------------------------- Email Related Functions */

function fMaskAddress(id, domain, idOnly) {
    var toName = id + "@" + domain
    var s = "";
    s += '<a href='
    s += '"mailto:' + id + '@' + domain + '"'
    s += ' title="Click here to open a new email message to ' + toName + '")'
    s += '>'
    s += id
    if (!idOnly)
    	s += "&nbsp;@&nbsp;" + domain
    s += '</a>'

    document.write(s);
}

/* ----------------------------------- Element Position Functions */

// find the absolute X offset of an element 
function findPosX(obj) 
{
    var curleft = 0;
    if (obj.offsetParent) 
    {
        while (1) 
        {
            curleft+=obj.offsetLeft;
            if (!obj.offsetParent) 
            {
                break;
            }
            obj=obj.offsetParent;
        }
    } 
    else if (obj.x) 
    {
        curleft+=obj.x;
    }
    return curleft;
}

// find the absolute Y offset of an element 
function findPosY(obj) 
{
    var curtop = 0;
    if (obj.offsetParent) 
    {
        while (1) 
        {
            curtop+=obj.offsetTop;
            if (!obj.offsetParent) 
            {
                break;
            }
            obj=obj.offsetParent;
        }
    } 
    else if (obj.y) 
    {
        curtop+=obj.y;
    }
    return curtop;
}

/* ----------------------------------- Browser Detection Functions */

function fDetectOS() {
    // returns "win" for pc and "mac" for macintosh
    return navigator.platform.substring(0, 3).toLowerCase();
}

function fDetectBrowser() {
    // returns "msie", "firefox", "safari" or "unknown"
    return navigator.userAgent.toLowerCase().indexOf("firefox") > 0 ? "firefox"
        : navigator.userAgent.toLowerCase().indexOf("safari") > 0 ? "safari"
        : navigator.userAgent.toLowerCase().indexOf("msie") > 0 ? "msie"
        : "unknown";
}

function fDetectPlugin(name) {
    // Check if browser has plugins
    if (navigator.plugins.length == 0) 
        return false;

    // Check for plugin and return appropriate value
    var isFound = false;
    for (var i in navigator.plugins) {
        var plugin = navigator.plugins[i];
        if (typeof (plugin.name) == "undefined")
            break;

        if (plugin.name.substring(0, name.length) == name) {
            isFound = true;
            break;
        }
    }

    return isFound; 
}

/* ----------------------------------- String Functions */

String.prototype.HTMLEncode = function() {
    var div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
}

String.prototype.HTMLDecode = function() {
    if (this==null) return; 
    var out = ""; 
    var l = this.length; 
    for (var i=0; i<l; i++) 
    { 
        var ch = this.charAt(i); 
        
        if (ch == '&') 
        { 
            var semicolonIndex = this.indexOf(';', i+1); 
            
        if (semicolonIndex > 0) 
        { 
                var entity = this.substring(i + 1, semicolonIndex); 
                if (entity.length > 1 && entity.charAt(0) == '#') 
                { 
                    if (entity.charAt(1) == 'x' || entity.charAt(1) == 'X') 
                        ch = String.fromCharCode(eval('0'+entity.substring(1))); 
                    else 
                        ch = String.fromCharCode(eval(entity.substring(1))); 
                } 
              else 
                { 
                    switch (entity) 
                    { 
                        case 'quot': ch = String.fromCharCode(0x0022); break; 
                        case 'amp': ch = String.fromCharCode(0x0026); break; 
                        case 'lt': ch = String.fromCharCode(0x003c); break; 
                        case 'gt': ch = String.fromCharCode(0x003e); break; 
                        case 'nbsp': ch = String.fromCharCode(0x00a0); break; 
                        case 'iexcl': ch = String.fromCharCode(0x00a1); break; 
                        case 'cent': ch = String.fromCharCode(0x00a2); break; 
                        case 'pound': ch = String.fromCharCode(0x00a3); break; 
                        case 'curren': ch = String.fromCharCode(0x00a4); break; 
                        case 'yen': ch = String.fromCharCode(0x00a5); break; 
                        case 'brvbar': ch = String.fromCharCode(0x00a6); break; 
                        case 'sect': ch = String.fromCharCode(0x00a7); break; 
                        case 'uml': ch = String.fromCharCode(0x00a8); break; 
                        case 'copy': ch = String.fromCharCode(0x00a9); break; 
                        case 'ordf': ch = String.fromCharCode(0x00aa); break; 
                        case 'laquo': ch = String.fromCharCode(0x00ab); break; 
                        case 'not': ch = String.fromCharCode(0x00ac); break; 
                        case 'shy': ch = String.fromCharCode(0x00ad); break; 
                        case 'reg': ch = String.fromCharCode(0x00ae); break; 
                        case 'macr': ch = String.fromCharCode(0x00af); break; 
                        case 'deg': ch = String.fromCharCode(0x00b0); break; 
                        case 'plusmn': ch = String.fromCharCode(0x00b1); break; 
                        case 'sup2': ch = String.fromCharCode(0x00b2); break; 
                        case 'sup3': ch = String.fromCharCode(0x00b3); break; 
                        case 'acute': ch = String.fromCharCode(0x00b4); break; 
                        case 'micro': ch = String.fromCharCode(0x00b5); break; 
                        case 'para': ch = String.fromCharCode(0x00b6); break; 
                        case 'middot': ch = String.fromCharCode(0x00b7); break; 
                        case 'cedil': ch = String.fromCharCode(0x00b8); break; 
                        case 'sup1': ch = String.fromCharCode(0x00b9); break; 
                        case 'ordm': ch = String.fromCharCode(0x00ba); break; 
                        case 'raquo': ch = String.fromCharCode(0x00bb); break; 
                        case 'frac14': ch = String.fromCharCode(0x00bc); break; 
                        case 'frac12': ch = String.fromCharCode(0x00bd); break; 
                        case 'frac34': ch = String.fromCharCode(0x00be); break; 
                        case 'iquest': ch = String.fromCharCode(0x00bf); break; 
                        case 'Agrave': ch = String.fromCharCode(0x00c0); break; 
                        case 'Aacute': ch = String.fromCharCode(0x00c1); break; 
                        case 'Acirc': ch = String.fromCharCode(0x00c2); break; 
                        case 'Atilde': ch = String.fromCharCode(0x00c3); break; 
                        case 'Auml': ch = String.fromCharCode(0x00c4); break; 
                        case 'Aring': ch = String.fromCharCode(0x00c5); break; 
                        case 'AElig': ch = String.fromCharCode(0x00c6); break; 
                        case 'Ccedil': ch = String.fromCharCode(0x00c7); break; 
                        case 'Egrave': ch = String.fromCharCode(0x00c8); break; 
                        case 'Eacute': ch = String.fromCharCode(0x00c9); break; 
                        case 'Ecirc': ch = String.fromCharCode(0x00ca); break; 
                        case 'Euml': ch = String.fromCharCode(0x00cb); break; 
                        case 'Igrave': ch = String.fromCharCode(0x00cc); break; 
                        case 'Iacute': ch = String.fromCharCode(0x00cd); break; 
                        case 'Icirc': ch = String.fromCharCode(0x00ce ); break; 
                        case 'Iuml': ch = String.fromCharCode(0x00cf); break; 
                        case 'ETH': ch = String.fromCharCode(0x00d0); break; 
                        case 'Ntilde': ch = String.fromCharCode(0x00d1); break; 
                        case 'Ograve': ch = String.fromCharCode(0x00d2); break; 
                        case 'Oacute': ch = String.fromCharCode(0x00d3); break; 
                        case 'Ocirc': ch = String.fromCharCode(0x00d4); break; 
                        case 'Otilde': ch = String.fromCharCode(0x00d5); break; 
                        case 'Ouml': ch = String.fromCharCode(0x00d6); break; 
                        case 'times': ch = String.fromCharCode(0x00d7); break; 
                        case 'Oslash': ch = String.fromCharCode(0x00d8); break; 
                        case 'Ugrave': ch = String.fromCharCode(0x00d9); break; 
                        case 'Uacute': ch = String.fromCharCode(0x00da); break; 
                        case 'Ucirc': ch = String.fromCharCode(0x00db); break; 
                        case 'Uuml': ch = String.fromCharCode(0x00dc); break; 
                        case 'Yacute': ch = String.fromCharCode(0x00dd); break; 
                        case 'THORN': ch = String.fromCharCode(0x00de); break; 
                        case 'szlig': ch = String.fromCharCode(0x00df); break; 
                        case 'agrave': ch = String.fromCharCode(0x00e0); break; 
                        case 'aacute': ch = String.fromCharCode(0x00e1); break; 
                        case 'acirc': ch = String.fromCharCode(0x00e2); break; 
                        case 'atilde': ch = String.fromCharCode(0x00e3); break; 
                        case 'auml': ch = String.fromCharCode(0x00e4); break; 
                        case 'aring': ch = String.fromCharCode(0x00e5); break; 
                        case 'aelig': ch = String.fromCharCode(0x00e6); break; 
                        case 'ccedil': ch = String.fromCharCode(0x00e7); break; 
                        case 'egrave': ch = String.fromCharCode(0x00e8); break; 
                        case 'eacute': ch = String.fromCharCode(0x00e9); break; 
                        case 'ecirc': ch = String.fromCharCode(0x00ea); break; 
                        case 'euml': ch = String.fromCharCode(0x00eb); break; 
                        case 'igrave': ch = String.fromCharCode(0x00ec); break; 
                        case 'iacute': ch = String.fromCharCode(0x00ed); break; 
                        case 'icirc': ch = String.fromCharCode(0x00ee); break; 
                        case 'iuml': ch = String.fromCharCode(0x00ef); break; 
                        case 'eth': ch = String.fromCharCode(0x00f0); break; 
                        case 'ntilde': ch = String.fromCharCode(0x00f1); break; 
                        case 'ograve': ch = String.fromCharCode(0x00f2); break; 
                        case 'oacute': ch = String.fromCharCode(0x00f3); break; 
                        case 'ocirc': ch = String.fromCharCode(0x00f4); break; 
                        case 'otilde': ch = String.fromCharCode(0x00f5); break; 
                        case 'ouml': ch = String.fromCharCode(0x00f6); break; 
                        case 'divide': ch = String.fromCharCode(0x00f7); break; 
                        case 'oslash': ch = String.fromCharCode(0x00f8); break; 
                        case 'ugrave': ch = String.fromCharCode(0x00f9); break; 
                        case 'uacute': ch = String.fromCharCode(0x00fa); break; 
                        case 'ucirc': ch = String.fromCharCode(0x00fb); break; 
                        case 'uuml': ch = String.fromCharCode(0x00fc); break; 
                        case 'yacute': ch = String.fromCharCode(0x00fd); break; 
                        case 'thorn': ch = String.fromCharCode(0x00fe); break; 
                        case 'yuml': ch = String.fromCharCode(0x00ff); break; 
                        case 'OElig': ch = String.fromCharCode(0x0152); break; 
                        case 'oelig': ch = String.fromCharCode(0x0153); break; 
                        case 'Scaron': ch = String.fromCharCode(0x0160); break; 
                        case 'scaron': ch = String.fromCharCode(0x0161); break; 
                        case 'Yuml': ch = String.fromCharCode(0x0178); break; 
                        case 'fnof': ch = String.fromCharCode(0x0192); break; 
                        case 'circ': ch = String.fromCharCode(0x02c6); break; 
                        case 'tilde': ch = String.fromCharCode(0x02dc); break; 
                        case 'Alpha': ch = String.fromCharCode(0x0391); break; 
                        case 'Beta': ch = String.fromCharCode(0x0392); break; 
                        case 'Gamma': ch = String.fromCharCode(0x0393); break; 
                        case 'Delta': ch = String.fromCharCode(0x0394); break; 
                        case 'Epsilon': ch = String.fromCharCode(0x0395); break; 
                        case 'Zeta': ch = String.fromCharCode(0x0396); break; 
                        case 'Eta': ch = String.fromCharCode(0x0397); break; 
                        case 'Theta': ch = String.fromCharCode(0x0398); break; 
                        case 'Iota': ch = String.fromCharCode(0x0399); break; 
                        case 'Kappa': ch = String.fromCharCode(0x039a); break; 
                        case 'Lambda': ch = String.fromCharCode(0x039b); break; 
                        case 'Mu': ch = String.fromCharCode(0x039c); break; 
                        case 'Nu': ch = String.fromCharCode(0x039d); break; 
                        case 'Xi': ch = String.fromCharCode(0x039e); break; 
                        case 'Omicron': ch = String.fromCharCode(0x039f); break; 
                        case 'Pi': ch = String.fromCharCode(0x03a0); break; 
                        case ' Rho ': ch = String.fromCharCode(0x03a1); break; 
                        case 'Sigma': ch = String.fromCharCode(0x03a3); break; 
                        case 'Tau': ch = String.fromCharCode(0x03a4); break; 
                        case 'Upsilon': ch = String.fromCharCode(0x03a5); break; 
                        case 'Phi': ch = String.fromCharCode(0x03a6); break; 
                        case 'Chi': ch = String.fromCharCode(0x03a7); break; 
                        case 'Psi': ch = String.fromCharCode(0x03a8); break; 
                        case 'Omega': ch = String.fromCharCode(0x03a9); break; 
                        case 'alpha': ch = String.fromCharCode(0x03b1); break; 
                        case 'beta': ch = String.fromCharCode(0x03b2); break; 
                        case 'gamma': ch = String.fromCharCode(0x03b3); break; 
                        case 'delta': ch = String.fromCharCode(0x03b4); break; 
                        case 'epsilon': ch = String.fromCharCode(0x03b5); break; 
                        case 'zeta': ch = String.fromCharCode(0x03b6); break; 
                        case 'eta': ch = String.fromCharCode(0x03b7); break; 
                        case 'theta': ch = String.fromCharCode(0x03b8); break; 
                        case 'iota': ch = String.fromCharCode(0x03b9); break; 
                        case 'kappa': ch = String.fromCharCode(0x03ba); break; 
                        case 'lambda': ch = String.fromCharCode(0x03bb); break; 
                        case 'mu': ch = String.fromCharCode(0x03bc); break; 
                        case 'nu': ch = String.fromCharCode(0x03bd); break; 
                        case 'xi': ch = String.fromCharCode(0x03be); break; 
                        case 'omicron': ch = String.fromCharCode(0x03bf); break; 
                        case 'pi': ch = String.fromCharCode(0x03c0); break; 
                        case 'rho': ch = String.fromCharCode(0x03c1); break; 
                        case 'sigmaf': ch = String.fromCharCode(0x03c2); break; 
                        case 'sigma': ch = String.fromCharCode(0x03c3); break; 
                        case 'tau': ch = String.fromCharCode(0x03c4); break; 
                        case 'upsilon': ch = String.fromCharCode(0x03c5); break; 
                        case 'phi': ch = String.fromCharCode(0x03c6); break; 
                        case 'chi': ch = String.fromCharCode(0x03c7); break; 
                        case 'psi': ch = String.fromCharCode(0x03c8); break; 
                        case 'omega': ch = String.fromCharCode(0x03c9); break; 
                        case 'thetasym': ch = String.fromCharCode(0x03d1); break; 
                        case 'upsih': ch = String.fromCharCode(0x03d2); break; 
                        case 'piv': ch = String.fromCharCode(0x03d6); break; 
                        case 'ensp': ch = String.fromCharCode(0x2002); break; 
                        case 'emsp': ch = String.fromCharCode(0x2003); break; 
                        case 'thinsp': ch = String.fromCharCode(0x2009); break; 
                        case 'zwnj': ch = String.fromCharCode(0x200c); break; 
                        case 'zwj': ch = String.fromCharCode(0x200d); break; 
                        case 'lrm': ch = String.fromCharCode(0x200e); break; 
                        case 'rlm': ch = String.fromCharCode(0x200f); break; 
                        case 'ndash': ch = String.fromCharCode(0x2013); break; 
                        case 'mdash': ch = String.fromCharCode(0x2014); break; 
                        case 'lsquo': ch = String.fromCharCode(0x2018); break; 
                        case 'rsquo': ch = String.fromCharCode(0x2019); break; 
                        case 'sbquo': ch = String.fromCharCode(0x201a); break; 
                        case 'ldquo': ch = String.fromCharCode(0x201c); break; 
                        case 'rdquo': ch = String.fromCharCode(0x201d); break; 
                        case 'bdquo': ch = String.fromCharCode(0x201e); break; 
                        case 'dagger': ch = String.fromCharCode(0x2020); break; 
                        case 'Dagger': ch = String.fromCharCode(0x2021); break; 
                        case 'bull': ch = String.fromCharCode(0x2022); break; 
                        case 'hellip': ch = String.fromCharCode(0x2026); break; 
                        case 'permil': ch = String.fromCharCode(0x2030); break; 
                        case 'prime': ch = String.fromCharCode(0x2032); break; 
                        case 'Prime': ch = String.fromCharCode(0x2033); break; 
                        case 'lsaquo': ch = String.fromCharCode(0x2039); break; 
                        case 'rsaquo': ch = String.fromCharCode(0x203a); break; 
                        case 'oline': ch = String.fromCharCode(0x203e); break; 
                        case 'frasl': ch = String.fromCharCode(0x2044); break; 
                        case 'euro': ch = String.fromCharCode(0x20ac); break; 
                        case 'image': ch = String.fromCharCode(0x2111); break; 
                        case 'weierp': ch = String.fromCharCode(0x2118); break; 
                        case 'real': ch = String.fromCharCode(0x211c); break; 
                        case 'trade': ch = String.fromCharCode(0x2122); break; 
                        case 'alefsym': ch = String.fromCharCode(0x2135); break; 
                        case 'larr': ch = String.fromCharCode(0x2190); break; 
                        case 'uarr': ch = String.fromCharCode(0x2191); break; 
                        case 'rarr': ch = String.fromCharCode(0x2192); break; 
                        case 'darr': ch = String.fromCharCode(0x2193); break; 
                        case 'harr': ch = String.fromCharCode(0x2194); break; 
                        case 'crarr': ch = String.fromCharCode(0x21b5); break; 
                        case 'lArr': ch = String.fromCharCode(0x21d0); break; 
                        case 'uArr': ch = String.fromCharCode(0x21d1); break; 
                        case 'rArr': ch = String.fromCharCode(0x21d2); break; 
                        case 'dArr': ch = String.fromCharCode(0x21d3); break; 
                        case 'hArr': ch = String.fromCharCode(0x21d4); break; 
                        case 'forall': ch = String.fromCharCode(0x2200); break; 
                        case 'part': ch = String.fromCharCode(0x2202); break; 
                        case 'exist': ch = String.fromCharCode(0x2203); break; 
                        case 'empty': ch = String.fromCharCode(0x2205); break; 
                        case 'nabla': ch = String.fromCharCode(0x2207); break; 
                        case 'isin': ch = String.fromCharCode(0x2208); break; 
                        case 'notin': ch = String.fromCharCode(0x2209); break; 
                        case 'ni': ch = String.fromCharCode(0x220b); break; 
                        case 'prod': ch = String.fromCharCode(0x220f); break; 
                        case 'sum': ch = String.fromCharCode(0x2211); break; 
                        case 'minus': ch = String.fromCharCode(0x2212); break; 
                        case 'lowast': ch = String.fromCharCode(0x2217); break; 
                        case 'radic': ch = String.fromCharCode(0x221a); break; 
                        case 'prop': ch = String.fromCharCode(0x221d); break; 
                        case 'infin': ch = String.fromCharCode(0x221e); break; 
                        case 'ang': ch = String.fromCharCode(0x2220); break; 
                        case 'and': ch = String.fromCharCode(0x2227); break; 
                        case 'or': ch = String.fromCharCode(0x2228); break; 
                        case 'cap': ch = String.fromCharCode(0x2229); break; 
                        case 'cup': ch = String.fromCharCode(0x222a); break; 
                        case 'int': ch = String.fromCharCode(0x222b); break; 
                        case 'there4': ch = String.fromCharCode(0x2234); break; 
                        case 'sim': ch = String.fromCharCode(0x223c); break; 
                        case 'cong': ch = String.fromCharCode(0x2245); break; 
                        case 'asymp': ch = String.fromCharCode(0x2248); break; 
                        case 'ne': ch = String.fromCharCode(0x2260); break; 
                        case 'equiv': ch = String.fromCharCode(0x2261); break; 
                        case 'le': ch = String.fromCharCode(0x2264); break; 
                        case 'ge': ch = String.fromCharCode(0x2265); break; 
                        case 'sub': ch = String.fromCharCode(0x2282); break; 
                        case 'sup': ch = String.fromCharCode(0x2283); break; 
                        case 'nsub': ch = String.fromCharCode(0x2284); break; 
                        case 'sube': ch = String.fromCharCode(0x2286); break; 
                        case 'supe': ch = String.fromCharCode(0x2287); break; 
                        case 'oplus': ch = String.fromCharCode(0x2295); break; 
                        case 'otimes': ch = String.fromCharCode(0x2297); break; 
                        case 'perp': ch = String.fromCharCode(0x22a5); break; 
                        case 'sdot': ch = String.fromCharCode(0x22c5); break; 
                        case 'lceil': ch = String.fromCharCode(0x2308); break; 
                        case 'rceil': ch = String.fromCharCode(0x2309); break; 
                        case 'lfloor': ch = String.fromCharCode(0x230a); break; 
                        case 'rfloor': ch = String.fromCharCode(0x230b); break; 
                        case 'lang': ch = String.fromCharCode(0x2329); break; 
                        case 'rang': ch = String.fromCharCode(0x232a); break; 
                        case 'loz': ch = String.fromCharCode(0x25ca); break; 
                        case 'spades': ch = String.fromCharCode(0x2660); break; 
                        case 'clubs': ch = String.fromCharCode(0x2663); break; 
                        case 'hearts': ch = String.fromCharCode(0x2665); break; 
                        case 'diams': ch = String.fromCharCode(0x2666); break; 
                        default: ch = ''; break; 
                    } 
                } 
                i = semicolonIndex; 
            } 
        } 
        
        out += ch; 
    } 
  
    return out; 
}

String.prototype.StripHTML = function() {
    return this.replace(/(<([^>]+)>)/ig,""); 
}

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}

String.prototype.fulltrim = function() {
    return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, "").replace(/\s+/g, " ");
}

//String.prototype.isValidDate = function() {
//    var IsoDateRe = new RegExp("^([0-9]{2})/([0-9]{2})/([0-9]{4})$");
//    
//    var matches = IsoDateRe.exec(this);
//    if (!matches) return false;

//    var composedDate = new Date(matches[3], (matches[1] - 1), matches[2]);

//    return ((composedDate.getMonth() == (matches[1] - 1)) &&
//          (composedDate.getDate() == matches[2]) &&
//          (composedDate.getFullYear() == matches[3]));

//}

function fZeroPad(theVal, width) {
    theVal = parseInt(theVal);
    return "0000000000".substring(0, width - 1).substring(0, width - theVal.toString().length) + theVal.toString();
}

/* ----------------------------------- Date Functions */

Date.prototype.dateDiff = function(theDate) {

    //create a date object from the date string,   
    //and a date object that represents now   
    var date = theDate;
    var now = this;

    //the current assumption is that now is earlier than the input date   
    //to give the difference from now to the later date   
    //but if that's not the case, invert the values   
    //so that you'll get the difference from the earlier date to now   
//    if (now >= date) {
//        var tmp = date;
//        date = now;
//        now = tmp;
//    }

    //create an object of differences, beginning with a TotalMinutes value   
    //which is the total difference in minutes   
    //we can use this to work out if a future time has been reached, or a past time is not in the past   
    //and to modify behavior when something has just started or is about to end
    var between = { 'TotalMinutes': (date.getTime() - now.getTime()) / 60000 };    

    //add individual differences to the between object
    between.TotalHours = (date.getTime() - now.getTime()) / 60000 / 60;
    between.TotalDays = (date.getTime() - now.getTime()) / 60000 / 60 / 24;
    between.year = date.getFullYear() - now.getFullYear();
    between.month = date.getMonth() - now.getMonth();
    between.day = date.getDate() - now.getDate();
    between.hour = date.getHours() - now.getHours();
    between.minute = date.getMinutes() - now.getMinutes();
    between.second = date.getSeconds() - now.getSeconds();
    between.millisecond = date.getMilliseconds() - now.getMilliseconds();

    //convert negative second difference to minute difference   
    if (between.second < 0) {
        between.minute--;
        between.second += 60;
    }

    //convert negative minute difference to hour difference   
    if (between.minute < 0) {
        between.hour--;
        between.minute += 60;
    }

    //convert negative hour difference to day difference   
    if (between.hour < 0) {
        between.day--;
        between.hour += 24;
    }

    //convert negative day difference to month difference   
    //this one is more complicated because months aren't all the same length   
    if (between.day < 0) {
        between.month--;
        var ynum = date.getFullYear();

        var mlengths = [
            31,
            (ynum % 4 == 0 && ynum % 100 != 0 || ynum % 400 == 0) ? 29 : 28,
            31, 30, 31, 30, 31, 31, 30, 31, 30, 31
            ];

        var mnum = date.getMonth() - 1;
        if (mnum < 0) { mnum += 12; }

        between.day += mlengths[mnum];
    }

    //convert negative month difference to year difference   
    if (between.month < 0) {
        between.year--;
        between.month += 12;
    }

    //return the between object   
    return between;
}


// example use:new Date().dateAdd("m", 2)
Date.prototype.dateAdd = function(p_Interval, p_Number){ 


    var thing = new String();     
     
    //in the spirt of VB we'll make this function non-case sensitive 
    //and convert the charcters for the coder. 
    p_Interval = p_Interval.toLowerCase(); 
     
    if(isNaN(p_Number)){ 
     
        //Only accepts numbers 
        //throws an error so that the coder can see why he effed up     
        throw "The second parameter must be a number. \n You passed: " + p_Number; 
        return false; 
    } 

    p_Number = new Number(p_Number); 
    switch(p_Interval.toLowerCase()){ 
        case "yyyy": {// year 
            this.setFullYear(this.getFullYear() + p_Number); 
            break; 
        } 
        case "q": {        // quarter 
            this.setMonth(this.getMonth() + (p_Number*3)); 
            break; 
        } 
        case "m": {        // month 
            this.setMonth(this.getMonth() + p_Number); 
            break; 
        } 
        case "y":        // day of year 
        case "d":        // day 
        case "w": {        // weekday 
            this.setDate(this.getDate() + p_Number); 
            break; 
        } 
        case "ww": {    // week of year 
            this.setDate(this.getDate() + (p_Number*7)); 
            break; 
        } 
        case "h": {        // hour 
            this.setHours(this.getHours() + p_Number); 
            break; 
        } 
        case "n": {        // minute 
            this.setMinutes(this.getMinutes() + p_Number); 
            break; 
        } 
        case "s": {        // second 
            this.setSeconds(this.getSeconds() + p_Number); 
            break; 
        } 
        case "ms": {        // second 
            this.setMilliseconds(this.getMilliseconds() + p_Number); 
            break; 
        } 
        default: { 
         
            //throws an error so that the coder can see why he effed up and 
            //a list of elegible letters. 
            throw    "The first parameter must be a string from this list: \n" + 
                    "yyyy, q, m, y, d, w, ww, h, n, s, or ms. You passed: " + p_Interval; 
            return false; 
        } 
    } 
    return this; 
} 


// example use:new Date().toLocalFormat("dd/MM/yyyy hh:mm:ss ap")
Date.prototype.toLocalFormat = function(theFormat) {
    var isMilitaryTime = true;

    if (_lang == "")
    {
        try { 
	_lang = readCookie("lang");
	if (_lang == "") _lang = "en";
        } 
        catch(e) {}
    }

    // arrays of "friendly" names
    var aDays = _lang == "en"
		? { 0: "Sunday", 1: "Monday", 2: "Tuesday", 3: "Wednesday", 4: "Thursday", 5: "Friday", 6: "Saturday" }
		: { 0: "Domingo", 1: "Lunes", 2: "Martes", 3: "Miércoles", 4: "Jueves", 5: "Viernes", 6: "Sábado" }
    var aMonths = _lang == "en"
		? { 0: "January", 1: "February", 2: "March", 3: "April", 4: "May", 5: "June", 6: "July", 7: "August", 8: "September", 9: "October", 10: "November", 11: "December" }
		: { 0: "Enero", 1: "Febrero", 2: "Marzo", 3: "Abril", 4: "Especes", 5: "Junio", 6: "Julio", 7: "Agosto", 8: "Septiembre", 9: "Octubre", 10: "Noviembre", 11: "Diciembre" };

    var aVars =
	{
	    MM: this.getMonth() + 1,
	    MN: aMonths[this.getMonth()],
	    Mn: aMonths[this.getMonth()].substring(0, 3),
	    dd: parseInt(this.getDate()),
	    Dd: parseInt(this.getDate()),
	    DN: aDays[this.getDay()],
	    Dn: aDays[this.getDay()].substring(0, 3),
	    ds: fDaySuffix(this.getDate()),
	    yyyy: this.getFullYear(),
	    hh: this.getHours(),
	    mm: this.getMinutes(),
	    ss: this.getSeconds(),
	    xx: fZeroPad(this.getMilliseconds(), 3),
	    ap: "AM",
	    tz: this.getTimezoneOffset() / -60
	}

    // if format contains an am/pm reference then shift hours 12 hours after noon
    if (theFormat.match(/\bap\b/i)) {
        //isMilitaryTime = false;
        if (aVars.hh > 12) {
            aVars.hh -= 12;
            aVars.ap = "PM";
        }
    }

    if (aVars.hh == 0) aVars.hh = 12;

    for (v in aVars)
    {
        theFormat = (v == "dd")
		? theFormat.replace(v, aVars[v]) 
		: theFormat.replace(v, fPad2digit(aVars[v], v));
    }

    function fPad2digit(theVal, v) {
        // return value padded with leading zero unless using military time
        return (theVal < 10 && v != "tz" && !(v == "hh" && !isMilitaryTime)) ? "0" + theVal : theVal;
    }

    function fDaySuffix(d) {
        var lastdigit = d.toString().substr(d.toString().length - 1, 1);
        var lasttwodigits = "";
        if (d.toString().length >= 2)
            lasttwodigits = d.toString().substr(d.toString().length - 2, 2);

        return d.toString()
            + (lasttwodigits == "11" || lasttwodigits == "12" || lasttwodigits == "13" ? "th"
            : (lastdigit == "1" ? "st" : (lastdigit == "2" ? "nd" : (lastdigit == "3" ? "rd" : "th"))));
    }

    return theFormat;
}

