/**************************************************************************
GENERAL UTILITIES
**************************************************************************/
function CenterPopup(URL, width, height, scrollbars, resizable) {
    // get center of browser window
    var X = (screen.width - width) / 2;
    var Y = (screen.height - height) / 2;
    if (scrollbars == undefined)
        scrollbars = 0;
    if (resizable == undefined)
        resizable = 0;
    var popup = window.open(URL, calcMD5(URL), 'status=no,toolbar=no,location=no,scrollbars=' + scrollbars + ',resizable=' + resizable + ',width=' + width + ',height=' + height + ',top=' + Y + ',left=' + X);
    if (popup)
        popup.focus();
}

function OpenPopUpAtRightBottom(URL, width, height, scrollbars) {
    // get center of browser window
    var X = screen.availWidth - width - 50;
    var Y = screen.availHeight - height - 75;
    if (scrollbars == undefined)
        scrollbars = 0;
    var popup = window.open(URL, calcMD5(URL), 'status=no,toolbar=no,location=no,scrollbars=' + scrollbars + ',width=' + width + ',height=' + height + ',top=' + Y + ',left=' + X);
    if (popup)
        popup.focus();
}

function GetFrameDimentions(doc) {
    var retVal = -1;
    if (doc.documentElement &&
		(doc.documentElement.clientWidth || doc.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        retVal = new Array(2);
        retVal[0] = doc.documentElement.clientWidth;
        retVal[1] = doc.documentElement.clientHeight;
    } else {
        if (doc.body && (doc.body.clientWidth || doc.body.clientHeight)) {
            //IE 4 compatible
            retVal = new Array(2);
            retVal[0] = doc.body.clientWidth;
            retVal[1] = doc.body.clientHeight;
        }
    }
    return retVal;
}

function replaceString(szString, szFind, szReplace) {
    var iMatched, fSubstring, sSubstring;
    iMatched = 0;
    while (iMatched >= 0) {
        iMatched = szString.indexOf(szFind);
        if (iMatched < 0)
            return szString;
        fSubstring = szString.substring(0, iMatched);
        sSubstring = szString.substring(iMatched + szFind.length, szString.length);
        szString = fSubstring + szReplace + sSubstring;
    }
}

function AddLeadingZero(nNumber) {
    return nNumber < 10 ? ("0" + nNumber) : (nNumber);

}

function trim(str) {
    if (!str || typeof str != 'string')
        return null;
    return str.replace(/^[\s]+/, '').replace(/[\s]+$/, '').replace(/[\s]{2,}/, ' ');
}


/*based on http://www.howtocreate.co.uk/perfectPopups.html */
function getRefToDivMod(divID, oDoc) {
    if (!oDoc) { oDoc = document; }
    if (document.layers) {
        if (oDoc.layers[divID]) { return oDoc.layers[divID]; } else {
            for (var x = 0, y; !y && x < oDoc.layers.length; x++) {
                y = getRefToDivMod(divID, oDoc.layers[x].document);
            }
            return y;
        }
    }
    if (document.getElementById) { return oDoc.getElementById(divID); }
    if (document.all) { return oDoc.all[divID]; }
    return document[divID];
}

/*based on http://www.howtocreate.co.uk/perfectPopups.html */
function resizeWinTo(idOfDiv) {
    var oH = getRefToDivMod(idOfDiv); if (!oH) { return false; }
    var x = window; x.resizeTo(screen.availWidth, screen.availWidth);
    var oW = oH.clip ? oH.clip.width : oH.offsetWidth;
    var oH = oH.clip ? oH.clip.height : oH.offsetHeight; if (!oH) { return false; }
    x.resizeTo(oW + 200, oH + 200);
    var myW = 0, myH = 0, d = x.document.documentElement, b = x.document.body;
    if (x.innerWidth) { myW = x.innerWidth; myH = x.innerHeight; }
    else if (d && d.clientWidth) { myW = d.clientWidth; myH = d.clientHeight; }
    else if (b && b.clientWidth) { myW = b.clientWidth; myH = b.clientHeight; }
    if (window.opera && !document.childNodes) { myW += 16; }
    //second sample, as the table may have resized
    var oH2 = getRefToDivMod(idOfDiv);
    var oW2 = oH2.clip ? oH2.clip.width : oH2.offsetWidth;
    var oH2 = oH2.clip ? oH2.clip.height : oH2.offsetHeight;
    var winWidth = oW2 + ((oW + 200) - myW);
    var winHeight = oH2 + ((oH + 200) - myH);
    x.resizeTo(winWidth, winHeight);

    //centre the window 
    if (window.moveTo) window.moveTo((screen.availWidth - winWidth) / 2, (screen.availHeight - winHeight) / 2);
}



/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Copyright (C) Paul Johnston 1999 - 2000.
* See http://pajhome.org.uk/site/legal.html for details.
*/

/*
* Convert a 32-bit number to a hex string with ls-byte first
*/
var hex_chr = "0123456789abcdef";
function rhex(num) {
    var str = "";
    for (var j = 0; j <= 3; j++)
        str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
           hex_chr.charAt((num >> (j * 8)) & 0x0F);
    return str;
}

/*
* Convert a string to a sequence of 16-word blocks, stored as an array.
* Append padding bits and the length, as described in the MD5 standard.
*/
function str2blks_MD5(str) {
    var nblk = ((str.length + 8) >> 6) + 1;
    var blks = new Array(nblk * 16);
    for (var i = 0; i < nblk * 16; i++) blks[i] = 0;
    for (i = 0; i < str.length; i++)
        blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
    blks[i >> 2] |= 0x80 << ((i % 4) * 8);
    blks[nblk * 16 - 2] = str.length * 8;
    return blks;
}

/*
* Add integers, wrapping at 2^32
*/
function add(x, y) {
    return ((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) ^ (x & 0x80000000) ^ (y & 0x80000000);
}

/*
* Bitwise rotate a 32-bit number to the left
*/
function rol(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt));
}

/*
* These functions implement the basic operation for each round of the
* algorithm.
*/
function cmn(q, a, b, x, s, t) {
    return add(rol(add(add(a, q), add(x, t)), s), b);
}
function ff(a, b, c, d, x, s, t) {
    return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t) {
    return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t) {
    return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t) {
    return cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
* Take a string and return the hex representation of its MD5.
*/
function calcMD5(str) {
    var x = str2blks_MD5(str);
    var a = 0x67452301;
    var b = 0xEFCDAB89;
    var c = 0x98BADCFE;
    var d = 0x10325476;

    for (var i = 0; i < x.length; i += 16) {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;

        a = ff(a, b, c, d, x[i + 0], 7, 0xD76AA478);
        d = ff(d, a, b, c, x[i + 1], 12, 0xE8C7B756);
        c = ff(c, d, a, b, x[i + 2], 17, 0x242070DB);
        b = ff(b, c, d, a, x[i + 3], 22, 0xC1BDCEEE);
        a = ff(a, b, c, d, x[i + 4], 7, 0xF57C0FAF);
        d = ff(d, a, b, c, x[i + 5], 12, 0x4787C62A);
        c = ff(c, d, a, b, x[i + 6], 17, 0xA8304613);
        b = ff(b, c, d, a, x[i + 7], 22, 0xFD469501);
        a = ff(a, b, c, d, x[i + 8], 7, 0x698098D8);
        d = ff(d, a, b, c, x[i + 9], 12, 0x8B44F7AF);
        c = ff(c, d, a, b, x[i + 10], 17, 0xFFFF5BB1);
        b = ff(b, c, d, a, x[i + 11], 22, 0x895CD7BE);
        a = ff(a, b, c, d, x[i + 12], 7, 0x6B901122);
        d = ff(d, a, b, c, x[i + 13], 12, 0xFD987193);
        c = ff(c, d, a, b, x[i + 14], 17, 0xA679438E);
        b = ff(b, c, d, a, x[i + 15], 22, 0x49B40821);

        a = gg(a, b, c, d, x[i + 1], 5, 0xF61E2562);
        d = gg(d, a, b, c, x[i + 6], 9, 0xC040B340);
        c = gg(c, d, a, b, x[i + 11], 14, 0x265E5A51);
        b = gg(b, c, d, a, x[i + 0], 20, 0xE9B6C7AA);
        a = gg(a, b, c, d, x[i + 5], 5, 0xD62F105D);
        d = gg(d, a, b, c, x[i + 10], 9, 0x02441453);
        c = gg(c, d, a, b, x[i + 15], 14, 0xD8A1E681);
        b = gg(b, c, d, a, x[i + 4], 20, 0xE7D3FBC8);
        a = gg(a, b, c, d, x[i + 9], 5, 0x21E1CDE6);
        d = gg(d, a, b, c, x[i + 14], 9, 0xC33707D6);
        c = gg(c, d, a, b, x[i + 3], 14, 0xF4D50D87);
        b = gg(b, c, d, a, x[i + 8], 20, 0x455A14ED);
        a = gg(a, b, c, d, x[i + 13], 5, 0xA9E3E905);
        d = gg(d, a, b, c, x[i + 2], 9, 0xFCEFA3F8);
        c = gg(c, d, a, b, x[i + 7], 14, 0x676F02D9);
        b = gg(b, c, d, a, x[i + 12], 20, 0x8D2A4C8A);

        a = hh(a, b, c, d, x[i + 5], 4, 0xFFFA3942);
        d = hh(d, a, b, c, x[i + 8], 11, 0x8771F681);
        c = hh(c, d, a, b, x[i + 11], 16, 0x6D9D6122);
        b = hh(b, c, d, a, x[i + 14], 23, 0xFDE5380C);
        a = hh(a, b, c, d, x[i + 1], 4, 0xA4BEEA44);
        d = hh(d, a, b, c, x[i + 4], 11, 0x4BDECFA9);
        c = hh(c, d, a, b, x[i + 7], 16, 0xF6BB4B60);
        b = hh(b, c, d, a, x[i + 10], 23, 0xBEBFBC70);
        a = hh(a, b, c, d, x[i + 13], 4, 0x289B7EC6);
        d = hh(d, a, b, c, x[i + 0], 11, 0xEAA127FA);
        c = hh(c, d, a, b, x[i + 3], 16, 0xD4EF3085);
        b = hh(b, c, d, a, x[i + 6], 23, 0x04881D05);
        a = hh(a, b, c, d, x[i + 9], 4, 0xD9D4D039);
        d = hh(d, a, b, c, x[i + 12], 11, 0xE6DB99E5);
        c = hh(c, d, a, b, x[i + 15], 16, 0x1FA27CF8);
        b = hh(b, c, d, a, x[i + 2], 23, 0xC4AC5665);

        a = ii(a, b, c, d, x[i + 0], 6, 0xF4292244);
        d = ii(d, a, b, c, x[i + 7], 10, 0x432AFF97);
        c = ii(c, d, a, b, x[i + 14], 15, 0xAB9423A7);
        b = ii(b, c, d, a, x[i + 5], 21, 0xFC93A039);
        a = ii(a, b, c, d, x[i + 12], 6, 0x655B59C3);
        d = ii(d, a, b, c, x[i + 3], 10, 0x8F0CCC92);
        c = ii(c, d, a, b, x[i + 10], 15, 0xFFEFF47D);
        b = ii(b, c, d, a, x[i + 1], 21, 0x85845DD1);
        a = ii(a, b, c, d, x[i + 8], 6, 0x6FA87E4F);
        d = ii(d, a, b, c, x[i + 15], 10, 0xFE2CE6E0);
        c = ii(c, d, a, b, x[i + 6], 15, 0xA3014314);
        b = ii(b, c, d, a, x[i + 13], 21, 0x4E0811A1);
        a = ii(a, b, c, d, x[i + 4], 6, 0xF7537E82);
        d = ii(d, a, b, c, x[i + 11], 10, 0xBD3AF235);
        c = ii(c, d, a, b, x[i + 2], 15, 0x2AD7D2BB);
        b = ii(b, c, d, a, x[i + 9], 21, 0xEB86D391);

        a = add(a, olda);
        b = add(b, oldb);
        c = add(c, oldc);
        d = add(d, oldd);
    }
    return rhex(a) + rhex(b) + rhex(c) + rhex(d);
}

/*function GetFrameByName(FrameName){
var p=parent;
for(var ix=1;ix<10;ix++){
if(p.frames.length>0){
var f=p.frames[FrameName]
if(f){
return f
}else{
p=p.parent
}
}else{
p=p.parent;
}
}
}
*/
function GetFrameByName(FrameName) {
    var top = FindTop(window);
    return FindFrame(FrameName, top);
}

function FindTop(start) {
    if (start == top) return top;
    try { var t = start.parent.name; } catch (e) { return start; }
    return FindTop(start.parent);
}

function FindFrame(frameName, start) {
    if (start == null) return null;

    var resframe = null;
    var frames = start.frames;
    if (frames.length == 0) return null;

    for (var i = 0; i < frames.length; i++) {
        tmpFrame = frames[i];

        try { tmpFrameName = tmpFrame.name; }
        catch (e) { continue; }

        if (tmpFrameName.toUpperCase() == frameName.toUpperCase()) {
            resframe = frames[i];
        } else {
            resframe = FindFrame(frameName, tmpFrame);
        }
        if (resframe != null) return resframe;
    } return null;
}

function centerElementOnScreen(element) {
    var scrollTop = document.body.scrollTop;
    var scrollLeft = document.body.scrollLeft;

    var viewPortHeight = document.body.clientHeight;
    var viewPortWidth = document.body.clientWidth;

    if (document.compatMode == "CSS1Compat") {
        viewPortHeight = document.documentElement.clientHeight;
        viewPortWidth = document.documentElement.clientWidth;

        scrollTop = document.documentElement.scrollTop;
        scrollLeft = document.documentElement.scrollLeft;
    }

    var topOffset = Math.ceil(viewPortHeight / 2 - element.offsetHeight / 2);
    var leftOffset = Math.ceil(viewPortWidth / 2 - element.offsetWidth / 2);

    var top = scrollTop + topOffset - 40;
    var left = scrollLeft + leftOffset - 70;

    element.style.position = "absolute";
    element.style.top = top + "px";
    element.style.left = left + "px";
}

function climbTo(srcElement, id) {
    //climbs up the DOM from the srcElement up it's parents to a tag with the provided ID
    //returns the DOM element found
    var parentElement;
    while ((srcElement = srcElement.parentNode) && !parentElement) {
        if (srcElement.id == id) {
            parentElement = srcElement;
        }
    }

    return parentElement;
}
