function ListItem(value, name, selected, enabled) {
	this.value=value;
	this.name=name;
	this.selected=selected;
	this.enabled=enabled;
}

function ArrayList(len) {
	this.elements=new Array(len);
    this.incVal=10;
    this.length=0;
    this.maxLength=len;
    this.toString=function() {
		var retVal="";
		for (var i=0;i<this.length;i++) {
			retVal+=this.elements[i].name+';';
		}
		return retVal;
    }
    this.add=function(value, name) {
		this.manageArraySize();
		
		this.elements[this.length]=new ListItem(value, name, false, true);
		this.length++;
     }
     
     this.addFirst=function(value, name) {
		this.manageArraySize();
		
		for (var i=this.length+1;i>0;i--) {
			this.elements[i]=this.elements[i-1];
		}
		this.elements[0]=new ListItem(value, name, false, true);
		
		this.length++;
     }
     
     this.clear=function() {
		this.elements=new Array(10);
		this.maxLength=10;
		this.length=0;
     }
     this.remove=function (index) {
		if (index<this.length) {
			for (var i=index;i<this.length;i++) {
				this.elements[i]=this.elements[i+1];
			}
			this.length--;
		}
     }
     this.getItem=function(index) {
		return this.elements[index];
     }
     
     this.getItemValueByName=function(name) {
		for (var i=0;i<this.length;i++) {
			if (this.elements[i].name==name) return this.elements[i].value;
		}
		return null;
     }
     this.isItemSelected=function(index) {
		return this.elements[index].selected;
     }
     this.isItemSelectedByValue=function(value) {
		for (var i=0;i<this.length;i++) {
			if (this.elements[i].value==value) return this.elements[i].selected;
		}
     }
     this.isItemEnabledByValue=function(value) {
		for (var i=0;i<this.length;i++) {
			if (this.elements[i].value==value) return this.elements[i].enabled;
		}
     }

     this.hasItemByValue=function(value) {
		for (var i=0;i<this.length;i++) {
			if (this.elements[i].value==value) return true;
		}
		return false;
     }         

     this.setItemSelectedByValue=function(value, selected) {
		for (var i=0;i<this.length;i++) {
			if (this.elements[i].value==value) this.elements[i].selected=selected;
		}
     }
     this.setItemSelected=function(index, selected) {
		this.elements[index].selected=selected;
     }
     this.getItems=function () {
		return this.elements;
     }
     
     this.manageArraySize=function() {
		//increase size
		if (this.length>=this.maxLength) {
			var newLength=this.length+this.incVal;
			var elements_temp=new Array(newLength);
			for (var i=0;i<this.length;i++) {
				elements_temp[i]=this.elements[i];
			}
			this.elements=elements_temp;
			this.maxLength=newLength;
		}
     }
     
     this.getLength=function() {
		return this.length;
	 }
}

function IThelp_Controls() {
	this.elements=new ArrayList();
	this.add=function(value, name) {
		this.elements.add(value, name);
	}
	this.getControl=function(name) {
		return this.elements.getItemValueByName(name);
	}
}

var ith_controls=new IThelp_Controls();

function ListBox(id, width, height) {
	this.id=id;
	ith_controls.add(this, id);
	this.height=height;
	this.width=width;
	this.positionX=null;
	this.positionY=null;
	this.elements=new ArrayList(10);
	this.eventPool=new ArrayList(10);
	this.multipleSelection=true;
	this.toString=function () {
		return '<span id=\''+this.id+'\'>'+this.render()+'</span>'
	}
	this.render=function () {
		//alert('asdf');
		retVal='<div style=\''+(this.positionX!=null?'LEFT: '+this.positionX+'px; TOP: '+this.positionY+'px; POSITION: absolute; Z-INDEX: 101;':'')+';border:1px solid #000;background-color:#FFFFFF;width:'+this.width+'px;height:'+this.height+'px;overflow:auto\'>';
		for (var i=0;i<this.elements.getLength();i++) {
			//retVal+='<div>asdf</div>';
			retVal+='<div class=\''+(this.elements.getItem(i).enabled?(this.elements.getItem(i).selected?'lb_item_active':'lb_item'):'lb_item_disabled')+'\' id=\''+this.id+":"+this.elements.getItem(i).value+'\' onclick=\'dispatch("onClick", event)\'>'+this.elements.getItem(i).name+'</div>';
		}
		retVal+='</div>';
		return retVal;
	}
	this.setSelectedByValue=function (value, controlPressed) {
		var temp_arr=this.elements.getItems();
		for (var i=0; i<this.elements.getLength();i++) {
			if (temp_arr[i].value!=value.split(':')[1] && (!this.multipleSelection || !controlPressed)) {
				ith_getElementById(this.id+':'+temp_arr[i].value).className=(temp_arr[i].enabled?'lb_item':'lb_item_disabled');
				this.elements.setItemSelectedByValue(temp_arr[i].value, false);
			}
		}
		
		if (this.elements.isItemSelectedByValue(value.split(':')[1]) && controlPressed) {
			ith_getElementById(value).className='lb_item';
			this.elements.setItemSelectedByValue(value.split(':')[1], false);
		}
		else if (this.elements.isItemEnabledByValue(value.split(':')[1])) {
			ith_getElementById(value).className='lb_item_active';
			this.elements.setItemSelectedByValue(value.split(':')[1], true);
		}
	}
	
	this.setAll=function(selected) {
		var temp_arr=this.elements.getItems();
		for (var i=0; i<this.elements.getLength();i++) {
			ith_getElementById(this.id+':'+temp_arr[i].value).className=(selected?'lb_item_active':'lb_item');
			this.elements.setItemSelectedByValue(temp_arr[i].value, selected);
		}
	}
	
	this.setAllFrame=function(selected, frame) {
		var temp_arr=this.elements.getItems();
		for (var i=0; i<this.elements.getLength();i++) {
			this.frames[frame].document.getElementById(this.id+':'+temp_arr[i].value).className=(selected?'lb_item_active':'lb_item');
			this.elements.setItemSelectedByValue(temp_arr[i].value, selected);
		}
	}
	
	this.getItem=function(index) {
		return this.elements.getItem(index);
	}
	
	this.setPosition=function(x, y) {
		this.positionX=x;
		this.positionY=y;
	}
	
	this.getSelectedId=function() {
		var temp_arr=this.elements.getItems();
		for (var i=0; i<this.elements.getLength();i++) {
			if (temp_arr[i].selected) return temp_arr[i].value;
		}
		return null;
	}
	
	this.getSelectedIndex=function() {
		var temp_arr=this.elements.getItems();
		for (var i=0; i<this.elements.getLength();i++) {
			if (temp_arr[i].selected) return i;
		}
		return null;
	}
	
	this.registerEvent=function(name, handler) {
		
        if(typeof handler !="function") { return; }
        /*var vHandler=function(event)
        {
            handler();
        };*/
		this.eventPool.add(handler, name);
	}
	
	this.callRegistredEvents=function(name, event) {
		temp_array=this.eventPool.getItems();
		retVal=true;
		for (var i=0;i<this.eventPool.getLength();i++) {
			
			if (temp_array[i].name==name) {
				retVal=retVal && temp_array[i].value(event);
			}
		}
		return retVal;
	}
	
	this.clear=function(refresh) {
		this.elements.clear();
		if (refresh) this.refresh();
	}
	
	this.refresh=function() {
		listbox=ith_getElementById(this.id);
		//alert(listbox.innerHTML);
		listbox.innerHTML=this.render();
		
	}

	this.hasValue=function(value) {
		return this.elements.hasItemByValue(value);
	}	

	this.add=function(value, name) {
		this.elements.add(value, name);
	}
	this.addFirst=function(value, name) {
		this.elements.addFirst(value, name);
	}
	
	this.remove=function(index) {
		this.elements.remove(index);
	}
	this.fill=function(arr) {
		this.elements=new ArrayList(arr.length);
		for (var i=0;i<arr.length;i++) {
			this.elements.add(arr[i][0], arr[i][1]);
			if (arr[i][2]!=null) this.elements.getItem(i).selected=arr[i][2];
			if (arr[i][3]!=null) this.elements.getItem(i).enabled=arr[i][3];
		}
	}
	
	/* arguments[0] has the event and arguments[1...] has own parameters */
	this.onClick=function(arguments) {
		ev=arguments[0];
		if (!this.callRegistredEvents('onClickBefore', ev)) return;
		this.setSelectedByValue(ith_getTarget(ev).id, ev.modifiers & ev.CONTROL_MASK || ev.ctrlKey);
		this.callRegistredEvents('onClickAfter', ev);
	}
}

/* global event handler, dispatch event object to control's <evt> funtion */
function dispatch (evt, event) {
	/* eliminates evt and control parameters from arguments array */
	temp_arg=new Array(arguments.length-2);
	for (var i=1;i<arguments.length;i++) {
		temp_arg[i-1]=arguments[i];
	}
	
	control=ith_controls.getControl(ith_getTarget(event).id.split(':')[0]);
	control[evt](temp_arg);
	//eval('control.'+evt+'(event)');
}


/* Browser specific settings */
if (document.all) {
	IE=1; NN=0;
	//document.onselectstart=new Function ("return false");
}
else if (document.getElementById) { 
	NN=1; IE=0; 
	//document.onmousedown=function(e) {return false;};
	//document.onclick=function() {return false;};
}
else { 
	IE=0;NN=0
};
/* Browser specific functions */
function ith_getElementById(id) {
		if (NN) return document.getElementById(id);
		else if (IE) return document.all[id];
}

/*String functions*/

function ith_str_replaceAll( inText, inFindStr, inReplStr, inCaseSensitive ) {
   //	inText is the text in which to do the search;
   //	inFindStr is the string to find;
   //	inReplStr is the string to substitute into inText in place of inFindStr; and
   //	inCaseSensitive is a boolean value (defaults to false).
   
   var searchFrom = 0;
   var offset = 0;
   var outText = "";
   var searchText = "";
   if ( inCaseSensitive == null ) {
      inCaseSensitive = false;
   }
   if ( inCaseSensitive ) {
      searchText = inText.toLowerCase();
      inFindStr = inFindStr.toLowerCase();
   } else {
      searchText = inText;
   }
   offset = searchText.indexOf( inFindStr, searchFrom );
   while ( offset != -1 ) {
      outText += inText.substring( searchFrom, offset );
      outText += inReplStr;
      searchFrom = offset + inFindStr.length;
      offset = searchText.indexOf( inFindStr, searchFrom );
   }
   outText += inText.substring( searchFrom, inText.length );
   
   return ( outText );
};

function ith_str_trim(sString) 
{
	while (sString.substring(0,1) == ' ')
	{
		sString = sString.substring(1, sString.length);
	}
	while (sString.substring(sString.length-1, sString.length) == ' ')
	{
		sString = sString.substring(0,sString.length-1);
	}
	return sString;
}

function ith_changeCss(theClass,element,value) {
	//documentation for this script at http://www.shawnolson.net/a/503/
	 var cssRules;
	 if (document.all) {
	  cssRules = 'rules';
	 }
	 else if (document.getElementById) {
	  cssRules = 'cssRules';
	 }
	 for (var S = 0; S < document.styleSheets.length; S++){
	  for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) {
	   if (document.styleSheets[S][cssRules][R].selectorText == theClass) {
	    document.styleSheets[S][cssRules][R].style[element] = value;
	   }
	  }
	 }	
	}


function ith_getFrameElementById(frame, id) {
	if (NN) return this.frames[frame].document.getElementById(id);
	else if (IE) return this.frames[frame].document.all[id];
	}

	function ith_getTarget(event) {
	if (NN) return event.target;
	else if (IE) return event.srcElement;
	}


	var IFrameObj; // our IFrame object
	function callToServer(path, procName, params) {
		
		if (!document.createElement) {return true};
		var IFrameDoc;
		var URL = path+'?rpcname='+procName+(params!=''?'&'+params:'');
		if (!IFrameObj && document.createElement) {
			// create the IFrame and assign a reference to the
			// object to our global variable IFrameObj.
			// this will only happen the first time 
			// callToServer() is called
		
			try {
				var tempIFrame=document.createElement('iframe');
				tempIFrame.setAttribute('id','RSIFrame');
				tempIFrame.style.border='0px';
				tempIFrame.style.width='0px';
				tempIFrame.style.height='0px';
				IFrameObj = document.body.appendChild(tempIFrame);
				
				if (document.frames) {
					// this is for IE5 Mac, because it will only
					// allow access to the document object
					// of the IFrame if we access it through
					// the document.frames array
					IFrameObj = document.frames['RSIFrame'];
				}
			} catch(exception) {
				
				// This is for IE5 PC, which does not allow dynamic creation
				// and manipulation of an iframe object. Instead, we'll fake
				// it up by creating our own objects.
				iframeHTML='\<;iframe id="RSIFrame" style="';
				iframeHTML+='border:0px;';
				iframeHTML+='width:0px;';
				iframeHTML+='height:0px;';
				iframeHTML+='"><\/iframe>';
				document.body.innerHTML+=iframeHTML;
				IFrameObj = new Object();
				IFrameObj.document = new Object();
				IFrameObj.document.location = new Object();
				IFrameObj.document.location.iframe = document.getElementById('RSIFrame');
				IFrameObj.document.location.replace = function(location) {
					this.iframe.src = location;
				}
			}
		}
		
		if (navigator.userAgent.indexOf('Gecko') !=-1 && !IFrameObj.contentDocument) {
		// we have to give NS6 a fraction of a second
		// to recognize the new IFrame
		setTimeout('callToServer()',10);
		return false;
		}
		
		if (IFrameObj.contentDocument) {
		// For NS6
		IFrameDoc = IFrameObj.contentDocument; 
		} else if (IFrameObj.contentWindow) {
		// For IE5.5 and IE6
		IFrameDoc = IFrameObj.contentWindow.document;
		} else if (IFrameObj.document) {
		// For IE5
		IFrameDoc = IFrameObj.document;
		} else {
		return true;
		}
		
		IFrameDoc.location.replace(URL);
		
		return false;
	}