/*  Copyright Shao Ming, 2006  |
 * ------------------------------------------------------------------
 *
 * Signetique AJAX Library, version 0.0.2.20060711
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 */

// sajax.js

//Function

/*
Add ietruebody function
Fandy Gotama
12-7-2005
*/
function ietruebody(){
        return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}
/* End */

// Tab Browser

var TabBrowse = Class.create();

TabBrowse.prototype = {

    initialize: function(element) {
        this.element = $(element);
        this.curTab = 0;
        this.loadstatustext="<br /> <img src='js/searching.gif' /> <font color='red'> retrieving content ...</font><br /><br />";
        // display area
        this.mcont = this.element.getAttribute("cont");
        this.wkflow = this.element.getAttribute("wkflow");
        // array containing the LI elements within UL
        var ulist=this.element.getElementsByTagName("li");
        this.ulist=$A(ulist);
        //loop through each LI element
        for (var x=0; x<this.ulist.length; x++){
            // always use LI's own 'cont', if available
            // if 'cont' is undefine, use the UL's 'mcont'
            var _save=null;
            var _url=this.ulist[x].getAttribute("href");
            var _cache=this.ulist[x].getAttribute("cache");
            var _cont=$(this.ulist[x].getAttribute("cont"))==undefined ? null : this.ulist[x].getAttribute("cont");
            var _status = ( this.ulist[x].getAttribute("inactive")==1 ) ? 0 : 1;
            var child = {
                id: x,
                url: _url,
                cache: _cache,
                cont: _cont,
                status: _status,
                save: null,
                jscript: null
            }
            this.ulist[x].info = child;
            if (this.ulist[x].className=="selected"){
                this.curTab=x;
            }
            if(_url!=null || _cont!=null) {
                Event.observe(this.ulist[x], 'click', this.tabClick.bindAsEventListener(this), false);
            }
        }
        this.paint();
    },

    tabClick: function(evnt) {
        if(this.curTab==Event.element(evnt).info.id || (Event.element(evnt).info.status!=1)) {
            return;
        }
        this.saveContent();
        this.curTab=Event.element(evnt).info.id;
        this.paint();
    },

    saveContent: function() {
        // cache current tab content, if
        // - does not have its own 'cont'
        // - cache is enabled
        if(this.ulist[this.curTab].info.cont==null && this.ulist[this.curTab].info.cache==1) {
            this.ulist[this.curTab].info.save=$(this.mcont).innerHTML;
        }
        // 'save' is used as a flag to denote LI's cont has been ajaxed
        // do not set this flag if cache has not been enabled
        if(this.ulist[this.curTab].info.cont!=null && this.ulist[this.curTab].info.cache==1) {
            this.ulist[this.curTab].info.save = 1;
        }
    },

    paint: function() {
        // clear selection
        this.ulist.each(
            function(tab){
			    tab.className=(tab.info.status!=1) ? "inactive" : "";
			    if(tab.info.cont!=null) {
			        Element.hide(tab.info.cont);
			    }
		    }
		);
        // highlight selected tab
		this.ulist[this.curTab].className="selected";
		// re-paint the tab area
        this.page();
    },

    page: function() {
        var target=this.mcont;
        var tab=this.ulist[this.curTab];
        if(tab.info.cont!=null) {
            target=tab.info.cont;
            Element.hide(this.mcont);
            Element.show(tab.info.cont);
        } else {
            Element.show(this.mcont);
        }

        // ajax when
        // - cache not enabled
        // - save is uninitialised
        // - url is defined
        if(tab.info.cache==0 || (tab.info.save==null && tab.info.url!=null)) {
            $(target).innerHTML=this.loadstatustext;
            var pars = '';
            var myAjax = new Ajax.Updater(
            {success: target,
             // failure: null   },
             failure: target   },
             tab.info.url,
            {
                method: 'get',
                parameters: pars,
                evalScripts: true,
                onSuccess: this.captureScript.bindAsEventListener(this.ulist[this.curTab])
            });
        } else {
            // if LI does not have owns 'cont', populate content to mcont
            if(tab.info.cont==null) {
                $(target).innerHTML=tab.info.save;
                if(tab.info.jscript!=null) {
                    for (var i = 0; i < tab.info.jscript.length; i++) {
                        if(tab.info.jscript[i]) {
                            eval(tab.info.jscript[i]);
                        }
                    }
                }
            }
        }

    },

    captureScript: function(a) {
        // the html code displayed by prototype at the 'mcont' is
        // without the javascript code
        // this tweak is to extract out the javascript before they disappear
        var myCode = new String(a.responseText);
        this.info.jscript = myCode.extractScripts();
        //$(_ajaxRespond).innerHTML=a.responseText;
    },

    add: function(_name,_url,_cont,_cache) {
        // ignore add if tag name is the same
        var _curTab=null;
        this.ulist.each(
            function(tab){
			    if(tab.innerHTML==_name) {
			        _curTab=tab.info.id;
			    }
		    }
		);
        if(_curTab!=null) {
            this.curTab=_curTab;
            this.ulist[_curTab].info.url=_url;
            this.ulist[_curTab].info.cache=_cache;
            this.ulist[_curTab].info.cont=_cont;
            this.ulist[_curTab].info.save=null;
            this.ulist[_curTab].info.jscript=null;
        } else {
            var li = document.createElement('li');
            _cont=$(_cont)==undefined ? null : _cont;
            var x = this.ulist.length;
            var child = {
                id: x,
                url: _url,
                cache: _cache,
                cont: _cont,
                save: null,
                jscript: null
            }
            li.info = child;
            li.className="selected";
            li.appendChild(document.createTextNode(_name));
            this.element.appendChild(li);
            var ulist=this.element.getElementsByTagName("li");
            this.ulist=$A(ulist);
            if(_url!=null || _cont!=null) {
                Event.observe(this.ulist[x], 'click', this.tabClick.bindAsEventListener(this), false);
            }
            this.curTab=x;
        }
        this.paint();
    },

    subform: function(_form,_index) {
        if(_index==null) {
            _index=this.curTab;
        }
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            this.saveContent();
            this.curTab=_index;
            var pars = Form.serialize(_form);
            tab.info.cache=1;
            tab.info.save=null;
            tab.info.jscript=null;
            tab.info.url=_form.action + '?' + pars;
            // alert(tab.info.url);
            tab.info.status=1;
            this.invalidateTab();
            this.paint();
        }

    },

    invalidateTab: function() {
        var wkflow = this.wkflow;
        var curTab = this.curTab;
        this.ulist.each(
            function(tab){
			    if(wkflow==1) {
			        if(tab.info.id > curTab) {
			            tab.info.status=0;
                        tab.info.save=null;
                        tab.info.jscript=null;
			            // tab.className="inactive";
			        }
			    }
			}
		);
	},

    go: function(_index,_url,_newname) {
        if(_index==null) {
            _index=this.curTab;
        }
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            this.saveContent();
            this.curTab=_index;
            tab.info.save=null;
            tab.info.url=_url;
            if(_newname!=null) {
                tab.innerHTML=_newname;
            }
            tab.info.status=1;
            this.invalidateTab();
            this.paint();
        }
    },

    setCache: function(_index,_cache) {
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            tab.info.cache=(_cache==0) ? 0 : 1;
        }
    },

    refresh: function(_index) {
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            tab.info.save=null;
            this.curTab=_index;
            this.paint();
        }
    },

    rename: function(_index,_newname) {
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            tab.innerHTML=_newname;
        }
    },

    status: function(_index,_state) {
        var tab=this.ulist[_index];
        if(tab!=undefined) {
            tab.info.status=(_state==0) ? 0 : 1;
        }
    }

}

////////////////////////////////////////////////

// Live List

var LiveList = Class.create();

LiveList.prototype = {

    initialize: function(_element,_target,_url,_targetVal,_initHsh,_curVal,_waiting,_defaultFirstValueName) {
        this.element = $(_element);
        this.target = $(_target);
        this.url = _url;
        this.targetVal = _targetVal;
        this.initHsh = _initHsh;
        this.curVal = _curVal;
        this.waiting = _waiting;
        this.defaultName = _defaultFirstValueName;

        this.pars = null;
        this.timer = null;

        Event.observe(this.element, 'change', this.ajaxList.bindAsEventListener(this), false);
        if(this.initHsh) {
            this.initList()
        }
        if(this.targetVal!=null||this.curVal!=null) {
            this.timer = self.setTimeout(this.ajaxWait.bind(this), 500);
        }
    },

    // incase the list is dependent on another list that also has to be ajaxed
    ajaxWait: function() {
        clearTimeout(this.timer);
        if($F(this.element)!=0) {
            this.ajaxList();
        } else {
            this.timer = self.setTimeout(this.ajaxWait.bind(this), 500);
        }
    },

    initList: function() {
      var llist = this;
    	for(var j=llist.element.options.length-1;j>0;j--) {
                llist.element.options[j]=null;
    	}
    	var j=0;
    	llist.element.options[j++]=new Option(this.defaultName,0);
        $H(this.initHsh).each(
            function tmp(id) {
                llist.element.options[j++]=new Option(id.value,id.key);
                if(id.key==llist.curVal) {
                    llist.element.options[j-1].selected=true;
                }
            }
        );
    },

    ajaxList: function() {
        if($F(this.element)=='0') { return; }
        this.pars = 'id=' + $F(this.element);

        var myAjax = new Ajax.Request(
        this.url,
        {
            method: 'get',
            parameters: this.pars,
            onComplete: this.processResponse.bindAsEventListener(this)
        });
        if($(this.waiting)!=undefined) {
            Element.show(this.waiting);
        }
    },

    processResponse: function(oReq) {
		var xmlDoc = oReq.responseXML;

		var results=xmlDoc.getElementsByTagName("rs")[0];
		for(var j=this.target.options.length-1;j>0;j--) {
                this.target.options[j]=null;
		}
		this.target.options[0]=new Option(this.defaultName,0);
		var rec_i = results.getElementsByTagName("i");
		var rec_d = results.getElementsByTagName("d");
        for (var j = 0; j < rec_d.length; j++) {
            this.target.options[j+1]=new Option(rec_d[j].firstChild.nodeValue,rec_i[j].firstChild.nodeValue);
            if(rec_i[j].firstChild.nodeValue==this.targetVal) {
                this.targetVal=null;
                this.target.options[j+1].selected=true;
            }
        }
	    if($(this.waiting)!=undefined) {
		    Element.hide(this.waiting);
		}
	}

}

////////////////////////////////////////////////

// Live Result

var LiveResult = Class.create();

LiveResult.prototype = {

    initialize: function(_element,_target,_url,_form,_timeout,_minlen,_waiting) {
        this.element = $(_element);
        this.target = $(_target);
        this.url = _url;
        this.srchform = _form;
        this.timeout = _timeout;
        this.minlen = _minlen;
        this.waiting = _waiting;
        this.srchstr = '';
        this.lastsrch = '';
        this.idletimer = '';
        this.dirty = 0;
        Event.observe(this.element, 'keyup', this.keyIsUp.bindAsEventListener(this), false);
    },

    keyIsUp: function(evnt) {
        this.srchstr = $F(this.element);
        if(this.srchstr.length >= this.minlen) {
            clearTimeout(this.idletimer);
            this.idletimer = self.setTimeout(this.srch.bind(this), this.timeout);
        };
    },

    srch: function() {
        if(this.lastsrch==this.srchstr&&this.dirty==0) {
            return;
        }
        this.lastsrch=this.srchstr;
        this.dirty=0;
        var pars = Form.serialize(this.srchform);
        var myAjax = new Ajax.Updater(
        {success: this.target},
        this.url,
        {
            method: 'get',
            parameters: pars,
            evalScripts: true,
            onComplete: this.processResponse.bindAsEventListener(this)
        });
        if($(this.waiting)!=undefined) {
            Element.show(this.waiting);
        }
    },

    processResponse: function(oReq) {
	    if($(this.waiting)!=undefined) {
		    Element.hide(this.waiting);
		}
	},

    showall: function() {
        this.dirty=1;
        $F(this.element) = '';
        Form.reset(this.srchform);
        this.srch();
    },

    goPage: function(pgno) {
        $(pg).options[pgno-1].selected=true;
        this.updrslt();
    },

    updrslt: function() {
        this.dirty=1;
        this.srch();
    }

}

////////////////////////////////////////////////

// Live Tip

var LiveTip = Class.create();

LiveTip.prototype = {

    initialize: function(element) {
        this.tlist=element;
        this.curTab = 0;
        this.cache = [];
        this.loadstatustext="<table border='0' cellpadding='0' cellspacing='0'><tr height='20'><td align='center' width='30'><img src='js/searching.gif'></td><td><font color='red' face='verdana' size='2'> retrieving content...</font></td></tr></table>";
        this.timer = null;

        for (var x=0; x<this.tlist.length; x++){
            if($(this.tlist[x])==undefined) { return; }
            var tip = $(this.tlist[x]);
            var child = {
                id: x,
                url: tip.getAttribute("href"),
                cont: $(tip.getAttribute("cont"))==undefined ? null : tip.getAttribute("cont"),
                dispx: tip.getAttribute("dispx"),
                dispy: tip.getAttribute("dispy"),

                /*
                Add tipHeight Property to adjust tip's height
                Fandy Gotama
                12-7-2005
                */
                tipHeight: tip.getAttribute("tipHeight"),
                /* End */

                save: null
            }
            tip.info = child;
            Event.observe(tip, 'click', this.showTip.bindAsEventListener(this), false);
            Event.observe(tip, 'mouseout', this.mouseIsOut.bindAsEventListener(this), false);
        }
        return;
    },

    showTip: function(evnt) {
        if(this.timer!=null) { clearTimeout(this.timer); }
        this.curTab=Event.element(evnt).info.id;
        var tip=$(this.tlist[this.curTab]);
        var tipobj=$(tip.info.cont);
        var tipobjx = (tipobj.style.width!='') ? parseInt(tipobj.style.width) : 300;

				/*
        Add ie and ns6 variable to detect browser type
        Fandy Gotama
        12-7-2005
        */
		var ie=document.all
        var ns6=document.getElementById && !document.all
        /* End */

        var offsetx=10;
        var offsety=10;

        /*
        Add code to adjusted tip's vertical and horizontal position
        Fandy Gotama
        12-7-2005
        */
        var curX=(ns6)?evnt.pageX : event.clientX+ietruebody().scrollLeft;
        var curY=(ns6)?evnt.pageY : event.clientY+ietruebody().scrollTop;
        var rightedge=ie&&!window.opera? ietruebody().clientWidth-event.clientX-offsetx : window.innerWidth-evnt.clientX-offsetx-20
        var bottomedge=ie&&!window.opera? ietruebody().clientHeight-event.clientY-offsety : window.innerHeight-evnt.clientY-offsety-20

        var leftedge=(offsetx<0)? offsetx*(-1) : -1000

        //if the horizontal distance isn't enough to accomodate the width of the context menu
        if (rightedge<curX)
        //move the horizontal position of the menu to the left by it's width
        tipobj.style.left=ie? ietruebody().scrollLeft+event.clientX-tipobjx-10+"px" : window.pageXOffset+evnt.clientX-tipobjx-10+"px"
        else if (curX<leftedge)
        tipobj.style.left="5px"
        else
        //position the horizontal position of the menu where the mouse is positioned
        tipobj.style.left=curX+offsetx+"px";


        tip.info.tipHeight = parseInt(tip.info.tipHeight);

        //same concept with the vertical position
        if (bottomedge<tip.info.tipHeight)
        tipobj.style.top=ie? ietruebody().scrollTop+event.clientY-tip.info.tipHeight-offsety+"px" : window.pageYOffset+evnt.clientY-tip.info.tipHeight-offsety+"px"
        else
        tipobj.style.top=curY+offsety+"px"
        tipobj.style.visibility="visible"
		/* End */

		/*
        Remark tip's vertical and horizontal original code
        Fandy Gotama
        12-7-2005
        */
        //var curX=evnt.pageX || (evnt.clientX+(document.documentElement.scrollLeft || document.body.scrollLeft));
        //var curY=evnt.pageY || (evnt.clientY+(document.documentElement.scrollTop || document.body.scrollTop));
        //tipobj.style.left=(tip.info.dispx=='L') ? curX-offsetx-tipobjx+"px" : curX+offsetx+"px";
        //tipobj.style.top=curY+offsety+"px";
        /* End */

        Element.show(tipobj);
        var target=tip.info.cont;
        // test for cache entry
        if(tip.info.save==null && tip.info.url!=null) {
            this.cache.each(function(id) {
                if(id.key==tip.info.url) {
                    tip.info.save=id.value;
                }
            });
        }
        if(tip.info.save==null && tip.info.url!=tip.info.cont) {
            $(target).innerHTML=this.loadstatustext;
            var pars = '';
            var myAjax = new Ajax.Updater(
            {success: target,
             // failure: null   },
             failure: target   },
             tip.info.url,
            {
                method: 'get',
                parameters: pars,
                evalScripts: false,
                onSuccess: this.saveContent.bindAsEventListener(tip)
            });
        } else {
            if(tip.info.save!=null) {
                $(target).innerHTML=tip.info.save;
            }
        }
        Event.stop(evnt);
    },

    mouseIsOut: function(evnt) {
        this.curTab=Event.element(evnt).info.id;
        var tip=$(this.tlist[this.curTab]);
        var tipobj=$(tip.info.cont);
        Event.observe(tipobj, 'mouseover', this.mouseIsIn.bindAsEventListener(this), false);
        this.timer = self.setTimeout(this.hideTip.bind(this), 500);
    },

    mouseIsIn: function(evnt) {
        if(this.timer!=null) { clearTimeout(this.timer); }
        var tip=$(this.tlist[this.curTab]);
        var tipobj=$(tip.info.cont);
        Element.show(tipobj);
        Event.observe(tipobj, 'mouseout', this.hideTip.bindAsEventListener(this), false);
    },

    hideTip: function(evnt) {
        if(this.timer!=null) { clearTimeout(this.timer); }
        var tip=$(this.tlist[this.curTab]);
        Element.hide(tip.info.cont);
        // save content to cache
        var pair = { key: '', value: '' };
        pair.key=tip.info.url;
        pair.value=tip.info.save;
        this.cache.push(pair);
    },

    saveContent: function(a) {
        var myCode = new String(a.responseText);
        this.info.save=myCode;
    }

}


