/*****
 THIS CODE IS FREE TO BE DISTRIBUTED
 I do not claim that this will work same across all browsers.. 
*/

gTreeSelect = Class.create();

gTreeSelect.prototype = {
    initialize: function(obj,url){
        this.url = url;
        this.obj = obj;
        this.fetched = [];
        this.selOpts = $(obj).options;
        $(obj).selectedIndex = -1;
        this.multiple = false;
        if($(obj).parentNode.innerHTML.toLowerCase().indexOf('multiple') >= 0)
            this.multiple = true;
        this.id = Math.random().toString().substring(3,9);
        var p = '<div id="gts_' + this.id + '" class="selectorOuter"></div>';
        Element.insert($(obj).parentNode, {bottom: p});
         p = '<div id="bc_' + this.id + '" class="breadCrumbs"></div>';
         p += '<div id="busy_' + this.id + '" style="display:none">'
         p += '<img src="busy.gif" border="0" /> </div>'

        Element.insert($(obj).parentNode, {after: p});
        $(this.obj).hide();
        this.throbber = $('busy_' + this.id);
        this.breadCrumbDiv = $('bc_' + this.id);
        Element.setStyle($(obj).parentNode, {"height" : $('gts_' + this.id).getHeight() + "px"});
        this.ginitSelector();
    },
    ginitSelector: function(){
        this.selectedId = $(this.obj).options[0].value;
        this.throbber.show();
        var param='v=2&init=true&id=' + this.selectedId;
        var getter = new Ajax.Request(
                this.url,
                { method: 'POST', parameters: param, onComplete: this.gSetOptsInit.bindAsEventListener(this) }
                );
    },
    appendAfter: function(pos, aOptions, setSelection){
        var objToupdate = 'gts_' + this.id;
        if(pos > 0)
            objToupdate = 'gtsli-' + this.id + '-' + pos;
        var p = '<ul>';
        var len = aOptions.length; 
        for(index = 0; index < len; index++){
                p += '<li id="gtsli-' + this.id + '-' + aOptions[index].value + '" class="level-'+pos+'">';
                p += aOptions[index].text + '</li>';
        }
        p += '</ul>';
        Element.insert(objToupdate, {bottom: p});
        for(index = 0; index < len; index++){
            Event.observe('gtsli-' + this.id + '-' + aOptions[index].value, 'click',
                this.selChange.bindAsEventListener(this));
            if(setSelection == true && aOptions[index].value == this.selectedId){
                  this.selectedObj = $('gtsli-' + this.id + '-' + aOptions[index].value);
              }
        }
    },
    selChange: function(evt){
        this.selectedObj = Event.element(evt);
        var sIndex = this.selectedObj.id.toString().split('-');
        this.selectedId = sIndex[2];
        if(this.selectedObj.hasClassName('level-0') == false){
           $(this.obj).options[0].value = sIndex[2];
           $(this.obj).value = sIndex[2];
        }
        if(this.fetched.include(this.selectedId) == false){
                this.throbber.show();
                this.fetched.push(this.selectedId);
                var param='v=2&id=' + this.selectedId;
                var getter = new Ajax.Request(
                        this.url,
                        { method: 'POST', parameters: param, onComplete: this.gSetOpts.bindAsEventListener(this) }
                        );
        }else
          this.setBreadCrumbs();
       $$("div#gts_" + this.id + " ul li").invoke('removeClassName','pChecked');
       this.selectedObj.addClassName('pChecked');
    },
    makeInitialSelectors: function(aOpts){
        var len = aOpts.length;
        for (var index = 0; index < len; index++){
            this.appendAfter(aOpts[index].parentID, aOpts[index].options, true);
            this.fetched.push(aOpts[index].parentID);
        }
    },
    gSetOptsInit: function(xhr){
       this.throbber.hide();
       try{
          eval('var myOpts = ' + xhr.responseText);
          this.makeInitialSelectors(myOpts);
          this.selectedObj.addClassName('pChecked');
          var gScroll = Position.positionedOffset(this.selectedObj) ;
          $('gts_' + this.id).scrollTop = gScroll[1] - ($('gts_' + this.id).getHeight() / 2);
       }catch(e){
          //alert(xhr.responseText);
       }
          this.setBreadCrumbs();
    },
    gSetOpts: function(xhr){
       this.throbber.hide();
       try{
          eval('var myOpts = ' + xhr.responseText);
          this.appendAfter(this.selectedId, myOpts, false);
          var gScroll = Position.positionedOffset(this.selectedObj);
          $('gts_' + this.id).scrollTop = gScroll[1];
       }catch(e){
          //alert(xhr.responseText);
       }
          this.setBreadCrumbs();
    },
    setBreadCrumbs: function(){
        var myA = this.selectedObj.ancestors();
        var len = myA.length - 1;
        var bc = [];
        for(var gindex = len; gindex >= 0; gindex--){
                var selParent = myA[gindex];
                if(selParent.tagName.toLowerCase() == 'li')
                        bc.push(selParent.firstChild.nodeValue);
        }
        bc.push(this.selectedObj.firstChild.nodeValue);
        this.breadCrumbDiv.update(bc.join('&nbsp;&raquo;&nbsp;'));
    }
};    

gDeepSelect = Class.create();
gDeepSelect.prototype = {
    initialize: function(obj,url){
        this.url = url;
        this.obj = obj;
        this.fetched = [];
        this.selOpts = $(obj).options;
        $(obj).selectedIndex = -1;
        this.id = Math.random().toString().substring(3,9);
        Event.observe(obj, 'change', this.selChange.bindAsEventListener(this));
    },
    selChange: function(evt){
        this.selectedId = $(this.obj).value;
        this.selectedObj = $(this.obj).selectedIndex;
        if(this.fetched.indexOf(this.selectedId) > -1) return;
        $('throbber').show();
        this.fetched.push(this.selectedId);
        var selText = $(this.obj).options[this.selectedObj].getAttribute("level");
        var param='v=1&id=' + this.selectedId + '&st=' + selText;
        var getter = new Ajax.Request(
                this.url,
                { method: 'POST', parameters: param, onComplete: this.gSetOpts.bindAsEventListener(this) }
                );
       $A($(this.obj).options).invoke('removeClassName','pChecked');
       $(this.obj).options[this.selectedObj].addClassName('pChecked');
    },
    gSetOpts: function(xhr){
       $('throbber').hide();
       if(xhr.responseText.indexOf('</option>') == -1) return;
       Element.insert($(this.obj).options[this.selectedObj], { after: xhr.responseText});
       $(this.obj).selectedIndex = this.selectedObj;
    }
};    

function setupApp(){
  if($('dsel')){
     var myDeepSel = new gDeepSelect('dsel','sel.php');
     $('dsel').show();
  }
  if($('tdeepsel'))
     var myTreeSel = new gTreeSelect('tdeepsel','sel.php', true);
}

Event.observe(window,'load', setupApp);
