// Hierarchical Select Menu script by Flooble.com.
// --------------------------------------------------------------------------------------
// Copyright(c) 2004 Animus Pactum Consulting Inc.
// This script is provided as is,without any warranties whatsoever.
// You may modify and re-distribute this script as long as you do not remove this notice.
// Go to http://www.flooble.com/scripts/hier.php for more information.
// --------------------------------------------------------------------------------------
// the drop-down part of this was originally written by flooble.com
// user-friendliness applied by Kae Verens,webworks.ie,May-August 2004 - kae@verens.com
// same rules apply for re-distribution - please keep the notices in.

// various global variables
var currentMenu=0;var selectMenus=new Array();var currentSelections=new Array();
var optionsCount=0;var selectOverMenu=false;var selectOpenSubmenus=new Array();
var selectMenuOpen=false;var selectSubmenuCount=0;var selectOptions=new Array();
var selectTimerParent;var selectSubmenuTimer;
var selectHighlightedObject=false;var HierSelect=0;var hierselectRecArr=new Array();
var submenuItems=6;var used=0;var dropdownMinWidth=200;

// because IE5 and IE6 are stupid piles of ...., select-boxes need to be hidden when this script is activated
var toHide=new Array();
function selectsHack(v){
 for(var i=0,n=toHide.length;i<n;i++){
  toHide[i].style.visibility=v;
 }
}
 

// browser dependant variables
var ie=(document.all)?true:false;
var selectRightArrow=(ie)?'&gt;':'&#x25BA;';

// translate <select> elements into javascript arrays
function createHierSelect(){
 // doesn't work in IE5 or Opera
 agent=navigator.userAgent;
 if(agent.indexOf('MSIE 5.0')>-1||agent.indexOf('Opera')>-1)return;
 // loop until all instances are found and converted
 do{
  found=0;
  a=document.getElementsByTagName('select');
  for(b=0;a[b];b++){
   if(a[b].className=='hierselect'){
    found=1;
    j=a[b].name;
    HierSelect=used;
    selectMenus[j]=HierSelect;
    selectOptions[used++]=HierSelect+'|| -- please choose -- ||';
    c=a[b].getElementsByTagName('optgroup');
    for(d=0;c[d];d++){
     selectOptions[used]=HierSelect+'||'+c[d].label+'||@@'+HierSelect+'.'+used; // sub-menu
     f=c[d].getElementsByTagName('option');arr=new Array();
     for(g=0;f[g];g++)arr[g]=new Array(f[g].innerHTML,f[g].value);
     hierselectBuildSubMenu(HierSelect+'.'+used+'||',arr,HierSelect+'.'+(used++),0);
    }
    h=document.createElement('a');h.className='hierselectTop';
    h.id=j;h.href="javascript:openSelect(document.getElementById('"+j+"'));";
    addEvent(h,'mouseover',selectMouseOver);
    addEvent(h,'mouseout',selectMouseOut);
    i=document.createElement('input');
    i.type='hidden';i.id=j+'_field';i.name=j;
    a[b].parentNode.insertBefore(h,a[b]);
    a[b].parentNode.insertBefore(i,a[b]);
    a[b].parentNode.removeChild(a[b]);
    selectRelateMenu(j);
   }
  }
 }while(found);
 if(agent.indexOf('MSIE')>-1){
  // find all non-hierselect select boxes on page (must be hidden in IE when hierselect is active)
  toHide=document.getElementsByTagName('select');
 }
}

// build submenus (ugly because of javascript's stupid variable scoping)
function hierselectBuildSubMenu(prefix,arr,hierselectPre,depth){
 hierselectRecArr[depth]=new Array();hierselectRecArr[depth]['prefix']=prefix;
 hierselectRecArr[depth]['arr']=arr;hierselectRecArr[depth]['hierselectPre']=hierselectPre;
 arrsize=hierselectRecArr[depth]['arr'].length;
 if(arrsize<=submenuItems||arrsize>submenuItems*3){
  hierselectRecArr[depth]['step']=Math.ceil(arrsize/submenuItems);
 }else{
  hierselectRecArr[depth]['step']=Math.ceil(arrsize/3);;
 }
 if(hierselectRecArr[depth]['step']<1)hierselectRecArr[depth]['step']=1;
 for(hierselectRecArr[depth]['g']=0;hierselectRecArr[depth]['g']<hierselectRecArr[depth]['arr'].length;hierselectRecArr[depth]['g']+=hierselectRecArr[depth]['step']){
  step=hierselectRecArr[depth]['step'];g=hierselectRecArr[depth]['g'];
  hierselectPre=hierselectRecArr[depth]['hierselectPre'];newArr=new Array();
  arrsize=hierselectRecArr[depth]['arr'].length;
  if(step>1){
   firstname=hierselectRecArr[depth]['arr'][g][0];
   if(firstname.length>30)firstname=firstname.substr(0,27)+'...';
   lastname=(hierselectRecArr[depth]['arr'][g+step-1])?hierselectRecArr[depth]['arr'][g+step-1][0]:hierselectRecArr[depth]['arr'][arrsize-1][0];
   if(lastname.length>30)lastname=lastname.substr(0,27)+'...';
   selectOptions[used]=hierselectPre+'||'+firstname+' <i>to</i> '+
    lastname+'||@@'+hierselectPre+'.'+used; // sub-menu
   for(h=0;(h<step)&&(h+g<hierselectRecArr[depth]['arr'].length);h++){
    newArr[h]=new Array(hierselectRecArr[depth]['arr'][h+g][0],hierselectRecArr[depth]['arr'][h+g][1]);
   }
   depth=hierselectBuildSubMenu(hierselectPre+'.'+hierselectRecArr[depth]['g']+'||',newArr,hierselectPre+'.'+(used++),1+depth);
  }else{
   selectOptions[used++]=hierselectRecArr[depth]['prefix']+hierselectRecArr[depth]['arr'][g][0]+'||'+hierselectRecArr[depth]['arr'][g][1];
  }
 }
 return -1+depth;
}

// cross-browser event attaching
function addEvent(el,ev,fn){
 if(el.attachEvent)el.attachEvent('on'+ev,fn);
 else if(el.addEventListener)el.addEventListener(ev,fn,false);
}
// cross-browser css creation
function addRule(rule){
 if(document.styleSheets){
  if(document.styleSheets.length){
   // DOM-compliant
   if(document.styleSheets[0].insertRule){document.styleSheets[0].insertRule(rule,0);}
   // IE
   else{arr=rule.split('{');s=arr[0];r=arr[1].split('}');document.styleSheets[0].addRule(s,r);}
  }else alert("you must provide a stylesheet (even a blank file will do!)\nfor this script to work");
 }
}

// return objects(IE and DOM)
function getObj(id){return(ie)?document.all[id]:document.getElementById(id);}

function selectGetOptions(level){
 var option;var returnArray=new Array();
 for(i=0;i<selectOptions.length;i++){
  option=selectOptions[i];
  if(option.substring(0,level.length+2)==''+level+'||'){
   returnArray[returnArray.length]=selectGetOptionLink(option,i);
  } 
 }
 return returnArray;
}
 
function selectGetOptionLink(option,index){
 var start=option.indexOf('||');var finish=option.lastIndexOf('||');var level=option.substring(0,start);
 var prefix=option.substring(start+2,finish);var suffix=option.substring(finish+2,option.length);
 if(suffix.indexOf('@@')==0){
  // is a submenu
  var parentIndex=level.substring(level.lastIndexOf('.')+1,level.length);
  if(option.indexOf(''+parentIndex)!=0) parentIndex++;
  return '<div class="select_inner_div" onmouseover="selectHighlight(this);selectOpenTimer('+(index+1)+',\''+suffix+'\',this,'+parentIndex+');" onmouseout="selectLowlight(this);selectCancelOpenTimer();" onClick="selectOpenSubmenu('+(index+1)+',\''+suffix+'\',this,'+parentIndex+');"><span>'+prefix+' '+selectRightArrow+'</span></div>';
 }else{
  // is an option
  return '<div class="select_inner_div" onmouseover="selectHighlight(this);" onmouseout="selectLowlight(this);" onClick="selectPickValue('+index+',\''+suffix+'\');"><span>'+prefix+'&nbsp;</span></div>';
 }
}

function selectOpenTimer(index,suffix,parent,parentIndex){
 selectTimerParent=parent;
 var command='selectOpenSubmenu('+index+',\''+suffix+'\',selectTimerParent,'+parentIndex+')';
 selectSubmenuTimer=setTimeout(command,200);
}
 
function selectCancelOpenTimer(){clearTimeout(selectSubmenuTimer);}
 
function selectHighlight(div,index){
 if(selectHighlightedObject)selectLowlight(selectHighlightedObject);
 div.className='select_inner_active';
 selectHighlightedObject=div;
}

function selectLowlight(div){div.className='select_inner_div';}

function selectGetOptionName(index){
 var option=selectOptions[index];
 return option.substring(option.indexOf('||')+2,option.lastIndexOf('||'));
}
 
function selectGetOptionGroup(index){
 var option=selectOptions[index];
 return option.substring(0,option.indexOf('||'));
}
 
function openSelect(parent){
 // displays the submenu of the selected parent
 var openMenu=true;
 if(selectMenuOpen){
  openMenu=(selectMenuOpen!=parent.id);
  var index=currentSelections[selectMenuOpen];var option=selectOptions[index];
  selectPickValue(index,option.substring(option.lastIndexOf('||')+2,option.length));
 } 
 if(openMenu){
  selectMenuOpen=parent.id;
  var div=selectGetSubMenu(selectMenus[parent.id]);
  div.style.visibility='hidden';
  div.style.display='block';
  div.style.zIndex='101';
  selectPositionMenu(div,parent);
  div.style.visibility='visible';
  if(div.scrollWidth<dropdownMinWidth){div.style.width=dropdownMinWidth;}
  selectOpenSubmenus[selectSubmenuCount++]=selectMenus[parent.id];
 }
}
 
function selectRelateMenu(menuName){
 var field=getObj(menuName+'_field');var value=field.value;
 var startIndex=''+selectMenus[menuName];var label;var option;
 var index=startIndex;
 if(value!=''){
  for(i=0;i<selectOptions.length;i++){
   option=selectOptions[i];
   if(option.substring(0,startIndex.length)==startIndex){
    if(option.substring(option.lastIndexOf('||')+2,option.length)==value)index=i;
   }
  }
 }
 currentSelections[menuName]=index;
 label=selectGetOptionName(index);
 getObj(menuName).innerHTML=label;
}

var colors=['#fff','#eee','#ddd','#ccc','#bbb'];

function selectOpenSubmenu(index,suffix,parent,parentIndex){
 for(i=selectSubmenuCount;selectOpenSubmenus[i-1]!=parentIndex;i--){
  idx=selectOpenSubmenus[i-1];
  div=getObj('select_div_'+idx);
  div.style.display='none';
  selectSubmenuCount--;
 }
// parent.style.background='#666';
// parent.style.color='#fff';
 var div=selectGetSubMenu(index);
 div.style.background=colors[selectSubmenuCount];
 div.style.visibility='hidden';
 div.style.display='block';
 div.style.zIndex=100+index;
 if(div.scrollWidth<100){ div.style.width=100;}
 selectPositionMenu(div,parent);
 div.style.visibility='visible';
 selectOpenSubmenus[selectSubmenuCount++]=index;
}
 
function selectPositionMenu(menu,parent){
 selectsHack('hidden');
 // position submenus
 menu.style.top=1;menu.style.left=1;
 if(parent.id==selectMenuOpen){
  // submenu is directly below root of menu
  menu.style.left=selectGetAbsoluteOffsetLeft(parent);
  y=selectGetAbsoluteOffsetTop(parent)+parent.scrollHeight;
  if(y>document.body.offsetHeight/2)
   menu.style.top=selectGetAbsoluteOffsetTop(parent)-menu.scrollHeight;
  else
   menu.style.top=selectGetAbsoluteOffsetTop(parent)+parent.scrollHeight;
 }else{
  // submenu is beside another submenu
  menu.style.left=(selectGetAbsoluteOffsetLeft(parent)+80+menu.scrollWidth>document.body.offsetWidth)?
   selectGetAbsoluteOffsetLeft(parent)-(menu.scrollWidth-80):   // menu on left
   selectGetAbsoluteOffsetLeft(parent)+80; // menu on right
  menu.style.top=selectGetAbsoluteOffsetTop(parent)+5;
 }  
}
 
function selectPickValue(index,value){
 var idx,div;
 for(i=selectSubmenuCount;i;i--){
  idx=selectOpenSubmenus[i-1];div=getObj('select_div_'+idx);div.style.display='none';
 }
 selectSubmenuCount=0;
 currentSelections[selectMenuOpen]=index;
 getObj(selectMenuOpen).innerHTML=selectGetOptionName(index);
 getObj(selectMenuOpen+'_field').value=value;
 selectMenuOpen=false;
 selectsHack('visible');
}
 
function selectGetSubMenu(index){
 var div=getObj('select_div_'+index);if(div==null)div=selectBuildDivFor(index);return div;
}
 
function selectBuildDivFor(index){
 var elemDiv=document.createElement('div');
 elemDiv.id='select_div_'+index;elemDiv.className='select_pulldown';
 elemDiv.style.position='absolute';elemDiv.style.display='none';
 addEvent(elemDiv,'mouseover',selectMouseOver);addEvent(elemDiv,'mouseout',selectMouseOut);
 var options=selectGetOptions(selectGetOptionGroup(index));
 for(i=0;i<options.length;i++)elemDiv.innerHTML=elemDiv.innerHTML+options[i];
 document.body.appendChild(elemDiv);
 return elemDiv;  
}
 
function selectMouseOver(){selectOverMenu=true;}
 
function selectMouseOut(){selectOverMenu=false;}
 
// calculate top position of element
function selectGetAbsoluteOffsetTop(obj){
 var top=obj.offsetTop;var parent=obj.offsetParent;
 while(parent!=document.body){top+=parent.offsetTop;parent=parent.offsetParent;}
 return top;
}

// calculate left position of element
function selectGetAbsoluteOffsetLeft(obj){
 var left=obj.offsetLeft;var parent=obj.offsetParent;
 while(parent!=document.body){left+=parent.offsetLeft;parent=parent.offsetParent;}
 return left;
}

// check if a document click has to do with the menus
function selectCheckClick(){
 if(selectMenuOpen&&!selectOverMenu){
  var index=currentSelections[selectMenuOpen];
  var option=selectOptions[index];
  selectPickValue(index,option.substring(option.lastIndexOf('||')+2,option.length));
 }
 return true;
}

// load generic css to make the thing look similar to select lists
function loadHierSelectCSS(){
 addRule('.select_pulldown{background:#fff;border:1px solid #000;}');
 addRule('.select_inner_active{border-bottom:1px solid #000;background:#900;}');
 addRule('.select_inner_active span{display:block;color:#fff;}');
 addRule('.select_inner_div{border-bottom:1px solid #eee;}');
 addRule('.select_inner_div span{display:block;}');
 addRule('a.hierselectTop{text-decoration:none;color:#000;border:solid;border-width:2px 1px 1px 2px;border-color:#404040 #c0c0c0 #c0c0c0 #404040;background:#fff url(/i/drop.png) right top no-repeat;height:21px;padding:0 19px 0 3px;width:'+dropdownMinWidth+'px;}');
}

addEvent(window,'load',loadHierSelectCSS);   // load CSS for dropdown thing
addEvent(window,'load',createHierSelect);    // do the conversion
addEvent(document,'click',selectCheckClick); // add a click event handler for handling the dropdowns
