/*  Copyright Shao Ming, 2006  |
 * ------------------------------------------------------------------
 *
 * Signetique AJAX Library, version 0.0.2.20060928
 *
 * 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

/* History
 *
 * 2006 09 28
 * LiveTip - use onClick to show/hide tip
 * TabBrowse - added delete funtion
 * TabBrowse - added 'id' parameter to add funtion
 *
 * 2006 07 12
 * Add ietruebody function - Fandy Gotama
 */

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");
        this.waitpic = (this.element.getAttribute("waitpic")!=undefined) ? 1 : 0;
        // 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)) {
            if(this.waitpic==1) {
                var today = new Date();
                $(target).innerHTML=this.loadstatustext + "<img src='" + this.element.getAttribute("waitpic") + "?" + today.getTime() + "' /><br /><br />";
            } else {
                $(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,_id,_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;
            if(_id!=null) {
                this.ulist[_curTab].id=_id;
            }
        } 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,
                status: 1,
                save: null,
                jscript: null
            }
            if(_id!=null) {
                li.id=_id;
            }
            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();
    },

    remove: function(_id) {
        var _list = this.ulist;
        _list.each(
            function(tab){
                // alert(tab.id);
                if(tab.id==_id) {
                    tab.parentNode.removeChild(tab);
                    if(tab.info.id==this.curTab) {
                        if(this.curTab>0) {
                            this.curTab--;
                        }
                    }
                }
            }
        );
        // reset e info id
        _ulist=this.element.getElementsByTagName("li");
        this.ulist=$A(_ulist);
        var _x=0;
        this.ulist.each(
            function(tab){
                tab.info.id=_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;
        this.element.value = '';
        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);
        }
        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);
        Event.observe(document,'click', this.hideTip.bindAsEventListener(this), false);
    },

    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;
    }

}

