String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
}
String.prototype.ltrim = function() {
    return this.replace(/^\s+/, "");
}
String.prototype.rtrim = function() {
    return this.replace(/\s+$/, "");
}
String.prototype.validateEmail = function() {
    var pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
    return pattern.test(this);
}

// enable the png fix for I6 & under.
if (document.all && /MSIE (5\.5|6)/.test(navigator.userAgent) &&
    document.styleSheets && document.styleSheets[0] && document.styleSheets[0].addRule) {
    // document.styleSheets[0].addRule('*', 'behavior: url(iepngfix.htc)');
    // Feel free to add rules for specific elements only, as above.
    // You have to call this once for each selector, like so:
    document.styleSheets[0].addRule('img', 'behavior: url(iepngfix.htc)');
    document.styleSheets[0].addRule('div', 'behavior: url(iepngfix.htc)');
}


/////////// ALIASES //////////////////
function de(elementId) {
    return document.getElementById(elementId);
}
function sf(form, name, value) {
    form.elements[name].value = value;
}

// keyboard enter?
function kH(e) {
    var code;

    if (!e) var e = window.event;
    if (e.keyCode) { code = e.keyCode; }
    else if (e.which) { code = e.which; }

    return ((code == 13) || (code == 9));
}

function hideObj(objId) {
    var o = document.getElementById(objId);
    if (o != null) {
        o.style.display = "none";
    }
}
function showObj(objId) {
    var o = document.getElementById(objId);
    if (o != null) {
        o.style.display = "block";
    }
}
function setClass(objId, className) {
    var o = document.getElementById(objId);
    if (o != null) {
        o.className = className;
    }
}

var _debug_ajax = false;
var _ajax_bad_chars = "<>&'\"";
var _ajax_bad_chars_html = "&lt; &gt; &amp; &#39; &quot;";
var _ajax_bad_chars_text = "< > & ' \"";

function AjaxHasBadChars(value) {
    for (var i = 0; i < _ajax_bad_chars.length; i++) {
        var c = _ajax_bad_chars.charAt(i);
        if (value.indexOf("" + c) >= 0) {
            return true;
        }
    }
    return false;
}

function AjaxGetBadChars() {
    return _ajax_bad_chars_html;
}

function AjaxGetBadChars2() {
    return _ajax_bad_chars_text;
}

// get the Ajax object (XmlHttp)
function GetXmlHttp() {
    var obj = null;
    try {
        obj = new ActiveXObject("Msxml2.XMLHTTP");
        return obj;
    } catch (e) {
        try {
            obj = new ActiveXObject("Microsoft.XMLHTTP");
            return obj;
        } catch (E) {
            // didn't work
        }
    }

    if (typeof XMLHttpRequest != 'undefined') {
        try {
            obj = new XMLHttpRequest();
            return obj;
        } catch (e) {
            // didn't work
        }
    }
    if (window.createRequest) {
        try {
            obj = window.createRequest();
            return obj;
        } catch (e) {
            // didn't work
        }
    }
    return obj;
}

function LoadXml(xmlString) {
    var xdoc;

    if (window.ActiveXObject && /Win/.test(navigator.userAgent)) {
        // IE code
        xdoc = new ActiveXObject("Microsoft.XMLDOM");
        xdoc.async = false;
        xdoc.loadXML(xmlString);
        return xdoc;
    } else if (document.implementation && document.implementation.createDocument) {
        // FF and Opera
        var parser = new DOMParser();
        xdoc = parser.parseFromString(xmlString, 'text/xml');
        return xdoc;
    } else {
        return null;
    }
}


function toDOM(HTMLstring) {
    var d = document.createElement('div');
    d.innerHTML = HTMLstring;
    var docFrag = document.createDocumentFragment();

    while (d.firstChild) {
        docFrag.appendChild(d.firstChild)
    };

    d.innerHTML = "";   // remove it

    return docFrag;
}


function AjaxRefreshAsync(formObj, divId) {
    // sniff form script and params
    var script = formObj.action;
    if (script == "") {
        script = document.location.href;
    }
    var httpreq = "";
    for (var i = 0; i < formObj.elements.length; i++) {
        var name = escape(formObj.elements[i].name);
        var value = escape(formObj.elements[i].value);
        if (name == "") {
            continue;
        }

        if (httpreq.length > 0) {
            httpreq += "&";
        }
        httpreq += name + "=" + value;
    }
    if (_debug_ajax) {
        alert("running script=" + script + "\nhttpreq=" + httpreq);
    }
    // get the ajax object
    var xmlhttp = GetXmlHttp();
    if (xmlhttp != null) {
        // post form
        xmlhttp.open("POST", script, true);
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                    if (_debug_ajax) {
                        alert("ok: text= " + xmlhttp.responseText);
                    }
                    var htmlString = xmlhttp.responseText;

                    var dom = toDOM(htmlString);
                    var htmlDiv1 = dom.getElementById(divId);
                    var htmlDiv2 = document.getElementById(divId);
                    if (htmlDiv1 != null && htmlDiv2) {
                        htmlDiv2.innerHTML = htmlDiv1.innerHTML;
                        if (_debug_ajax) alert('target DIV updated successfully');
                    } else {
                        if (_debug_ajax) alert('target DIV not found');
                    }

                } else {
                    if (_debug_ajax) {
                        alert("error: " + xmlhttp.status);
                    }
                }
            }
        }
        xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        xmlhttp.send(httpreq);
    }
}

////////////////////////////// lvsys string object /////////////////////////
// TODO: move these into string.prototype
function lvsysStr() {
    // encode the quotes and newlines so that we can use the string in javascript
    this.encodeEntities = function(s) {
        if (s == null) return "";
        s = s.replace(/\'/g, "&#39;");
        s = s.replace(/\r\n/g, "<br/>");
        s = s.replace(/\n/g, "<br/>");
        return s;
    }
    // decodes the quotes and newlines so that we can use the string in javascript
    this.restoreEntities = function(s) {
        if (s == null) return "";
        s = s.replace(/&#39;/, "'");
        s = s.replace(/<br\/>/, "\n");
        return s;
    }
}
var lvsysStr = new lvsysStr();

////////////////////////////// lvsys object /////////////////////////
// this object is a singleton (only one static instance)
function lvsys() {
    this.imgCycleEnabled = true;    // use this to disable slideshows for IE6 (it interferes with droppy)
    this.imgIdArray = new Array();
    this.imgCycleIdArray = new Array();
    this.imgInterval = null;
    this.wsCS = ""; // global webservice setting

    this.prepImg = function(sImageId) {
        this.imgIdArray.push(sImageId);
    }
    this.prepCycle = function(sCycleId, sCycleEffect, iTransitionInterval, iSpeed) {
        var o = new Object();
        o.sCycleId = sCycleId;
        o.sCycleEffect = sCycleEffect;
        o.iTransitionInterval = iTransitionInterval;
        o.iSpeed = iSpeed;
        this.imgCycleIdArray.push(o);
    }

    this.imgReady = function() {
        var bImgLoaded = true;

        for (var i = 0; i < this.imgIdArray.length; i++) {
            if (document.getElementById(this.imgIdArray[i]).complete == false) {
                bImgLoaded = false;
            }
        }
        return bImgLoaded;
    }

    this.imgCheckStatus = function() {
        if (this.imgReady()) {

            // all images are ready.
            clearInterval(this.imgInterval);

            if (this.imgCycleEnabled) {
                // start all cycles.
                for (var i = 0; i < this.imgCycleIdArray.length; i++) {
                    $("#" + this.imgCycleIdArray[i].sCycleId).cycle({
                        fx: this.imgCycleIdArray[i].sCycleEffect,
                        speed: this.imgCycleIdArray[i].iTransitionInterval,
                        timeout: this.imgCycleIdArray[i].iSpeed  // still duration
                        //delay: -2000,
                        //startingSlide: 0
                    });
                }
            }

            // reset array
            this.imgCycleIdArray = new Array();
        }
    }

    // return an array of [width,height] where we guarantee width or height is at the correct thumbsize.
    this.imgScaleRatio = function(width, height, toWidth, toHeight) {
        var ratioArray1 = new Array();
        var ratioArray2 = new Array();
        if (width > toWidth) {
            ratioArray1[0] = toWidth;
        } else {
            ratioArray1[0] = width;
        }
        ratioArray1[1] = Math.floor((ratioArray1[0] * height) / width);

        if (height > toHeight) {
            ratioArray2[1] = toHeight;
        } else {
            ratioArray2[1] = height;
        }
        ratioArray2[0] = Math.floor((ratioArray2[1] * width) / height);

        if (ratioArray1[1] < toHeight) {
            return ratioArray1;
        } else {
            return ratioArray2;
        }
    }

    this.ajaxInvokePluginCalendar = function(options) {
        var backgroundColor = $('#' + options['pluginHtmlID']).css('background-color');
        var backgroundImage = $('#' + options['pluginHtmlID']).css('background-image');
        var backgroundRepeat = $('#' + options['pluginHtmlID']).css('background-repeat');
        var backgroundPosition = $('#' + options['pluginHtmlID']).css('background-position');
        if (backgroundPosition == undefined) {
            backgroundPosition = 'center center';
        }
        $.post(
				'index.php',
		 				{
		 				    ajax: '1',
		 				    func: 'invokePlugin',
		 				    page: options['page'],
		 				    inputName: options['inputName'],
		 				    offset: options['offset'],
		 				    date: options['date'],
		 				    pluginHtmlID: options['pluginHtmlID']
		 				},
		 				function(data, textStatus) {
		 				    //alert('get pager, status:' + textStatus);
		 				    //alert('get pager, data:' + data);
		 				    if (textStatus == 'success') {
		 				        var dom = toDOM(data);
		 				        $('#' + options['pluginHtmlID'] + ' > *').remove();
		 				        $('#' + options['pluginHtmlID'])
		 				            .css('opacity', '1')
		 				            .css('z-index', '1')
		 				            .css('background-color', backgroundColor)
		 				            .css('background-image', backgroundImage)
		 				            .css('background-repeat', backgroundRepeat)
		 				            .css('background-position', backgroundPosition);
		 				        $('#' + options['pluginHtmlID']).html(dom.firstChild.innerHTML);
		 				        $('#' + options['pluginHtmlID']).attr('rel', $(data).attr('rel'));
		 				    }
		 				},
		 				'html'
		 			);
        // this div gets inserted behind the plugin div, and will fail to show its animated GIF 
        // if the plugin has a background set
        $("#" + options['pluginHtmlID']).wrapInner('<div />')
            .css('opacity', '0.5')
            .css('z-index', '2')
            .css('background', 'no-repeat url(admin/img/ajax-loader.gif) center center')
            .attr('id', options['pluginHtmlID']);
    }

    // update a plugin pager
    this.ajaxInvokePluginPager = function(options) {
        var backgroundColor = $('#' + options['pluginHtmlID']).css('background-color');
        var backgroundImage = $('#' + options['pluginHtmlID']).css('background-image');
        var backgroundRepeat = $('#' + options['pluginHtmlID']).css('background-repeat');
        var backgroundPosition = $('#' + options['pluginHtmlID']).css('background-position');
        if (backgroundPosition == undefined) {
            backgroundPosition = 'center center';
        }
        $.post(
				'index.php',
		 				{
		 				    ajax: '1',
		 				    func: 'invokePlugin',
		 				    page: options['page'],
		 				    ref: options['ref'],
		 				    inputName: options['inputName'],
		 				    pluginParams: options['pluginParams'],
		 				    pluginHtmlID: options['pluginHtmlID'],
		 				    pluginPageNo: options['pluginPageNo']
		 				},
		 				function(data, textStatus) {
		 				    //alert('get pager, status:' + textStatus);
		 				    //alert('get pager, data:' + data);
		 				    if (textStatus == 'success') {
		 				        var dom = toDOM(data);
		 				        $('#' + options['pluginHtmlID'] + ' > *').remove();
		 				        $('#' + options['pluginHtmlID'])
		 				            .css('opacity', '1')
		 				            .css('z-index', '1')
		 				            .css('background-color', backgroundColor)
		 				            .css('background-image', backgroundImage)
		 				            .css('background-repeat', backgroundRepeat)
		 				            .css('background-position', backgroundPosition);
		 				        $('#' + options['pluginHtmlID']).html(dom);
		 				    }
		 				},
		 				'html'
		 			);
        $("#" + options['pluginHtmlID']).wrapInner('<div />')
            .css('opacity', '0.5')
            .css('z-index', '2')
            .css('background', 'no-repeat url(admin/img/ajax-loader.gif) center center')
            .attr('id', options['pluginHtmlID']);

    }
    this.ajaxInvokePluginContent = function(options) {
        $.post(
				'index.php',
 				{
 				    ajax: '1',
 				    func: 'invokePlugin',
 				    page: options['page'],
 				    ref: options['ref'],
 				    inputName: options['inputName'],
 				    pluginParams: options['pluginParams'],
 				    pluginHtmlID: options['pluginHtmlID'],
 				    pluginData: options['pluginData']
 				},
 				function(data, textStatus) {
 				    //alert('get content, status:'+textStatus);
 				    //alert('get content, data:' + data);
 				    if (textStatus == 'success') {
 				        var dom = toDOM(data);
 				        $('#' + options['pluginHtmlID'] + ' > *').remove();
 				        $('#' + options['pluginHtmlID']).html(dom);
 				    }
 				},
 				'html'
 			);

    }

    //Cancels the event if it is cancelable, without stopping further propagation of the event.
    this.disableDefaultEvent = function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else if (event.returnValue) {
            event.returnValue = false;
        }
    }

    // method called when window is ready
    this.ready = function() {
        this.imgInterval = setInterval("lvsys.imgCheckStatus()", 1000);
    }

    // method hides a group of rows
    this.uiToggleGroup = function(options) {
        var idButton = options['button'];
        var group = options['group'];
        var imgShow = options['imgShow'];
        var imgHide = options['imgHide'];

        // collapse the rows
        var img = $("#" + idButton).attr("src");
        var bShow = (img == imgShow);

        $("*[group='" + group + "']").each(function(i) {
            if (bShow) {
                if ($(this).is("tr")) {
                    $(this).css("display", ""); // jQuery show() does not work well for TR
                } else {
                    $(this).show("fast");
                }
            } else {
                if ($(this).is("tr")) {
                    $(this).css("display", "none"); // jQuery show() does not work well for TR
                } else {
                    $(this).hide("fast");
                }
            }
        });
        if (bShow) {
            $("#" + idButton).attr("src", imgHide);
        } else {
            $("#" + idButton).attr("src", imgShow);
        }
    }
}

// load lvsys when the document is ready
var lvsys = new lvsys();
$(document).ready(function() {
    lvsys.ready();
});
