function isAlien(a)
{
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) 
{
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a)
{
    return typeof a == 'boolean';
}

function isEmpty(o)
{
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (!!isUndefined(v) && !!isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a)
{
    return typeof a == 'function';
}

function isNull(a)
{
    return typeof a == 'object' && !a;
}

function isInteger(a)
{
    re = /^-?\d+$/g
    return re.test(a);

}

function isObject(a) {
    return (typeof a == 'object' && !!a) || isFunction(a);
}

function isString(a)
{
    return typeof a == 'string';
}

function isUndefined(a)
{
    return typeof a == 'undefined';
}

function addCSSClass(obj, cc) 
{
    if (isString(cc)) {
        if ((obj.className.indexOf(" "+cc) == -1) && (obj.className.indexOf(cc+" ") == -1) && (obj.className != cc)) {
            obj.className = obj.className + " " + cc;
        } else if (obj.className.trim() == '' && cc.length) {
            obj.className = cc;
        }        
    }
}

function removeCSSClass(obj, cc) 
{
    if (isString(cc)) {
        if (obj.className.indexOf(' '+cc) != -1) {
            obj.className = obj.className.str_replace(' '+cc, '').trim();
        } else if (obj.className.indexOf(cc+' ') != -1) {
            obj.className = obj.className.str_replace(cc+' ', '').trim();
        } else if (obj.className == cc) {
            obj.className = '';
        }    
    }
}

// redirect to the home page
function hpRedirect() 
{
        setTimeout("self.location = '/'",4500);
}

function makeDomElement(name, attrs, style, text)
{
    var e = document.createElement(name.toUpperCase());
    if (attrs) {
        for (key in attrs) {
            switch (key) {
                case 'class':
                case 'className':
                    e.className = attrs[key];
                    break;
                case 'id':
                    e.id = attrs[key];
                    break;
                default:
                    e.setAttribute(key, attrs[key]);
            }
        }
    }
    if (style) {
        for (key in style) {
            e.style[key] = style[key];
        }
    }
    if (text) { e.appendChild(document.createTextNode(text)); }

    return e;
}

var aeOL = [];
function addEvent(o, n, f, l)
{
    var a = 'addEventListener', h = 'on'+n, b = '', s = '';
    if (o[a] && !l)
        return o[a](n, f, false);

    o._c |= 0;
    if (o[h]) {
        b = '_f' + o._c++; o[b] = o[h];
    }

    s = '_f' + o._c++;
    o[s] = f;
    o[h] = function(e) {
        e = e || window.event;
        var r = true;
        if (b) r = o[b](e) != false && r;
        r = o[s](e) != false && r;
        return r;
    };

    aeOL[aeOL.length] = { o: o, h: h };
};
addEvent(window, 'unload', function() { for (var i = 0; i < aeOL.length; i++) with (aeOL[i]) { o[h] = null; for(var c = 0; o['_f' + c]; c++) o['_f' + c] = null; } } );

var popUpWindowTrackingList = new Array();
var popUpCurOffsetX         = 50;
var popUpCurOffsetY         = 50;
var popUpBaseOffsetX        = 50;
var popUpBaseOffsetY        = 50;
var popUpWindowStepDistance = 25;
var popUpMaxX               = 400;
var popUpMaxY               = 300;
var popUpWidth              = 800;
var popUpHeight             = 600;

function popUp(URL, pWidth, pHeight, pOffsetX, pOffsetY, WindowName, WindowAttribs)
{
    // window size
    if (!pWidth) {
        pWidth = popUpWidth;
    }
    if (!pHeight) {
        pHeight = popUpHeight;
    }

    // X pos
    if (!pOffsetX || pOffsetX > popUpMaxX) {
        pOffsetX = popUpCurOffsetX;
        popUpCurOffsetX = popUpCurOffsetX + popUpWindowStepDistance;
    }
    if (pOffsetX > popUpMaxX) {
        pOffsetX = popUpBaseOffsetX;
    }

    // Y pos
    if (!pOffsetY || pOffsetY > popUpMaxY) {
        pOffsetY = popUpCurOffsetY;
        popUpCurOffsetY = popUpCurOffsetY + popUpWindowStepDistance;
    }
    if (pOffsetY > popUpMaxY) {
        pOffsetY = popUpBaseOffsetY;
    }

    // possibly add 'resizable' & 'scrollable' window attribs
    if (typeof(WindowAttribs) == 'undefined') {
        WindowAttribs = ',resizable=1,scrollbars=1';
    } else {
        if (WindowAttribs.indexOf("resizable") == -1) {
            WindowAttribs = ','+WindowAttribs+',resizable=1';
        }
        if (WindowAttribs.indexOf("scrollbars") == -1) {
            WindowAttribs = ','+WindowAttribs+',scrollbars=1';
        }
    }

    // create (if window handle does not yet exist) & popup a window and store the handle (if we were given a WindowName)
    if ((typeof WindowName != 'undefined') && WindowName > '') {
        if (typeof popUpWindowTrackingList[WindowName] != undefined && isObject(popUpWindowTrackingList[WindowName]) && !popUpWindowTrackingList[WindowName].closed) {
            handle = popUpWindowTrackingList[WindowName];
        } else {
            popUpWindowTrackingList[WindowName] = window.open(URL,WindowName,'width='+pWidth+',height='+pHeight+',screenX='+pOffsetX+',screenY='+pOffsetY+',top='+pOffsetY+',left='+pOffsetX+WindowAttribs);
            handle = popUpWindowTrackingList[WindowName];
        }
    } else {
        handle = window.open(URL,'','width='+pWidth+',height='+pHeight+',screenX='+pOffsetX+',screenY='+pOffsetY+',top='+pOffsetY+',left='+pOffsetX+WindowAttribs);
    }

    setFocus(handle);

    return handle;
}

function popupSecImgExplaination()
{
	return popUp('/imgsec_expl.php', 600, 400, 100, 100, 'ImgSecExpl_'+document.domain, 'resizable=0,scrollbars=0,menubar=0,status=0,toolbar=0');	
}

function URLEncode(plaintext)
{
    var SAFECHARS = "0123456789" +                  // Numeric
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +  // Alphabetic
                    "abcdefghijklmnopqrstuvwxyz" +
                    "-_.!~*'()";                    // RFC2396 Mark characters
    var HEX = "0123456789ABCDEF";

    var encoded = "";
    for (var i = 0; i < plaintext.length; i++ ) {
        var ch = plaintext.charAt(i);
        if (ch == " ") {
            encoded += "+";             // x-www-urlencoded, rather than %20
        } else if (SAFECHARS.indexOf(ch) != -1) {
            encoded += ch;
        } else {
            var charCode = ch.charCodeAt(0);
            if (charCode > 255) {
                /*
                alert( "Unicode Character '" + ch + "' cannot be encoded using standard URL encoding.\n" +
                        "(URL encoding only supports 8-bit characters.)\n" +
                        "A space (+) will be substituted." );
                */
                encoded += "+";
            } else {
                encoded += "%";
                encoded += HEX.charAt((charCode >> 4) & 0xF);
                encoded += HEX.charAt(charCode & 0xF);
            }
        }
    } // for

    return encoded;
};

function URLDecode(encoded)
{
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.

   var HEXCHARS = "0123456789ABCDEFabcdef";
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
       if (ch == "+") {
           plaintext += " ";
           i++;
       } else if (ch == "%") {
            if (i < (encoded.length-2)
                    && HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
                    && HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
                plaintext += unescape(encoded.substr(i,3));
                i += 3;
            } else {
                /*
                alert( 'Bad escape combination near ...' + encoded.substr(i) );
                */
                plaintext += "%[ERROR]";
                i++;
            }
        } else {
           plaintext += ch;
           i++;
        }
    } // while
   return plaintext;
};


String.prototype.ucFirstLetter = function()
{
    return this.substr(0, 1).toUpperCase() + this.substr(1); 
}

if (typeof String.prototype.pad == 'undefined') { 
    String.prototype.pad                = function( chr, count, edge )
    {
    	var padStr = "";
    	for (var i=this.length; i< count; i++) {
    	   padStr = padStr + chr;
    	   //alert(padStr.length+' - padStr :"'+padStr+'"');
        }
                
    	//alert('str len:'+this.length+', count:'+count);
    	//alert('padStr :"'+padStr+'"');
    	
    	switch (edge) {
    	   case 'l':
    	   case 'left':       
    	       return padStr + this;	       
    	   case 'both': //  can't handle this yet
    	   case 'r':
    	   case 'right':
    	   default:
    	       return this + padStr;
    	}
    }
    String.prototype.padr               = function( chr, count ) { return this.pad( chr, count, 'right' ); }
    String.prototype.padl               = function( chr, count ) { return this.pad( chr, count, 'left' ); }

}
// trim the string - pass a single param of true in order to have double spaces removed also.
if (typeof String.prototype.trim == 'undefined') {
    String.prototype.trim                   = function(remDoubleSpaces)
    {
        var retValue = this.replace( /^\s+|\s+$/g, "" );
    
        if (isBoolean(remDoubleSpaces) && remDoubleSpaces) {
            while (retValue.indexOf("  ") != -1) { // Note that there are two spaces in the string - look for multiple spaces within the string
                retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ")+1, retValue.length); // Again, there are two spaces in each of the strings
            }   
        }
        
        return retValue; 
    }
}

// simple replacement of a string
String.prototype.str_replace            = function(fStr, rStr, honorCase)
{
    re = new RegExp( fStr, (honorCase ? 'g': 'ig'));
    return this.replace( re, rStr );
}

// New C# style string formatter 
String.prototype.stringFormat           = function (arrInput)
{
    var idx            = 0; 
    var placeholderlen = 2;
    var strOutput      = this.toString();
    if (arrInput instanceof Array) {
        var thisArgs = arrInput;
    } else {
        var thisArgs = arguments;
    }

    for (var i=0; i < thisArgs.length; i++) {
        while ((idx = strOutput.indexOf('{' + i + '}', idx)) != -1) {
            strOutput = strOutput.substring(0, idx) + thisArgs[i] + strOutput.substr(idx + placeholderlen + idx.toString().length);
        }
    }

    
    return strOutput;
}

String.prototype.stripTags              = function (validTags) 
{
    var newstr  = this.toString();
    var regExp1 = /<\/?(\w+)(.*?)>/ig;
    
    if (validTags && validTags.prototype == Array) {
        var regExp2 = new RegExp('/^('+validTags.join('|')+')$/i'); // em|strong|u|p
    } 
    
    while(mt = regExp1.exec(newstr)) {
        oldstr = mt[0]; tag = mt[1]; pars = mt[2];
        repl   = '';       
                
        if(regExp2 && tag.match(regExp2)) {
            repl = oldstr.replace(pars,'');
        } 
        
        newstr = newstr.replace(oldstr, repl);
    }
    return newstr;
}


Array.prototype.inArray = function (value)
// Returns true if the passed value is found in the
// array.  Returns false if it is not.
{
    var i;
    for (i=0; i < this.length; i++) {
        // Matches identical (===), not just similar (==).
        if (this[i] === value) {
            return true;
        }
    }
    return false;
};

/* add each arg to the end of the array */
if ( typeof Array.push == 'undefined' ) {
    Array.prototype.push = function()
    {
        for ( var i = 0; i < arguments.length; i++ )
        {
            this[this.length] = arguments[i];
        }
        return this.length;
    }
}

/* Finds the index of the first occurence of item in the array, or -1 if not found */
Array.prototype.indexOf = function(item) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] == item) {
            return i;
        }
    }
    return -1;
};

/* Returns an array of items judged 'true' by the passed in test function */
Array.prototype.filter = function(test) {
    var matches = [];
    for (var i = 0; i < this.length; i++) {
        if (test(this[i])) {
            matches[matches.length] = this[i];
        }
    }
    return matches;
};

/* Indicates whether some other array is "equal to" this one */
Array.prototype.equals = function(a) {
    if (this.length != a.length) {
        return false;
    }
    for (var i = 0; i < this.length; i++) {
        if (this[i] != a[i]) {
            return false;
        }
    }
    return true;
}
