/* Common.js */

/* ----------------------------------- Email Related Functions */

function fMaskAddress(id, domain, name, nameOnly) {
    var toName;
    if (typeof (name) != 'undefined')
        toName = name
    else
        toName = id + "@" + domain

    var s = "";
    s += '<a href='
    s += '"mailto:' + id + '@' + domain + '"'
    s += ' class="popuplink"'
    s += ' onmouseover=\'fStatus("Send Email to ' + toName + '")\''
    s += ' onmouseout=\'fStatus("")\''
    s += ' title="Click here to open a new email message to ' + toName + '")'
    s += '>'
    s += toName
    if (!nameOnly)
        s += '&nbsp; (' + id + '<img src="/sl/images/at.gif" border="0" />' + domain + ')'
    s += '</a>'

    document.write(s);
}

function fStatus(s) {
    window.status = s;                                  
    window.event.returnValue = true;
    return true;
}

/* ----------------------------------- Form Validation Functions */

function fCheckField(oFld, sMsg) {

    if (oFld.value == '') {
        alert(sMsg);
        oFld.focus();
        //		if ((oFld.type=='text') || (oFld.type=='password')) oFld.select();
        return false;
    }

    return true;
}

function fCheckCondition(oFld, isBadCondition, sMsg) {

    if (isBadCondition) {
        alert(sMsg);
        oFld.focus();
        //		if ((oFld.type=='text') || (oFld.type=='password')) oFld.select();
        return false;
    }

    return true;
}

/* ----------------------------------- URL Parameter Functions */

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 unescape(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, " ");
}

/* ----------------------------------- Clipboard Function */

function copyDivToClipboard(div, msg) {
    var text = document.getElementById(div).innerHTML.StripHTML();
    copyToClipboard(text);

    if (typeof (msg) != "undefined" && msg != "")
        alert(msg)

    return false;
}

function copyToClipboard(text) {
    if (window.clipboardData) {
        window.clipboardData.setData("text", text);
    }
//    else {
//        var clipboarddiv = document.getElementById("dvClipboardSWF");
//        if (clipboarddiv == null) {
//            clipboarddiv = document.createElement("div");
//            clipboarddiv.setAttribute("name", "dvClipboardSWF");
//            clipboarddiv.setAttribute("id", "dvClipboardSWF");
//            document.body.appendChild(clipboarddiv);
//        }
//        clipboarddiv.innerHTML = "<embed"
//            + " src='FireFox-Clipboard.swf'"
//            + " FlashVars='clipboard=" + fURLEncode(text) + "'"
//            + " width='0'"
//            + " height='0'"
//            + " type='application/x-shockwave-flash'>"
//            + "</embed>";
//    }

    return false;
}

/* ----------------------------------- Bookmark Function */

function createBookmark(title, url) {
    if (window.sidebar) // firefox
        window.sidebar.addPanel(title, url, "");
    else if (window.opera && window.print) { // opera
        var elem = document.createElement('a');
        elem.setAttribute('href', url);
        elem.setAttribute('title', title);
        elem.setAttribute('rel', 'sidebar');
        elem.click();
    }
    else if (document.all)// ie
        window.external.AddFavorite(url, title);
}

/* ----------------------------------- Rollover Functions */

function rollover(obj) {
    obj.src = obj.src.substring(0, obj.src.length - 4) + "_hover.gif";
}

function rollout(obj) {
    obj.src = obj.src.substring(0, obj.src.length - 10) + ".gif";
}

/* ----------------------------------- 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);
}

/* ----------------------------------- 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.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 */

//function initializeTimeZone() {
//    // set cookie for server side use
//    if (createCookie)
//        createCookie("TimeZone", new Date().toLocalFormat("tz"), 365);
//}

Date.prototype.toAge = function() {
    // all comparisons are based on GMT time

    var s = "";
    var span = 0;
    var uom = "";

    // get the current time in GMT
    var oDiff = this.dateDiff(new Date(new Date().toUTCString().replace(" UTC", "")));

    if (oDiff.TotalMinutes < 59) {
        span = Math.round(oDiff.TotalMinutes);
        uom = "min";
    }
    else {
        if (oDiff.TotalHours < 23.5) {
            span = Math.round(oDiff.TotalHours);
            uom = "hour";
        }
        else {
            span = Math.round(oDiff.TotalDays);
            uom = "day";
        }
    }

    if (span < 0)
        span = 0;
        
    s = span + " " + uom;
    if (span > 1)
        s += "s";

    s += " ago";

    return s;
}

Date.prototype.toTimeSpan = function(theDate, showMilliseconds) {
    var oDiff = this.dateDiff(theDate);
    var s = "";

    s += (oDiff.year > 0 ? oDiff.year.toString() + " year" + (oDiff.year > 1 ? "s" : "") : "");
    s += (oDiff.month > 0 ? (s.length > 0 ? ", " : "") + oDiff.month.toString() + " month" + (oDiff.month > 1 ? "s" : "") : "");
    s += (oDiff.day > 0 ? (s.length > 0 ? ", " : "") + oDiff.day.toString() + " day" + (oDiff.day > 1 ? "s" : "") : "");
    s += (oDiff.hour > 0 ? (s.length > 0 ? ", " : "") + oDiff.hour.toString() + " hour" + (oDiff.hour > 1 ? "s" : "") : "");
    s += (oDiff.minute > 0 ? (s.length > 0 ? ", " : "") + oDiff.minute.toString() + " min" + (oDiff.minute > 1 ? "s" : "") : "");
    s += (oDiff.second > 0 ? (s.length > 0 ? ", " : "") + oDiff.second.toString() + " sec" + (oDiff.second > 1 ? "s" : "") : "");
    if (typeof (showMilliseconds) != "undefined" && showMilliseconds)
        s += (oDiff.millisecond > 0 ? (s.length > 0 ? ", " : "") + oDiff.millisecond.toString() + " ms" : "");

    return s;
}

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().toLocalFormat("dd/MM/yyyy hh:mm:ss ap")
Date.prototype.toLocalFormat = function(theFormat) {
    var isMilitaryTime = true;

    // arrays of "friendly" names
    var aDays = { 0: "Sunday", 1: "Monday", 2: "Tuesday", 3: "Wednesday", 4: "Thursday", 5: "Friday", 6: "Saturday" }
    var aMonths = { 0: "January", 1: "February", 2: "March", 3: "April", 4: "May", 5: "June", 6: "July", 7: "August", 8: "September", 9: "October", 10: "November", 11: "December" }

    var aVars =
	{
	    MM: this.getMonth() + 1,
	    MN: aMonths[this.getMonth()],
	    Mn: aMonths[this.getMonth()].substring(0, 3),
	    dd: 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 = 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;
}

/* ----------------------------------- Object Event Handler Functions */

var __eventListeners = [];

function addEvent(instance, eventName, listener) {
    var listenerFn = listener;
    if (instance.addEvent) {
        instance.addEvent(eventName, listenerFn, false);
    } else if (instance.attachEvent) {
        listenerFn = function() {
            listener(window.event);
        }
        instance.attachEvent("on" + eventName, listenerFn);
    } else {
        throw new Error("Event registration not supported");
    }
    var event = {
        instance: instance,
        name: eventName,
        listener: listenerFn
    };
    __eventListeners.push(event);
    return event;
}

function removeEvent(event) {
    var instance = event.instance;
    if (instance.removeEvent) {
        instance.removeEvent(event.name, event.listener, false);
    } else if (instance.detachEvent) {
        instance.detachEvent("on" + event.name, event.listener);
    }
    for (var i = 0; i < __eventListeners.length; i++) {
        if (__eventListeners[i] == event) {
            __eventListeners.splice(i, 1);
            break;
        }
    }
}

function unregisterAllEvents() {
    while (__eventListeners.length > 0) {
        removeEvent(__eventListeners[0]);
    }
}

