/* javascript components: gwt*/

/********
class GWT
********/

GWT.prototype.root=null;
GWT.prototype.eventDispatchTarget;
GWT.prototype.nextEventDispatchTargetId;
function GWT(){
	
	this.eventDispatchTarget=new Array();
	this.nextEventDispatchTargetId=0;
	_next_gwt_uid=0;
	
};

GWT.prototype.setRoot=function(component){
	this.root=component;
	
};
GWT.prototype.callback=function(eventName,target){
	
	this.registerForEventDispatching(target);
	return "on"+eventName+"='gwt.process_"+eventName+"(this,"+target.eti+");'";
	
};
GWT.setRoot=function(component){
	gwt.setRoot(component);
	
};
GWT.callback=function(eventName,target){
	  
	gwt.registerForEventDispatching(target);
	var prefix="on"+eventName+"='gwt.process_"+eventName+"(this,"+target.eti;
	for(var i=2;i<arguments.length;i++){
		prefix+=","+arguments[i];
	}
	prefix+=");'";
	//debug("callback: "+prefix);
	return prefix;
	
};
GWT.setupCallback=function(event,listener,target,paramVarArg){
	
	gwt.registerForEventDispatching(listener);
	
	// the handler, such as 'onClick' -------------------------------
	
	var handler	="on"+event;
	
	// binding. this invokes gwt's process_EVENT() method -----------
	// with the following parameters:
	// - the HTMLElement that generated the event
	// - the listener ID (eti) of the listener
	// - parameters specified in parametersVararg
	
	var glue		="gwt.process_"+event+"(this,"+listener.eti;
	
	for(var i=3;i<arguments.length;i++)glue+=","+arguments[i];
	glue+=");";
	
	// this is x-browser
	target[handler]=function(){eval(glue);};
	// this doesn't work in IE6.
	//target.setAttribute(handler,glue);
	
};
GWT.insertUId=function(){
	return "id=\""+id+"\" ";
	
};

GWT.getUId=function(){
	return "__GWT_"+(++_next_gwt_uid);
	
};

GWT.useBrowserRoot=function(){
	gwt.render=function(){
		this.root.targetElement=document.getElementsByTagName("body")[0];
		this.root.paint();
	}
	
};

GWT.prototype.render=function(targetElementId){
	debug("GWT.render("+targetElementId+")");
	var element=document.getElementById(targetElementId);
	this.root.targetElement=element;
	this.root.paint();
	
};
GWT.prototype.registerForEventDispatching=function(arg){
	if(arg==undefined)return;				// if the target is undefined, give up
	if(arg==null)return;						// if the target is null, give up
	if(arg.eti!=undefined)return;		// if the target already has an event processing handle, don't reassign (!)
	
	var targetId=this.nextEventDispatchTargetId++;
	this.eventDispatchTarget[targetId]=arg;
	arg.eti=targetId;
	
};
GWT.prototype.process_blur=function(targetElement,callbackId){
	var passedArguments=new Array();
	for(var i=2;i<arguments.length;i++)passedArguments[i-2]=arguments[i];
	this.eventDispatchTarget[callbackId].processOnBlur(targetElement,passedArguments);
	
};
GWT.prototype.process_validate=function(targetElement,callbackId){
	this.eventDispatchTarget[callbackId].processOnValidate(targetElement);
	
};
GWT.prototype.process_click=function(targetElement,callbackId){
	var passedArguments=new Array();
	for(var i=2;i<arguments.length;i++)passedArguments[i-2]=arguments[i];
	this.eventDispatchTarget[callbackId].processOnClick(targetElement,passedArguments);
	
};
GWT.prototype.process_change=function(targetElement,callbackId){
	var passedArguments=new Array();
	for(var i=2;i<arguments.length;i++)passedArguments[i-2]=arguments[i];
	this.eventDispatchTarget[callbackId].processOnChange(targetElement,passedArguments);
	
};
GWT.prototype.process_click=function(targetElement,callbackId){
	var passedArguments=new Array();
	for(var i=2;i<arguments.length;i++)passedArguments[i-2]=arguments[i];
	this.eventDispatchTarget[callbackId].processOnClick(targetElement,passedArguments);
	
};
/************
class Browser
************/

function Browser(){}
Browser.root;
Browser.getRootComponent=function(){
	if(this.root==null){
		this.root=new Container();
		var body=document.getElementsByTagName("body")[0];
		this.root.targetElement=body;
		this.root.setTag("div");
		GWT.setRoot(this.root);
		GWT.useBrowserRoot();
	}
	return this.root;
};

/* javascript components: components*/

var targetElement;
var xxxListeners;
function paint(){
	this.targetElement.innerHTML="";
	
};

function processOnClick(targetElement){
	var event=null;
	if(this.xxxListeners==null)return;
	for(var i in this.xxxListeners){
		if(event==null){
			event=new EVENT_TYPE(this,targetElement);
		}
		this.listeners[i].EVENT_OCCURED(event);
	}
	
};
/**********
class Block
**********/

Block.prototype.targetElement;
Block.prototype.htmlContent;
Block.prototype.content;
Block.prototype._class;
function Block(htmlContent){
	
	this.htmlContent=htmlContent;
	
};
Block.prototype.paint=function(){
	if(this.targetElement==null)return;
	if(this.htmlContent==null)return;
	this.targetElement.innerHTML=this.htmlContent;
	if(this._class!=undefined)this.targetElement.className=this._class;
	
};

Block.prototype.setClass=function(_class){
	this._class=_class;
	
};
Block.prototype.setHTMLContent=function(htmlContent){
	this.htmlContent=htmlContent;
	if(this.targetElement!=null)this.targetElement.innerHTML=htmlContent;
	
};
Block.prototype.setContent=function(content){
	this.targetElement.innerHTML="";
	this.targetElement.appendChild(content);
	
	
};
/***************
class BlockTable
***************/

BlockTable.prototype.model;
BlockTable.prototype.setModel=function(model){this.model=model;};
BlockTable.prototype.output="";
BlockTable.prototype.fastEdit=true;
BlockTable.prototype.getFastEdit=function(){return this.fastEdit;};
BlockTable.prototype.setFastEdit=function(fastEdit){this.fastEdit=fastEdit;};
BlockTable.prototype.defaultCellRenderer=new TableCellRenderer();
BlockTable.prototype.getDefaultCellRenderer=function(){return this.defaultCellRenderer;};
BlockTable.prototype.setDefaultCellRenderer=function(defaultCellRenderer){this.defaultCellRenderer=defaultCellRenderer;};
BlockTable.prototype._class;
BlockTable.prototype.defaultCellEditor=new TableCellEditor();
BlockTable.prototype.getDefaultCellEditor=function(){return this.defaultCellEditor;};
BlockTable.prototype.setDefaultCellEditor=function(defaultCellEditor){this.defaultCellEditor=defaultCellEditor;};
BlockTable.prototype.renderers;
BlockTable.prototype.editors;
BlockTable.prototype.maxRecordsPerBlock=10;
BlockTable.prototype.minRecordsPerBlock=5;
BlockTable.prototype.maxBlockCount=2;
BlockTable.prototype.minBlockCount=1;
BlockTable.prototype.balanceRowsPerBlock=true;
BlockTable.prototype.showHeader=true;
BlockTable.prototype.setShowHeader=function(showHeader){this.showHeader=showHeader;};
BlockTable.prototype.blockCount;
BlockTable.prototype.recordsPerBlock;
BlockTable.prototype.cellRenderer=new CellRenderer();
function BlockTable(){
	
	this.renderers=new Object();
	this.editors=new Object();
	this.initDefaultRenderers();
	this.initDefaultEditors();
	
};

BlockTable.prototype.setDefaultEditor=function(_class,editor){
	
	this.editors[_class]=editor;
	//debug("associate editor with function:"+editor.render);
	
};
BlockTable.prototype.setDefaultRenderer=function(_class,renderer){
	
	this.renderers[_class]=renderer;
	debug("associate renderer with function:"+renderer.render);
	
};
BlockTable.prototype.updateElement=function(row,col,value){
	//alert("update with value:"+value);
	this.model.setValueAt(value,row,col);
	
};
BlockTable.prototype.setClass=function(_class){
	this._class=_class;
	
};
BlockTable.prototype.setDefaultEditor=function(_class,editor){
	
	this.editors[_class]=editor;
	//debug("associate editor with function:"+editor.render);
	
};
BlockTable.prototype.setMaxBlockCount=function(count){
	this.maxBlockCount=count;
	
};
BlockTable.prototype.setMaxRecordsPerBlock=function(count){
	this.maxRecordsPerBlock=count;
	
};
BlockTable.prototype.setMinBlockCount=function(count){
	this.minBlockCount=count;
	
};
BlockTable.prototype.setMinRecordsPerBlock=function(count){
	this.minRecordsPerBlock=count;
	
};
BlockTable.prototype.setBlockCount=function(count){
	this.maxBlockCount=count;
	this.minBlockCount=count;
	
};
BlockTable.prototype.setRecordsPerBlock=function(count){
	this.minRecordsPerBlock=count;
	this.maxRecordsPerBlock=count;
	
};
BlockTable.prototype.getCellRenderer=function(row,col){
	if(this.fastEdit){
		if(this.model.isCellEditable(row,col)){
			return this.getCellEditor(row,col);
		}
	}
	var _class	 =	null;
	if(this.model.getCellClass!=undefined){
		_class=this.model.getCellClass(row,col);
	}else{
		_class=this.model.getColumnClass(col);
	}
	var object =	this.renderers[_class];
	if(object==undefined)return this.defaultCellRenderer;
	return object;
	
};
BlockTable.prototype.getCellEditor=function(row,col){
	var _class	 =null;
	if(this.model.getCellClass!=undefined){
		_class=this.model.getCellClass(row,col);
	}else{
		_class=this.model.getColumnClass(col);
	}
	var object =	this.editors[_class];
	if(object==undefined)return this.defaultCellEditor;
	//debug("use class editor for class:"+class);
	//debug("render function is:"+object.render);
	return object;
	
};
BlockTable.prototype.render=function(){
	this.evalDimensions();
	debug("record per block:"+this.recordsPerBlock);
	debug("block count:"+this.blockCount);
	this.output="";
	this.out("<table>");
	if(this.showHeader)this.renderHeader();
	this.renderBody();
	this.out("</table>\n");
	return this.output;
	
};

BlockTable.prototype.paint=function(){
	this.output="";
	this.evalDimensions();
	debug("render block table");
	var tableElement=document.createElement("table");
	if(this.showHeader)this.renderHeader(tableElement);
	this.renderBody(tableElement);
	this.targetElement.innerHTML="";
	this.targetElement.appendChild(tableElement);
	if(this._class!=null){
		this.targetElement.setAttribute('class',this._class);
	}
	
};

BlockTable.prototype.renderHeader=function(tableElement){
	var headElement=document.createElement("thead");
	var rowElement=document.createElement("tr");
	
	// add all column names (we may cycle to fit block count)
	
	debug("iterate over "+this.blockCount+" blocks");
	for(var block=0;block<this.blockCount;block++){
		for(var i=0;i<this.model.getColumnCount();i++){
			var cellElement	=	document.createElement("td");
			var content			=	this.model.getColumnName(i);
			var contentNode	=	document.createTextNode(content);
			cellElement.appendChild(contentNode);
			rowElement.appendChild(cellElement);
		}
	}
	
	headElement.appendChild(rowElement);
	tableElement.appendChild(headElement);
	
};
BlockTable.prototype.renderBody=function(tableElement){
	var bodyElement=document.createElement("tbody");
	
	var rowCount=this.model.getRowCount();
	var colCount=this.model.getColumnCount();
	
	for(tableRow=0;tableRow<this.recordsPerBlock;tableRow++){								// iterate over each table row
		var rowElement=null;																									// row will only be created if it contains cells.
		for(block=0;block<this.blockCount;block++){														// iterate over blocks, spanning each several cells
			for(var modelCol=0;modelCol<colCount;modelCol++){											// iterate over model columns
				var modelRow=block*this.recordsPerBlock+tableRow;										// evaluate the model row		
				var cellElement	=	document.createElement("td");											// create the cell element.
				if(modelRow<rowCount){																							// if the model row is valid...
					var renderer		=	this.getCellRenderer(modelRow,modelCol);				// get the cell renderer
					renderer.targetElement=cellElement;																// assign the renderer's target element
					//
					renderer.render(																									// render into the cell
						this,																														//
						this.model.getValueAt(modelRow,modelCol),												//
						false,																													//
						modelRow,modelCol);																							//
				}
				if(rowElement==null)rowElement=document.createElement("tr"); 				// create the row if not done yet
				rowElement.appendChild(cellElement);																// append the cell to the row
			} // end-iterate over columns
		}	// end-iterate over blocks
		if(rowElement!=null)bodyElement.appendChild(rowElement);								// if a column was created, add it to the table
	} // end-iterate over table rows
	
	tableElement.appendChild(bodyElement);
	
};
BlockTable.prototype.out=function(arg){
	this.output+=arg;
	
};
BlockTable.prototype.balanceRowsPerBlock=function(arg){
	this.balanceRowsPerBlock=arg;
	
};
BlockTable.prototype.evalDimensions=function(){
	var n		=	this.model.getRowCount();		debug("row count:"+n);
	var a		=	this.minRecordsPerBlock;		debug("min records per block:"+a);
	var b		=	this.maxRecordsPerBlock;		debug("max records per block:"+b);
	var c		=	this.minBlockCount;					debug("min block count:"+c);
	var d		=	this.maxBlockCount;					debug("max block count:"+d);
	var ab	=	(a+b)/2;										debug("ab:"+ab);
	var cd	=	(c+d)/2;										debug("cd:"+cd);
	
	if(this.balanceRowsPerBlock){										// with balanced scheme, we assume first a median block count
	
		this.blockCount				=	cd;										// set block count to median block count
		this.recordsPerBlock	=	Math.round(n/cd);			// same number of records per block
	
	}else{																					// with standard scheme, we try to fill each block until max records per block is reached
	
		this.recordsPerBlock	= b;										// set records per block to maximum
		this.blockCount				=	Math.round(n/b);			// set block count to number of records divided by records per block
	
	}
	
	if(cd==c)return;													// if the block count cannot be changed, return.
		
	while(this.recordsPerBlock>b){						// increase block count until 
		this.blockCount++;											// records per block is less than maximum or
		this.recordsPerBlock=Math.round(n/cd);	// block count reaches maximum
		if(this.blockCount>=d)return;
		if(this.recordsPerBlock<=b)return;
	}
	
	while(this.recordsPerBlock<a){						// decrease block count until 
		this.blockCount--;											// records per block is more than minimum or
		this.recordsPerBlock=Math.round(n/cd);	// block count reaches minimum
		if(this.blockCount<=c)return;	
		if(this.recordsPerBlock>=a)return;
	}
	
};

BlockTable.prototype.initDefaultRenderers=function(){
	
	
};

BlockTable.prototype.initDefaultEditors=function(){
	this.setDefaultEditor("enum",new TableEnumCellEditor());
	this.setDefaultEditor("action",new TableActionCellEditor());
	this.setDefaultEditor("radio",new TableRadioCellEditor());
	this.setDefaultEditor("password",new TablePasswordCellEditor());
	this.setDefaultEditor("checkbox",new TableCheckboxCellEditor());
	
};

/***********
class Button
***********/

Button.prototype.actionListeners=null;
Button.prototype.targetElement;
Button.prototype.label;
Button.prototype.actionCommand;
Button.prototype.getActionCommand=function(){return this.actionCommand;};
Button.prototype.setActionCommand=function(actionCommand){this.actionCommand=actionCommand;};
Button.prototype.enabled=true;
Button.prototype.getEnabled=function(){return this.enabled;};
Button.prototype.setEnabled=function(enabled){this.enabled=enabled;};
Button.prototype._class;
Button.prototype.buttonClass;
function Button(label,optionalCommand){
	
	
	this.label=label;
	if(arguments.length==2)this.actionCommand=optionalCommand;
};
Button.prototype.setClass=function(_class){
	this._class=_class;
	
};
Button.prototype.setButtonClass=function(_class){
	this.buttonClass=_class;
	
};
Button.prototype.paint=function(){
	if(this.targetElement==null)return;
	var disableString="";
	var classString="";
	if(!this.enabled)disableString=" disabled";
	if(this.buttonClass!=null)classString=" class='"+this.buttonClass+"'";
	var contentString="<button "+GWT.callback("click",this)+disableString+classString+">"+this.label+"</button>";
	//lert(contentString);
	this.targetElement.innerHTML=contentString;
	if(this._class!=undefined)this.targetElement.className=this._class;
	
};

Button.prototype.addActionListener=function(l){
	if(this.actionListeners==null)this.actionListeners=new Array();
	this.actionListeners[this.actionListeners.length]=l;
	
};
Button.prototype.processOnClick=function(targetElement){
	var event=null;
	if(this.actionListeners==null)return;
	for(var i in this.actionListeners){
		if(event==null){
			event=new ActionEvent(this,targetElement,this.actionCommand);
		}
		this.actionListeners[i].actionPerformed(event);
	}
	
};
Button.prototype.toString=function(){
	return "Button{"+this.label+"}";
	
};

/*****************
class CellRenderer
*****************/

function CellRenderer(){}
CellRenderer.prototype.render=function(list,value,index,sel){
	return value;
	
};
/*************
class Checkbox
*************/

Checkbox.prototype.actionListeners=null;
Checkbox.prototype.targetElement;
Checkbox.prototype.label;
Checkbox.prototype.actionCommand;
Checkbox.prototype.getActionCommand=function(){return this.actionCommand;};
Checkbox.prototype.setActionCommand=function(actionCommand){this.actionCommand=actionCommand;};
Checkbox.prototype.enabled=true;
Checkbox.prototype.getEnabled=function(){return this.enabled;};
Checkbox.prototype.setEnabled=function(enabled){this.enabled=enabled;};
Checkbox.prototype.selected;
Checkbox.prototype._class;
Checkbox.prototype.buttonClass;
function Checkbox(label,optionalCommand){
	
	
	this.label=label;
	if(arguments.length==2)this.actionCommand=optionalCommand;
};
Checkbox.prototype.setClass=function(_class){
	this._class=_class;
	
};
Checkbox.prototype.setButtonClass=function(_class){
	this.buttonClass=_class;
	
};
Checkbox.prototype.paint=function(){
	if(this.targetElement==null)return;
	var disableString	="";
	var classString		="";
	var checkedString	="";
	if(!this.enabled)disableString=" disabled";
	if(this.isSelected())checkedString=" checked='checked'";
	if(this.buttonClass!=null)classString=" class='"+this.buttonClass+"'";
	var contentString="<input type='checkbox' "+GWT.callback("click",this)+disableString+checkedString+classString+">"+this.label+"</input>";
	//lert(contentString);
	this.targetElement.innerHTML=contentString;
	if(this._class!=undefined)this.targetElement.setAttribute("class",this._class);
	
};

Checkbox.prototype.addActionListener=function(l){
	if(this.actionListeners==null)this.actionListeners=new Array();
	this.actionListeners[this.actionListeners.length]=l;
	
};
Checkbox.prototype.processOnClick=function(targetElement){
	var event=null;
	if(this.actionListeners==null)return;
	for(var i in this.actionListeners){
		if(event==null){
			event=new ActionEvent(this,targetElement,this.actionCommand);
		}
		this.actionListeners[i].actionPerformed(event);
	}
	
};
Checkbox.prototype.toString=function(){
	return "Button{"+this.label+"}";
	
};

Checkbox.prototype.setSelected=function(flag){
	if(this.targetElement!=null){
		var e=this.targetElement.getElementsByTagName("input")[0];
		e.checked=flag;
	}else{
		this.selected=flag;
	}
	
};
Checkbox.prototype.isSelected=function(){
	if(this.targetElement!=null){
		var e=this.targetElement.getElementsByTagName("input")[0];
		if(e==null)return this.selected;
		return e.checked;
	}else{
		return this.selected;
	}
	
};

/*************
class ComboBox
*************/

function ComboBox(){}
ComboBox.prototype.model;
ComboBox.prototype.setModel=function(model){this.model=model;};
ComboBox.prototype.renderer=new CellRenderer();
ComboBox.prototype.getRenderer=function(){return this.renderer;};
ComboBox.prototype.targetElement;
ComboBox.prototype.selectElement;
ComboBox.prototype.listeners;
ComboBox.prototype.paint=function(){
	if(this.selectElement==undefined){
		this.selectElement=document.createElement("select");
	}else{
		this.selectElement.innerHTML="";
	}
	for(var i=0;i<this.model.getSize();i++){
		var option=document.createElement("option");
		option.setAttribute("value",i);
		option.innerHTML=
			this.renderer.render(this,this.model.getElementAt(i),i,false);
		this.selectElement.appendChild(option);	
	}
	this.targetElement.innerHTML="";
	this.targetElement.appendChild(this.selectElement);
	
	
};

ComboBox.prototype.addActionListener=function(actionListener){
	if(this.listeners==null)this.listeners=new Array();
	this.listeners[this.listeners.length]=actionListener;
};
ComboBox.prototype.getSelectedItem=function(){
	return this.model.getElementAt(this.getSelectedIndex());
	
	
};

ComboBox.prototype.getSelectedIndex=function(){
	return this.selectElement.selectedIndex;
	
	
};

ComboBox.prototype.setRenderer=function(r){
	debug("set renderer:"+r);
	this.renderer=r;
	for(var i in r)debug("property of renderer:"+i);
	
	
};
/**************
class Container
**************/

Container.prototype.targetElement;
Container.prototype.components;
Container.prototype.getComponents=function(){return this.components;};
Container.prototype.layout=null;
Container.prototype.getLayout=function(){return this.layout;};
Container.prototype.setLayout=function(layout){this.layout=layout;};
Container.prototype._class;
Container.prototype.get_class=function(){return this._class;};
Container.prototype.set_class=function(_class){this._class=_class;};
Container.prototype.tag="span";
Container.prototype.getTag=function(){return this.tag;};
Container.prototype.setTag=function(tag){this.tag=tag;};
function Container(optionalTag){
	
	if(arguments.length!=0)this.tag=optionalTag;
	this.components=new Array();
	
};
Container.prototype.setComponents=function(componentVararg){
	this.components=new Array();
	for(var i=0;i<arguments.length;i++){
		var component=arguments[i];
		this.components[i]=component;
	}
	
};
Container.prototype.add=function(componentVararg){
	//debug("Container.add("+arguments.length+" children)");
	for(var i=0;i<arguments.length;i++){
		var component=arguments[i];
		this.remove(component);
		this.components[this.components.length]=component;
	}
	
};
Container.prototype.remove=function(componentVararg){
	if(this.components==null)return;
	if(this.components.length==0)return;
	//lert(this.components.length);
	for(var i=0;i<arguments.length;i++){
		var component=arguments[i];
		for(var i=0;i<this.components.length;i++){
			if(this.components[i]==component){
				this.components.splice(i,1);
				break;
			}
		}
	}
	
};
Container.prototype.setComponent=function(index,component){
	debug("set component at index:"+index+":"+component);
	var prev=this.components[index];
	debug("reassign component");
	this.components[index]=component;
	debug("prev:"+prev);
	if(prev!=null){
		var elem=prev.targetElement;
		debug("replace content for element:"+elem);
		if(component!=null){
			component.targetElement=elem;
			component.paint();
		}else{
			prev.targetElement.innerHTML="";
		}
	}else{
		debug("repaint container");
		this.paint();
		debug("\\repaint container");
	}
	debug(this.components.join());
	
};
Container.prototype.getComponent=function(index){
	return this.components[index];
	
};
Container.prototype.paint=function(){
	//debug("Container.paint(): target element:"+this.targetElement);
	if(this.targetElement==null){
		//debug("Container.paint()::target element was null; return");
		return;
	}
	this.targetElement.innerHTML="";
	if(this.layout==null){
		for(var i in this.components){
			//debug("render component:"+i);
			var childContainer=document.createElement(this.tag);
			if(this.components[i]!=null){
				this.components[i].targetElement=childContainer;
				this.components[i].paint();
			}
			this.targetElement.appendChild(childContainer);
		}
		//alert(this.targetElement.innerHTML);
	}else{
		//debug("Container.paint() - paint using layout");
		this.layout.paint(this);
	}
	if(this._class!=undefined){
		//alert("apply class:"+this._class);
		//this.targetElement.setAttribute("class",this._class);
		this.targetElement.className=this._class;
	}
	
};

Container.prototype.output=function(arg){
	this.targetElement.innerHTML+=arg;
	
};
Container.prototype.setClass=function(_class){
	this._class=_class;
	
};
/****************
class DebugWindow
****************/

DebugWindow.prototype.window;
function DebugWindow(){
	
	this.window=window.open("about:blank","debug_window","left=32,top=32,width=480,height=800,toolbar=0,resizable=1,scrollbars=1");
	
};

DebugWindow.prototype.out=function(arg){
	this.window.document.write(arg);
	
};
DebugWindow.init=function(){
	_debug_window=new DebugWindow();
};

/***********
class IFrame
***********/

IFrame.prototype.targetElement;
IFrame.prototype.components;
IFrame.prototype.getComponents=function(){return this.components;};
IFrame.prototype.template;
IFrame.prototype.getTemplate=function(){return this.template;};
IFrame.prototype.setTemplate=function(template){this.template=template;};
IFrame.prototype.layout=null;
IFrame.prototype.getLayout=function(){return this.layout;};
IFrame.prototype.setLayout=function(layout){this.layout=layout;};
IFrame.prototype.iframe=null;
IFrame.prototype.getIframe=function(){return this.iframe;};
IFrame.prototype.setIframe=function(iframe){this.iframe=iframe;};
IFrame.prototype.tag="span";
IFrame.prototype.getTag=function(){return this.tag;};
IFrame.prototype.setTag=function(tag){this.tag=tag;};
IFrame.prototype.stylesheet;
IFrame.prototype.setStylesheet=function(stylesheet){this.stylesheet=stylesheet;};
IFrame.prototype.width;
IFrame.prototype.setWidth=function(width){this.width=width;};
IFrame.prototype.height;
IFrame.prototype.setHeight=function(height){this.height=height;};
function IFrame(optionalTag){
	
	
	if(arguments.length!=0)this.tag=optionalTag;
	this.components=new Array();
	
};
IFrame.prototype.add=function(componentVararg){
	debug("add "+arguments.length+"children to container.");
	for(var i=0;i<arguments.length;i++){
		var component=arguments[i];
		this.remove(component);
		this.components[this.components.length]=component;
	}
	
};
IFrame.prototype.remove=function(componentVararg){
	debug("remove "+arguments.length+"children to container.");
	for(var i=0;i<arguments.length;i++){
		var component=arguments[i];
		for(var i=0;i<this.components.length;i++){
			if(this.components[i]==component){
				this.components.splice(i,1);
				break;
			}
		}
	}
	
};
IFrame.prototype.setComponent=function(index,component){
	debug("set component at index:"+index+":"+component);
	var prev=this.components[index];
	debug("reassign component");
	this.components[index]=component;
	debug("prev:"+prev);
	if(prev!=null){
		var elem=prev.targetElement;
		debug("replace content for element:"+elem);
		if(component!=null){
			component.targetElement=elem;
			component.paint();
		}else{
			prev.targetElement.innerHTML="";
		}
	}else{
		debug("repaint container");
		this.paint();
		debug("\\repaint container");
	}
	
};
IFrame.prototype.setSize=function(width,height){
	if(this.iframe==null){
		this.width=width;
		this.height=height;
		return;
	}
	this.iframe.setAttribute("width",width);
	this.iframe.setAttribute("height",height);
	
	
};
IFrame.prototype.getComponent=function(index){
	return this.components[index];
	
};
IFrame.prototype.getTargetBody=function(){
	var cd=this.iframe.contentDocument;
	if(cd==null){
		return null;
	}
	/*
	cd.write("<body></body>");
	cd.close();
	*/
	var body=cd.getElementsByTagName("body")[0];
	/*if(body==null){
		cd.write("<body></body>");
		cd.close();
		body=this.iframe.contentDocument.getElementsByTagName("body");
		//alert("body element recovered:"+body);
	}*/
	/*var head=cd.getElementsByTagName("head")[0];
	if(head!=null)if(cd.styleSheets.length==0){
		var css=cd.createElement("link");
		css.type="text/css";
		css.rel="stylesheet";
		css.href="style.css";
		head.appendChild(css);
	}*/
	return body;
	
	
};

IFrame.prototype.getTargetDocument=function(){
	var cd=this.iframe.contentDocument;
	if(cd==null){
		return null;
	}
	return cd;
	
	
};

IFrame.prototype.paint=function(){
	debug("Container.paint(): target element:"+this.targetElement);
	if(this.targetElement==null){
		debug("Container.paint()::target element was null; return");
		return;
	}
	
	// whenever the target element is replaced, we somehow
	
	var childIFrame=this.targetElement.getElementsByTagName('iframe')[0];
	if(this.iframe==null){
	//	this.targetElement.innerHTML="<iframe width='"+this.width+"' height='"+this.height+"' src='about:blank' frameborder='0'></iframe>";
		this.targetElement.innerHTML="<iframe width='"+this.width+"' height='"+this.height+"' src='"+this.template+"' frameborder='0'></iframe>";
		this.iframe=this.targetElement.getElementsByTagName("iframe")[0];
	}else if(childIFrame==null){
		this.targetElement.appendChild(this.iframe);
	}
	
	var targetBody=this.getTargetBody();
	//alert(this.iframe);
	if(targetBody==null){
		//alert("target body is null; set timeout to repaint\n"+this.targetElement.innerHTML);
		__iframeToRepaint=this;
		setTimeout('__iframeToRepaint.paint()',150);
		return;
	}
	if(this.layout==null){
		for(var i in this.components){
			debug("render component:"+i);
			var childContainer=document.createElement(this.tag);
			this.components[i].targetElement=childContainer;
			this.components[i].paint();
			targetBody.appendChild(childContainer);
		}
	}else{
		debug("Container.paint() - paint using layout");
		return this.layout.paint(this);
	}
	
};

IFrame.prototype.output=function(arg){
	this.targetElement.innerHTML+=arg;
	
};
/***************
class LoginPanel
***************/

function LoginPanel(){}
LoginPanel.prototype.action="login.php";
LoginPanel.prototype.getAction=function(){return this.action;};
LoginPanel.prototype.setAction=function(action){this.action=action;};
LoginPanel.prototype.method="post";
LoginPanel.prototype.userNameLabel="user name";
LoginPanel.prototype.passwordLabel="password";
LoginPanel.prototype.render=function(){
	var form				=	new SimpleForm();
	form.action			=	this.action;
	form.method			=	this.method;
	form.submitName	=	"login";
	form.keys				= [this.userNameLabel,this.passwordLabel];
	form.types			= ["text"				,"text"				];
	form.names			= ["userName"		,"password"		];
	form.render();
	
};

/**********
class HList
**********/

/*********************
class ListCellRenderer
*********************/

function ListCellRenderer(){}
ListCellRenderer.prototype.list;
ListCellRenderer.prototype.processOnClick=function(targetElement,data){
	
	//lert("list cell renderer processOnClick():"+data[0]);
	this.list.updateElement(data[0],null);
	
};
ListCellRenderer.prototype.render=function(list,value,index,sel){
	this.list=list;
	var e=document.createElement("a");
	GWT.setupCallback("click",this,e,index);
	e.innerHTML=value.toString();
	this.targetElement.innerHTML="";
	this.targetElement.appendChild(e);
	
};
/*****************************
class ListCheckboxCellRenderer
*****************************/

function ListCheckboxCellRenderer(){}
ListCheckboxCellRenderer.prototype.table;
ListCheckboxCellRenderer.prototype.processOnClick=function(targetElement,data){
	
	//alert("click cell:"+data[0]);
	this.list.updateElement(data[0],targetElement.checked);
	
};
ListCheckboxCellRenderer.prototype.render=function(list,selection,index,cell){
	
	this.list=list;
	if(selection.indexOf(":")<0){
		//lert("no checkbox data:"+selection);
		this.targetElement.innerHTML=selection;
		return;
	}
	var arr			=	selection.split(':');
	var name		=	arr[0];
	var value		=	arr[1];
	var checked	=	arr[2]=='true';
	//alert(arr[0]+" "+arr[1]+" "+arr[2]);
	this.targetElement.innerHTML="<input type='checkbox' name='"+name+"' value='"+value+"' "+(checked?"checked ":" ")+GWT.callback("click",this,index)+">"+value;
	
};
HList.prototype.targetElement;
HList.prototype.output="";
HList.prototype.fastEdit=true;
HList.prototype.getFastEdit=function(){return this.fastEdit;};
HList.prototype.setFastEdit=function(fastEdit){this.fastEdit=fastEdit;};
HList.prototype.listeners=null;
HList.prototype.model;
HList.prototype.getModel=function(){return this.model;};
HList.prototype.setModel=function(model){this.model=model;};
HList.prototype._class;
HList.prototype.selection=0;
HList.prototype.cellRenderer;
HList.prototype.getCellRenderer=function(){return this.cellRenderer;};
HList.prototype.setCellRenderer=function(cellRenderer){this.cellRenderer=cellRenderer;};
function HList(optionalElementsVararg){
	
	if(arguments.length>0){
		//debug("CREATE SIMPLE LIST MODEL:"+arguments.length);
		var arr=new Array();
		for(var i=0;i<arguments.length;i++)arr[i]=arguments[i];
		//debug("IN ARRAY: "+arr.length);
		this.model=new SimpleListModel(arr);
	}
	this.cellRenderer=new ListCellRenderer();
	
};
HList.prototype.addListSelectionListener=function(listener){
	if(this.listeners==null)this.listeners=new Array();
	//alert("add HList listener:"+this.id);
	this.listeners[this.listeners.length]=listener;
	//alert("listener added to: "+this.yyy);
	
};
HList.prototype.updateElement=function(index,value){
	
	//alert("with index:"+index);
	if(this.listeners==null)return;
	var event=new ListSelectionEvent();
	event.firstIndex=index;
	event.source=this.model.getElementAt(index);
	for(var i=0;i<this.listeners.length;i++){
		this.listeners[i].valueChanged(event);
	}
	this.selection=index;
	
};
HList.prototype.setClass=function(_class){
	this._class=_class;
	
};
HList.prototype.paint=function(){
	debug("HList.paint(): target element:"+this.targetElement);
	var e=this.targetElement;
	if(e==null)return;
	e.innerHTML="";
	this.output="";
	
	// now allocate cells for children to render into -----------------------------------------------
	
	var tableElement=document.createElement("table");
	var tbodyElement=document.createElement("tbody");
	var rowElement=document.createElement("tr");
	
	for(var i=0;i<this.model.getSize();i++){
		var value=this.model.getElementAt(i);
		var cellElement=document.createElement("td");
		if(this.model.getElementClass!=null){
			//alert("cell class:"+this.model.getElementClass(i));
			cellElement.className=this.model.getElementClass(i);
		}
		this.cellRenderer.targetElement=cellElement;
		this.cellRenderer.render(this,value,i,false);
		rowElement.appendChild(cellElement);
	}
	tbodyElement.appendChild(rowElement);
	tableElement.appendChild(tbodyElement);
	this.targetElement.appendChild(tableElement);
	
	if(this._class!=null){
		this.targetElement.className=this._class;
	}
	
};

HList.prototype.out=function(arg){
	this.output+=arg;
	
};
HList.prototype.fireListSelectionEvent=function(index,targetElement){
	var event=null;
	if(this.listeners==null){
		alert("HList: no listeners");
		return;
	}
	for(var i in this.listeners){
		if(event==null){
			event=new ListSelectionEvent(this,index,targetElement);
		}
		this.listeners[i].valueChanged(event);
	}
	
};
HList.prototype.processOnClick=function(targetElement){
	debug("HList.processOnClick("+targetElement.name+")");
	this.fireListSelectionEvent(targetElement.name,targetElement);
	
};
HList.prototype.initDefaultRenderers=function(){
	
	
};

HList.prototype.initDefaultEditors=function(){
	this.setDefaultEditor("enum",new ListEnumCellEditor());
	this.setDefaultEditor("action",new ListActionCellEditor());
	this.setDefaultEditor("radio",new ListRadioCellEditor());
	this.setDefaultEditor("password",new ListPasswordCellEditor());
	this.setDefaultEditor("checkbox",new ListCheckboxCellEditor());
	
};

/*********
class Link
*********/

Link.prototype.targetElement;
Link.prototype.text;
Link.prototype.getText=function(){return this.text;};
Link.prototype.listeners;
Link.prototype._class;
function Link(label){
	
	this.label=label;
	this.listeners=null;
};
Link.prototype.paint=function(){
	this.targetElement.innerHTML="<a>"+this.label+"</a>";
	if(this._class!=undefined)this.targetElement.setAttribute("class",this._class);
	
};

Link.prototype.setClass=function(_class){
	this._class=_class;
	
};
Link.prototype.setText=function(text){
	this.text=text;
	paint();
	
};
Link.prototype.addActionListener=function(actionListener){
	if(this.listeners==null)this.listeners=new Array();
	this.listeners[this.listeners.length]=actionListener;
};
/******************
class PasswordField
******************/

function PasswordField(){}
PasswordField.prototype.listeners;
PasswordField.prototype.targetElement;
PasswordField.prototype._class;
PasswordField.prototype.addActionListener=function(actionListener){
	if(this.listeners==null)this.listeners=new Array();
	this.listeners[this.listeners.length]=actionListener;
	
};
PasswordField.prototype.paint=function(){
	this.targetElement.innerHTML="<input "+GWT.callback("validate",this)+"type=\"password\"/>";
	if(this._class!=undefined)this.targetElement.className=this._class;
	
};

PasswordField.prototype.setClass=function(_class){
	this._class=_class;
	
};
PasswordField.prototype.getText=function(){
	return this.targetElement.getElementsByTagName("input")[0].value;
	
};

PasswordField.prototype.processOnValidate=function(targetElement){
	var event=null;
	if(this.listeners==null)return;
	for(var i in this.listeners){
		if(event==null){
			event=new ActionEvent(this,targetElement);
		}
		this.listeners[i].actionPerformed(event);
	}
	
};
/**********
class VList
**********/

VList.prototype.listeners=null;
VList.prototype.model;
VList.prototype.getModel=function(){return this.model;};
VList.prototype.setModel=function(model){this.model=model;};
VList.prototype.output="";
VList.prototype.cellRenderer=new CellRenderer();
VList.prototype.getCellRenderer=function(){return this.cellRenderer;};
VList.prototype.setCellRenderer=function(cellRenderer){this.cellRenderer=cellRenderer;};
function VList(){
	
	gwt.registerForEventDispatching(this);
	
};

VList.prototype.addListSelectionListener=function(listener){
	if(this.listeners==null)this.listeners=new Array();
	this.listeners[this.listeners.length]=listener;
	
};
VList.prototype.paint=function(){
	debug("render VList using:"+this.model);
	debug("model size:"+this.model.getSize());
	if(this.model!=null)for(var i=0;i<this.model.getSize();i++){
			var callback=gwt.callback("click",this);
			var anchor="<a "+callback+" style='cursor: pointer' name='"+i+"'>";
			alert("list anchor: "+anchor);
			this.out(anchor);
			this.out(this.cellRenderer.render(this.model.getElementAt(i)));
			this.out("<br>");
			this.out("</a>");		
	}
	this.targetElement.innerHTML=this.output;
	
};

VList.prototype.out=function(arg){
	this.output+=arg;
	
};
VList.prototype.fireListSelectionEvent=function(index){
	var event=null;
	if(this.listeners==null)return;
	for(var i in this.listeners){
		if(event==null){
			event=new ListSelectionEvent(this,index);
		}
		this.listeners[i].valueChanged(event);
	}
	
};
VList.prototype.processOnClick=function(targetElement){
	this.fireListSelectionEvent(targetElement.name);
	
};
/***************
class SimpleForm
***************/

function SimpleForm(){}
SimpleForm.prototype.action;
SimpleForm.prototype.method="post";
SimpleForm.prototype.keys;
SimpleForm.prototype.types;
SimpleForm.prototype.names;
SimpleForm.prototype.values;
SimpleForm.prototype.output="";
SimpleForm.prototype.submitName="submit";
SimpleForm.prototype.render=function(){
	if(this.action!=null)this.out("<form action='"+this.action+"' method='"+this.method+"'>");
	this.out("<table>");
	for(var i=0;i<this.keys.length;i++){
		this.renderEntry(i);
	}
	this.out("<tr><td></td><td><input type='submit' value='"+this.submitName+"'></td>");
	this.out("</table>");
	if(this.action!=null)this.out("</form>");
	document.write(this.output);
	
};

SimpleForm.prototype.renderEntry=function(i){
	this.out("<tr>");
	this.out("<td>"+this.keys[i]+"</td>");
	this.out("<td>");
	if( (this.types[i]==null) && (this.names[i]==null) ){
		if(this.values!=null)if(this.values(i)!=null)this.out(this.values[i]);
	}else{
		this.out("<input type='"+this.types[i]+"' name='"+this.names[i]+"'");
		if(this.values!=null)if(this.values[i]!=null)this.out("value='"+this.values[i]+"'");
		this.out(">");
	}
	this.out("</td>");
	this.out("</tr>\n");
	
};
SimpleForm.prototype.out=function(arg){
	this.output+=arg;
	
};
/********************
class SimpleListModel
********************/

SimpleListModel.prototype.elements;
function SimpleListModel(elementsArray){
	
	this.elements=elementsArray;
	
};
SimpleListModel.prototype.getSize=function(){
	return this.elements.length;
	
};

SimpleListModel.prototype.getElementAt=function(index){
	return this.elements[index];
};
/**************
class TextField
**************/

function TextField(){}
TextField.prototype.listeners;
TextField.prototype.targetElement;
TextField.prototype.text;
TextField.prototype._class;
TextField.prototype.paint=function(){
	var value=this.getText();
	if(value==null)value="";
	this.text=null;
	this.targetElement.innerHTML="<input "+GWT.callback("validate",this)+"type=\"text\" value=\""+value+"\"/>";
	if(this._class!=undefined)this.targetElement.className=this._class;
	
};

TextField.prototype.setText=function(text){
	if(this.targetElement==null){
		this.text=text;
	}else{
		this.targetElement.getElementsByTagName("input")[0].value=text;
		this.text=null;
	}
	
};
TextField.prototype.getText=function(){
	if(this.targetElement==null)return this.text;
	
	var inputElements=this.targetElement.getElementsByTagName("input");
	if(inputElements.length==0)return this.text;
	if(this.text!=null)return this.text;
	return inputElements[0].value;
	
};

TextField.prototype.addActionListener=function(actionListener){
	if(this.listeners==null)this.listeners=new Array();
	this.listeners[this.listeners.length]=actionListener;
	
};
TextField.prototype.processOnValidate=function(targetElement){
	var event=null;
	if(this.listeners==null)return;
	for(var i in this.listeners){
		if(event==null){
			event=new ActionEvent(this,targetElement);
		}
		this.listeners[i].actionPerformed(event);
	}
	
};
TextField.prototype.setClass=function(_class){
	this._class=_class;
};
/**********
class Table
**********/

/**********************
class TableCellRenderer
**********************/

function TableCellRenderer(){}
TableCellRenderer.prototype.render=function(table,value,sel,row,col){
	
	//debug("render:"+value);
	this.targetElement.innerHTML=value;
	
};
/********************
class TableCellEditor
********************/

function TableCellEditor(){}
TableCellEditor.prototype.table;
TableCellEditor.prototype.processOnBlur=function(targetElement,data){
	
	//alert("blur cell:"+data[0]+" ; "+data[1]);
	this.table.updateElement(data[0],data[1],targetElement.value);
	
};
TableCellEditor.prototype.render=function(table,value,sel,row,col){
	
	//debug("render:"+value);
	this.table=table;
	var str="<input "+GWT.callback("blur",this,row,col)+"type=\"text\" value=\""+value+"\"/>";
	this.targetElement.innerHTML=str;
	
};
/****************************
class TablePasswordCellEditor
****************************/

function TablePasswordCellEditor(){}
TablePasswordCellEditor.prototype.table;
TablePasswordCellEditor.prototype.processOnBlur=function(targetElement,data){
	
	//alert("blur cell:"+data[0]+" ; "+data[1]);
	this.table.updateElement(data[0],data[1],targetElement.value);
	
};
TablePasswordCellEditor.prototype.render=function(table,value,sel,row,col){
	
	//alert("render as password:"+value);
	this.table=table;
	var str="<input "+GWT.callback("blur",this,row,col)+"type=\"password\" value=\""+value+"\"/>";
	this.targetElement.innerHTML=str;
	
};
/************************
class TableEnumCellEditor
************************/

function TableEnumCellEditor(){}
TableEnumCellEditor.prototype.table;
TableEnumCellEditor.prototype.processOnChange=function(targetElement,data){
	
	//alert("cell changed:"+data[0]+" ; "+data[1]+" ; "+targetElement.selectedIndex);
	this.table.updateElement(data[0],data[1],targetElement.selectedIndex);
	
};
TableEnumCellEditor.prototype.render=function(table,value,sel,row,col){
	
	if(value==null){
		this.targetElement.innerHTML="";
		return;
	}
	this.table=table;
	var values=table.getModel().getValueEnumeration(row,col);
	
	var content="<select "+GWT.callback("change",this,row,col)+">\n";
	for(var i=0;i<values.length;i++){
		content+="<option value=\""+i+"\" "+(i==value?"selected":"")+">";
		content+=values[i];
		content+="</option>\n";
	}
	content+="</select>";
	//alert("select statement:\n"+content);
	this.targetElement.innerHTML=content;
	
};
/**************************
class TableActionCellEditor
**************************/

function TableActionCellEditor(){}
TableActionCellEditor.prototype.table;
TableActionCellEditor.prototype.processOnClick=function(targetElement,data){
	
	//lert("click cell:"+data[0]+" ; "+data[1]);
	this.table.updateElement(data[0],data[1],null);
	
};
TableActionCellEditor.prototype.render=function(table,value,sel,row,col,_class){
	
	//alert("render action cell");
	this.table=table;
	if(value==null){
		alert("value for button is null");
		this.targetElement.innerHTML="";
		return;
	}
	//lert("in table action editor:"+_class);
	var classString=""; if(_class!=null)classString=" class='"+_class+"'";
	var contentString="<button "+GWT.callback("click",this,row,col)+classString+">"+value+"</button>";
	//alert(contentString);
	this.targetElement.innerHTML=contentString;
	
};
/****************************
class TableCheckboxCellEditor
****************************/

function TableCheckboxCellEditor(){}
TableCheckboxCellEditor.prototype.table;
TableCheckboxCellEditor.prototype.processOnClick=function(targetElement,data){
	
	//alert("click cell:"+data[0]+" ; "+data[1]);
	this.table.updateElement(data[0],data[1],targetElement.checked);
	
};
TableCheckboxCellEditor.prototype.render=function(table,selection,sel,row,col){
	
	this.table=table;
	var arr			=	selection.split(':');
	var name		=	arr[0];
	var value		=	arr[1];
	var checked	=	arr[2]=='true';
	//alert(arr[0]+" "+arr[1]+" "+arr[2]);
	this.targetElement.innerHTML="<input type='checkbox' name='"+name+"' value='"+value+"' "+(checked?"checked ":" ")+GWT.callback("click",this,row,col)+">";
	
};
/*************************
class TableRadioCellEditor
*************************/

function TableRadioCellEditor(){}
TableRadioCellEditor.prototype.table;
TableRadioCellEditor.prototype.processOnClick=function(targetElement,data){
	
	//alert("click cell:"+data[0]+" ; "+data[1]);
	this.table.updateElement(data[0],data[1],null);
	
};
TableRadioCellEditor.prototype.render=function(table,selection,sel,row,col){
	
	this.table=table;
	var arr		=	selection.split(':');
	var name	=	arr[0];
	var value	=	arr[1];
	var checked= arr[2]=='true';
	var html="<input type='radio' name='"+name+"' value='"+value+"' "+(checked?"checked ":"")+GWT.callback("click",this,row,col)+">";
	//alert(html);
	this.targetElement.innerHTML=html;
	
};
Table.prototype.output="";
Table.prototype.fastEdit=true;
Table.prototype.getFastEdit=function(){return this.fastEdit;};
Table.prototype.setFastEdit=function(fastEdit){this.fastEdit=fastEdit;};
Table.prototype.model;
Table.prototype.getModel=function(){return this.model;};
Table.prototype.setModel=function(model){this.model=model;};
Table.prototype.showHeader=true;
Table.prototype.setShowHeader=function(showHeader){this.showHeader=showHeader;};
Table.prototype.defaultCellRenderer=new TableCellRenderer();
Table.prototype.getDefaultCellRenderer=function(){return this.defaultCellRenderer;};
Table.prototype.setDefaultCellRenderer=function(defaultCellRenderer){this.defaultCellRenderer=defaultCellRenderer;};
Table.prototype.defaultCellEditor=new TableCellEditor();
Table.prototype.getDefaultCellEditor=function(){return this.defaultCellEditor;};
Table.prototype.setDefaultCellEditor=function(defaultCellEditor){this.defaultCellEditor=defaultCellEditor;};
Table.prototype.renderers;
Table.prototype._class;
Table.prototype._contentClass;
Table.prototype.editors;
function Table(){
	
	this.renderers=new Object();
	this.editors=new Object();
	this.initDefaultRenderers();
	this.initDefaultEditors();
	
};

Table.prototype.setClass=function(_class){
	this._class=_class;
	
};
Table.prototype.setContentClass=function(_class){
	this._contentClass=_class;
	
};
Table.prototype.setDefaultRenderer=function(_class,renderer){
	
	this.renderers[_class]=renderer;
	//debug("associate renderer with function:"+renderer.render);
	
};
Table.prototype.setDefaultEditor=function(_class,editor){
	
	this.editors[_class]=editor;
	//debug("associate editor with function:"+editor.render);
	
};
Table.prototype.updateElement=function(row,col,value){
	//alert("update with value:"+value);
	this.model.setValueAt(value,row,col);
	
};
Table.prototype.getCellRenderer=function(row,col){
	if(this.fastEdit){
		if(this.model.isCellEditable(row,col)){
			return this.getCellEditor(row,col);
		}
	}
	var _class	 =	null;
	if(this.model.getCellClass!=undefined){
		_class=this.model.getCellClass(row,col);
	}else{
		_class=this.model.getColumnClass(col);
	}
	var object =	this.renderers[_class];
	if(object==undefined)return this.defaultCellRenderer;
	return object;
	
};
Table.prototype.getCellEditor=function(row,col){
	var _class	 =null;
	if(this.model.getCellClass!=undefined){
		_class=this.model.getCellClass(row,col);
	}else{
		_class=this.model.getColumnClass(col);
	}
	var object =	this.editors[_class];
	//debug("data class:"+class);
	if(object==undefined){
		return this.defaultCellEditor;
	}
	//debug("use class editor for class:"+class);
	//debug("render function is:"+object.render);
	return object;
	
};
Table.prototype.paint=function(){
	this.output="";
	//debug("render table");
	var tableElement=document.createElement("table");
	
	if(this.showHeader)this.renderHeader(tableElement);
	this.renderBody(tableElement);
	this.targetElement.innerHTML="";
	this.targetElement.appendChild(tableElement);
	
	if(this._contentClass!=null){
		tableElement.className=this._contentClass;
	}
	
	if(this._class!=null){
		this.targetElement.className=this._class;
	}
	
	
};

Table.prototype.renderHeader=function(tableElement){
	
	var headElement=document.createElement("thead");
	var rowElement=document.createElement("tr");
	
	for(var i=0;i<this.model.getColumnCount();i++){
		var cellElement	=	document.createElement("td");
		var content			=	this.model.getColumnName(i);
		var contentNode	=	document.createTextNode(content);
		cellElement.appendChild(contentNode);
		rowElement.appendChild(cellElement);
	}
	
	headElement.appendChild(rowElement);
	tableElement.appendChild(headElement);
	
};
Table.prototype.renderBody=function(tableElement){
	
	var bodyElement=document.createElement("tbody");
	
	var rowCount=this.model.getRowCount();
	var colCount=this.model.getColumnCount();
	
	var skip=this.createSkipTable(rowCount,colCount);										// get an array that cells us which cells to skip according to rowspan/colspan
	
	for(var i=0;i<rowCount;i++){
		var rowElement=null;																							// row will only be created if it contains cells.
		//debug("paint table row:"+i);
		for(var j=0;j<colCount;j++){
			if(!skip[i][j]){																								// if skip is set, this is a skip cell because of row/colspan
		
				var cellElement	=	document.createElement("td");								// the cell element.
				var cec=null;if(this.model.getColumnElementClass!=null){
					cec=this.model.getColumnElementClass(j);
					//if(cec!=null)alert("set cec:"+cec+" with value "+this.model.getValueAt(i,j));
					cellElement.className=cec;
				}
				var rowSpan=this.getRowSpan(i,j);															// apply
				var colSpan=this.getColSpan(i,j);															// row span and colspan
				if(rowSpan>1)cellElement.setAttribute("rowspan",rowSpan);			// attributes, if present.
				if(colSpan>1)cellElement.setAttribute("colspan",colSpan);			//
				//
				var renderer		=	this.getCellRenderer(i,j);												// get the cell renderer
				renderer.targetElement=cellElement;																	// assign the renderer's target element
				var ccec=null;if(this.model.getColumnContentElementClass!=null){
					ccec=this.model.getColumnContentElementClass(j);
				}
				renderer.render(this,this.model.getValueAt(i,j),false,i,j,ccec);		// render into the cell.
				//
				if(rowElement==null)rowElement=document.createElement("tr"); 	// create the row if not done yet
				rowElement.appendChild(cellElement);													// append the cell to the row.
			} // end-if(skip)
		}
		if(rowElement!=null){
			if(this.model.getRowElementClass!=null){
				var _class=this.model.getRowElementClass(i);
				if(_class!=null){
					rowElement.className=_class;									// if the model defines a class name for the row, apply it.
					//lert("row:"+i+" - "+_class);
				}
			}
			bodyElement.appendChild(rowElement);														// if a column was created, add it to the table
		}
	}
	tableElement.appendChild(bodyElement);
	
};
Table.prototype.out=function(arg){
	this.output+=arg;
	
};
Table.prototype.getValueEnumeration=function(row,col){
	
	
};
Table.prototype.initDefaultRenderers=function(){
	
	
};

Table.prototype.initDefaultEditors=function(){
	this.setDefaultEditor("enum",new TableEnumCellEditor());
	this.setDefaultEditor("action",new TableActionCellEditor());
	this.setDefaultEditor("radio",new TableRadioCellEditor());
	this.setDefaultEditor("password",new TablePasswordCellEditor());
	this.setDefaultEditor("checkbox",new TableCheckboxCellEditor());
	
};

Table.prototype.createSkipTable=function(rows,cols){
	var skip=[];
	
	// first, initialise the skip table to all false (don't skip)
	
	for(var row=0;row<rows;row++){
		skip[row]=[];
		for(var col=0;col<cols;col++){
			skip[row][col]=false;
		}
	}
	
	// next, for each cell, determine rowspan/colspan and set skip cells accordingly.
	
	for(var row=0;row<rows;row++){
		for(var col=0;col<cols;col++){
			var rowSpan=this.getRowSpan(row,col);
			var colSpan=this.getColSpan(row,col);
			for(var rowOffset=0;rowOffset<rowSpan;rowOffset++){
				for(var colOffset=0;colOffset<colSpan;colOffset++){
					if((rowOffset>0)||(colOffset>0)){
						skip[row+rowOffset][col+colOffset]=true;
					}
				}
			}
		}
	}
	
	/*
	var str="";
	for(var row=0;row<rows;row++){
		for(var col=0;col<cols;col++){
			str+=(skip[row][col])?"1":0;
		}
		str+="\n";
	}
	
	alert(str);
	*/
	
	return skip;
	
};
Table.prototype.getRowSpan=function(row,col){
	var value=1; if(this.model.getRowSpan!=undefined)value=this.model.getRowSpan(row,col);
	if(value==undefined)value=1;
	if(value<=0)value=1;
	return value;
	
};
Table.prototype.getColSpan=function(row,col){
	var value=1; if(this.model.getColSpan!=undefined)value=this.model.getColSpan(row,col);
	if(value==undefined)value=1;
	if(value<=0)value=1;
	return value;
	
};
/**********************
class RegistrationPanel
**********************/

function RegistrationPanel(){
	
	
	
};

RegistrationPanel.prototype.action="register.php";
RegistrationPanel.prototype.method="post";
RegistrationPanel.prototype.userNameLabel="user name";
RegistrationPanel.prototype.passwordLabel="password";
RegistrationPanel.prototype.verifyPasswordLabel="verify password";
RegistrationPanel.prototype.render=function(){
	var form		=	new SimpleForm();
	form.action	=	this.action;
	form.method	=	this.method;
	form.keys		= [this.userNameLabel,this.passwordLabel,this.verifyPasswordLabel];
	form.types	= ["text"				,"text"				,"text"];
	form.names	= ["userName"		,"password"		,"passwordCheck"];
	form.render();
	
};

/* javascript components: event*/

function valueChanged(e){
	
	
};
var source;
/****************
class EventObject
****************/

EventObject.prototype.source;
function EventObject(optSource){
	
	if(arguments.length!=0)this.source=optSource;
	
};
/***********************
class ListSelectionEvent
***********************/

ListSelectionEvent.prototype.firstIndex;
ListSelectionEvent.prototype.lastIndex;
ListSelectionEvent.prototype.isAdjusting;
ListSelectionEvent.prototype.source;
ListSelectionEvent.prototype.getSource=function(){return this.source;};
function ListSelectionEvent(){
	
	
	
};

ListSelectionEvent.prototype.getFirstIndex=function(){
	//alert("return first index:"+this.firstIndex);
	return this.firstIndex;
	
};

ListSelectionEvent.prototype.getLastIndex=function(){
	return this.lastIndex;
	
};

ListSelectionEvent.prototype.isAdjusting=function(){
	return this.isAdjusting;
	
};

/****************
class ActionEvent
****************/

ActionEvent.prototype.sourceElement;
ActionEvent.prototype.getSourceElement=function(){return this.sourceElement;};
ActionEvent.prototype.source;
ActionEvent.prototype.getSource=function(){return this.source;};
ActionEvent.prototype.actionCommand;
ActionEvent.prototype.getActionCommand=function(){return this.actionCommand;};
function ActionEvent(source,sourceElement,actionCommand){
	
	
	
	
	this.source					=	source;
	this.sourceElement	=	sourceElement;
	this.actionCommand	=	actionCommand;
	
};
ActionEvent.prototype.toString=function(){
	return "ActionEvent (from:"+this.source+")";
	
};

/***********************
class ListSelectionEvent
***********************/

ListSelectionEvent.prototype.sourceElement;
ListSelectionEvent.prototype.getSourceElement=function(){return this.sourceElement;};
ListSelectionEvent.prototype.source;
ListSelectionEvent.prototype.getSource=function(){return this.source;};
ListSelectionEvent.prototype.index;
ListSelectionEvent.prototype.getIndex=function(){return this.index;};
function ListSelectionEvent(source,index,sourceElement){
	
	this.source=source;
	this.index=index;
	this.sourceElement=sourceElement;
	
};
ListSelectionEvent.prototype.toString=function(){
	return "["+this.source+"] "+this.index;
	
};

/* javascript components: layout*/

/*********************
class HorizontalLayout
*********************/

function HorizontalLayout(){}
HorizontalLayout.prototype.paint=function(container){
	debug("HorizontalLayout.paint(): target element:"+this.targetElement);
	
	var components=container.getComponents();
	var e=container.targetElement;
	e.innerHTML="";
	
	// generate the table structure ----------------------------------------------------------------
	
	var table=document.createElement("table");
	var row=document.createElement("tr");
	for(var i=0;i<components.length;i++){
		var cell=document.createElement("td");
		components[i].targetElement=cell;
		components[i].paint();
		row.appendChild(cell);
	}
	table.appendChild(row);
	e.innerHTML="<table>"+table.innerHTML+"</table>";
	
};
HorizontalLayout.prototype.output=function(arg,e){
	e.innerHTML+=arg;e.innerHTML+=arg;
	
};
/******************
class GridBagLayout
******************/

function GridBagLayout(){}
GridBagLayout.prototype.template=null;
GridBagLayout.prototype.getTemplate=function(){return this.template;};
GridBagLayout.prototype.setTemplate=function(template){this.template=template;};
GridBagLayout.prototype.paint=function(container){
	debug("GridBagLayout.paint(): target element:"+this.targetElement);
	
	var components=container.getComponents();
	var e=container.targetElement;
	e.innerHTML=this.template;
	
	// generate the table structure ----------------------------------------------------------------
	
	//alert(e.innerHTML);
	// now collect cells for children to render into -----------------------------------------------
	
	var cells=this.getCells(e.getElementsByTagName("table")[0]);
	
	// paint children ------------------------------------------------------------------------------
	
	debug("GridBagLayout.paint() children - layout cells:"+cells.length);
	for(var i=0;i<components.length;i++){
		debug("GridBagLayout.paint() - paint child component at index: "+i);
		if(components[i]!=null){
			components[i].targetElement=cells[i];
			components[i].paint();
		}else{
			debug("GridBagLayout.paint() - skip cell: "+i);	
		}
	}
	//alert(e.innerHTML);
	//debug("painted all children");
	
	
	
};
GridBagLayout.prototype.getCells=function(tableElement){
	var allCells=new Array();
	debug("GridBagLayout.getCell("+tableElement+")");
	var rows=tableElement.getElementsByTagName("tr");
	for(var rowIndex=0;rowIndex<rows.length;rowIndex++){
		var rowElement=rows[rowIndex];
		debug("GridBagLayout.getCell(): row:"+rowElement);
		var cells=rowElement.getElementsByTagName("td");
		for(var cellIndex=0;cellIndex<cells.length;cellIndex++){
			debug("add cell:"+cells[cellIndex].innerHTML);
			allCells[allCells.length]=cells[cellIndex];
		}
	}
	//debug("processed template:"+allCells.length);
	return allCells;
	
};
/* javascript components: model*/

function getValueAt(row,col){
	
	
};
function getRowCount(){
	
};

function getColumnCount(){
	
};

function isEditable(row,col){
	
};
function getColumnName(col){
	
};
function getValueAt(row,col){
	
};
function getValueEnumeration(row,col){
	
	
};
function getCellClass(row,col){
	
	
};
function getRowSpan(row,col){
	
};
function getColSpan(row,col){
	
};
function getRowElementClass(row){
	
};
function getColumnElementClass(col){
	
	
	
};
function getColumnContentElementClass(col){
	
	
	
};
function getSize(){
	
	
};

function getElementAt(index){
	
	
};
function getElementClass(index){
	
	
};
function simplexml_load_file(file){
	var request;
	try{ // Internet Explorer
		request=new ActiveXObject("Microsoft.XMLDOM");
	}catch(ex){
		try{ // Firefox, Mozilla, Opera, ...
			request=new XMLHttpRequest();
			//xmlDoc=document.implementation.createDocument("","",null);
		}catch(ex){
			alert(e.message);
			return;
		}
	}
	//alert("load file:"+file);
	//xmlDoc.async=false;
	var browser=navigator.appName.toLowerCase();
	if(browser.indexOf("explorer")>0){
		request.async=false;
		request.load(file);
		return request;
	}else{
		request.open("GET",file,false);
		request.send(null);
		return request.responseXML;
	}
	
	
};
function setCookie(c_name,value,expiredays){
	var exdate=new Date();
	exdate.setDate(exdate.getDate()+expiredays);
	document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
	
	
};
function getCookie(c_name){
	if (document.cookie.length>0){
	  c_start=document.cookie.indexOf(c_name + "=");
	  if (c_start!=-1){ 
	    c_start=c_start + c_name.length+1; 
	    c_end=document.cookie.indexOf(";",c_start);
	    if (c_end==-1) c_end=document.cookie.length;
	    return unescape(document.cookie.substring(c_start,c_end));
	  }
	}
	return "";
	
};
function debug(arg){
	try{
		_debug_window.out("<code><small>"+arg+"</code></small><br>");
	}catch(err){};
	
};
function init_debug_window(){
	_debug_window=new DebugWindow();
};

