/**
 * @author Timo 10.04.2008
 * 
 */
function JSFunction(sName,aAttributes,sBody){//static => can't create simultaneous instances. Yuo must consume them instantly.
	this._name=sName;
	this._sBody=sBody;
	this._attributes=aAttributes;
	if(this._attributes==null){
		this._attributes=new Array();
	}
}//JSFunction

//public nonStatic
JSFunction.prototype.toString=function(){
	var _name=this._name;
	var _attributes=this._attributes;

	//private
	getEnd=function(){
		var sResult="\n"+JSFunction.BODY_END;
		return sResult;
	}

	//private
	getStart=function(){
		var sResult=_name;
		if(this._sBody!=null){
			sResult+="=function";
		}
		return sResult;
	}

	//private
	getHtmlAttributes=function(){
		var sResult="";
		if(_attributes!=null){
			sResult+=JSFunction.ATTRIBUTE_START;
			var i_while=0;
			var i_wend=_attributes.length;
			while(i_while<i_wend){
				var attribute=_attributes[i_while];
				if(attribute!=null){
					sResult+=attribute;
				}
				i_while=i_while+1;
				if(i_while<i_wend&&_attributes.length>1){
					sResult+=",";
				}
			}//while
			sResult+=JSFunction.ATTRIBUTE_END;
		}//if
		return sResult;
	}

	var sResult=getStart()+getHtmlAttributes();
	if(this._sBody!=null){
		sResult+="\n"+JSFunction.BODY_START+this._sBody+getEnd();
	}else{
		sResult+=";";
	}
	return sResult;
}//toString

//public
JSFunction.prototype.addAttribute=function(sValue){
	this._attributes[this._attributes.length]=sValue;
}

JSFunction.prototype.addStringAttribute=function(sValue){
	this._attributes[this._attributes.length]=HtmlAttribute.INNER_QUOTE+sValue+HtmlAttribute.INNER_QUOTE;
}

//terminology
JSFunction.BODY_END="}";
JSFunction.BODY_START="{";
JSFunction.ATTRIBUTE_END=")";
JSFunction.ATTRIBUTE_START="(";

JSFunction.S_EVENT="event";
JSFunction.S_THIS="this";

JSFunction.VOID=new JSFunction("void",[0],null);
JSFunction.FILE_EXTENSION=".js";

/**
 * @author Timo 28.09.2007
 * 
 */
function CssProperty(iName,sValue,bImportant){
	//protected
	this.iName=iName;
	this.sValue=sValue;
	this.bImportant=bImportant;
}//CssProperty

//public  nonStatic
CssProperty.prototype.toString=function(){
	var sResult="";
	if(this.sValue==null){
		this.sValue=CssProperty.defaults[this.iName];
	}
	if(this.sValue!=null){
		if(!isNaN(this.sValue)){
			this.sValue=parseInt(this.sValue);
		}
		sResult=CssProperty.names[this.iName]+":"+this.sValue;
		if(CssProperty.units[this.iName]!=null){
			sResult+=CssProperty.units[this.iName];
		}
		if(this.bImportant==true){
			sResult+=" !important";
		}
		sResult+=";";
	}
	if(CssProperty.helpers[this.iName]!=null){//add required additional css properties E.G: unicode-bidi:bidi-override; for direction:...
		sResult+=new CssProperty(CssProperty.helpers[this.iName]);
	}
	return sResult;
}//toString

CssProperty.prototype.setStringArray=function(stringArray){
	var result="";
	var i_while=0;
	var i_wend=stringArray.length;
	while(i_while<i_wend){
		var sValue=stringArray[i_while];
		if(sValue!=null){
			if(i_while>0){
				result+=",";
			}
			result+=CssProperty.getStringValue(sValue);
		}
		i_while=i_while+1;
	}//while
	this.sValue=result;
}

CssProperty.getStringValue=function(sValue){
	var result=HtmlAttribute.INNER_QUOTE+sValue+HtmlAttribute.INNER_QUOTE;
	return result;
}

//public terminology
//position
CssProperty.ABSOLUTE="absolute";
CssProperty.RELATIVE="relative";
//writing-mode
CssProperty.HORIZONTAL="lr-tb";
CssProperty.VERTICAL="tb-rl";
//direction
CssProperty.LEFTWARDS="rtl";
CssProperty.RIGHTWARDS="ltr";
//display
CssProperty.BLOCK="block";
CssProperty.INLINE="inline";
CssProperty.NONE="none";
CssProperty.TABLE="table";

var indexCssProperty=0;
CssProperty.I_BACKGROUND_COLOR=indexCssProperty++;
CssProperty.I_DIRECTION=indexCssProperty++;
CssProperty.I_DISPLAY=indexCssProperty++;
CssProperty.I_FONT_FAMILY=indexCssProperty++;
CssProperty.I_FONT_SIZE=indexCssProperty++;
CssProperty.I_HEIGHT=indexCssProperty++;
CssProperty.I_LEFT=indexCssProperty++;
CssProperty.I_LINE_HEIGHT=indexCssProperty++;
CssProperty.I_MARGIN=indexCssProperty++;
CssProperty.I_PADDING=indexCssProperty++;
CssProperty.I_PAGE_BREAK_AFTER=indexCssProperty++;
CssProperty.I_PAGE_BREAK_BEFORE=indexCssProperty++;
CssProperty.I_POSITION=indexCssProperty++;
CssProperty.I_RIGHT=indexCssProperty++;
CssProperty.I_TOP=indexCssProperty++;
CssProperty.I_UNICODE_BIDI=indexCssProperty++;
CssProperty.I_WIDTH=indexCssProperty++;
CssProperty.I_WRITING_MODE=indexCssProperty++;

CssProperty.names=new Array();
CssProperty.names[CssProperty.I_BACKGROUND_COLOR]="background-color";
CssProperty.names[CssProperty.I_DIRECTION]="direction";
CssProperty.names[CssProperty.I_DISPLAY]="display";
CssProperty.names[CssProperty.I_FONT_FAMILY]="font-family";
CssProperty.names[CssProperty.I_FONT_SIZE]="font-size";
CssProperty.names[CssProperty.I_HEIGHT]="height";
CssProperty.names[CssProperty.I_LEFT]="left";
CssProperty.names[CssProperty.I_LINE_HEIGHT]="line-height";
CssProperty.names[CssProperty.I_MARGIN]="margin";
CssProperty.names[CssProperty.I_PADDING]="padding";
CssProperty.names[CssProperty.I_PAGE_BREAK_AFTER]="page-break-after";
CssProperty.names[CssProperty.I_PAGE_BREAK_BEFORE]="page-break-before";
CssProperty.names[CssProperty.I_POSITION]="position";
CssProperty.names[CssProperty.I_RIGHT]="right";
CssProperty.names[CssProperty.I_TOP]="top";
CssProperty.names[CssProperty.I_UNICODE_BIDI]="unicode-bidi";
CssProperty.names[CssProperty.I_WIDTH]="width";
CssProperty.names[CssProperty.I_WRITING_MODE]="writing-mode";

CssProperty.units=new Array();
CssProperty.units[CssProperty.I_FONT_SIZE]="px";
CssProperty.units[CssProperty.I_HEIGHT]="px";
CssProperty.units[CssProperty.I_LEFT]="px";
CssProperty.units[CssProperty.I_LINE_HEIGHT]="px";
CssProperty.units[CssProperty.I_MARGIN]="px";
CssProperty.units[CssProperty.I_PADDING]="px";
CssProperty.units[CssProperty.I_RIGHT]="px";
CssProperty.units[CssProperty.I_TOP]="px";
CssProperty.units[CssProperty.I_WIDTH]="px";

CssProperty.helpers=new Array();
CssProperty.helpers[CssProperty.I_DIRECTION]=CssProperty.I_UNICODE_BIDI;

CssProperty.defaults=new Array();
CssProperty.defaults[CssProperty.I_UNICODE_BIDI]="bidi-override";
CssProperty.defaults[CssProperty.I_PAGE_BREAK_AFTER]="always";
CssProperty.defaults[CssProperty.I_PAGE_BREAK_BEFORE]="always";

/**
 * @author Timo 28.09.2007
 * 
 */
function HtmlAttribute(iName,sValue){
	this.iName=iName;
	this.sValue=sValue;
}//HtmlAttribute

//public  nonStatic
HtmlAttribute.prototype.toString=function(){
	var sResult="";
	if(this.sValue==null){
		this.sValue=HtmlAttribute.defaultValues[this.iName];
	}
	if(this.sValue!=null/*no way &&this.sValue!=""*/){
		sResult=HtmlAttribute.names[this.iName];
		sResult+="='"+this.sValue+"'";
	}
	return sResult;
}//toString

//public terminology
HtmlAttribute.INNER_QUOTE='"';

HtmlAttribute.BUTTON="button";
HtmlAttribute.CHECKBOX="checkbox";
HtmlAttribute.HIDDEN="hidden";
HtmlAttribute.TEXT="text";

var indexHtmlAttribute=0;
HtmlAttribute.I_ALT=indexHtmlAttribute++;
HtmlAttribute.I_CLASS=indexHtmlAttribute++;
HtmlAttribute.I_FRAME_BORDER=indexHtmlAttribute++;
HtmlAttribute.I_HEIGHT=indexHtmlAttribute++;
HtmlAttribute.I_HREF=indexHtmlAttribute++;
HtmlAttribute.I_ID=indexHtmlAttribute++;
HtmlAttribute.I_LANGUAGE=indexHtmlAttribute++;
HtmlAttribute.I_NAME=indexHtmlAttribute++;
HtmlAttribute.I_ON_BLUR=indexHtmlAttribute++;
HtmlAttribute.I_ON_CHANGE=indexHtmlAttribute++;
HtmlAttribute.I_ON_CLICK=indexHtmlAttribute++;
HtmlAttribute.I_ON_KEY_UP=indexHtmlAttribute++;
HtmlAttribute.I_ON_LOAD=indexHtmlAttribute++;
HtmlAttribute.I_ON_MOUSE_OUT=indexHtmlAttribute++;
HtmlAttribute.I_ON_MOUSE_OVER=indexHtmlAttribute++;
HtmlAttribute.I_ON_MOUSE_UP=indexHtmlAttribute++;// enable to select the only option
HtmlAttribute.I_REL=indexHtmlAttribute++;
HtmlAttribute.I_SELECTED=indexHtmlAttribute++;
HtmlAttribute.I_SIZE=indexHtmlAttribute++;
HtmlAttribute.I_SRC=indexHtmlAttribute++;
HtmlAttribute.I_STYLE=indexHtmlAttribute++;
HtmlAttribute.I_TITLE=indexHtmlAttribute++;
HtmlAttribute.I_TYPE=indexHtmlAttribute++;
HtmlAttribute.I_VALUE=indexHtmlAttribute++;

HtmlAttribute.names=new Array();
HtmlAttribute.names[HtmlAttribute.I_ALT]="alt";
HtmlAttribute.names[HtmlAttribute.I_CLASS]="class";
HtmlAttribute.names[HtmlAttribute.I_FRAME_BORDER]="frameborder";
HtmlAttribute.names[HtmlAttribute.I_HEIGHT]="height";
HtmlAttribute.names[HtmlAttribute.I_HREF]="href";
HtmlAttribute.names[HtmlAttribute.I_ID]="id";
HtmlAttribute.names[HtmlAttribute.I_LANGUAGE]="language";
HtmlAttribute.names[HtmlAttribute.I_NAME]="name";
HtmlAttribute.names[HtmlAttribute.I_ON_BLUR]="onblur";
HtmlAttribute.names[HtmlAttribute.I_ON_CHANGE]="onchange";
HtmlAttribute.names[HtmlAttribute.I_ON_CLICK]="onclick";
HtmlAttribute.names[HtmlAttribute.I_ON_KEY_UP]="onkeyup";
HtmlAttribute.names[HtmlAttribute.I_ON_LOAD]="onload";
HtmlAttribute.names[HtmlAttribute.I_ON_MOUSE_OUT]="onmouseout";
HtmlAttribute.names[HtmlAttribute.I_ON_MOUSE_OVER]="onmouseover";
HtmlAttribute.names[HtmlAttribute.I_ON_MOUSE_UP]="onmouseup";// enable to select the only option
HtmlAttribute.names[HtmlAttribute.I_REL]="rel";
HtmlAttribute.names[HtmlAttribute.I_SELECTED]="selected";
HtmlAttribute.names[HtmlAttribute.I_SIZE]="size";
HtmlAttribute.names[HtmlAttribute.I_SRC]="src";
HtmlAttribute.names[HtmlAttribute.I_STYLE]="style";
HtmlAttribute.names[HtmlAttribute.I_TITLE]="title";
HtmlAttribute.names[HtmlAttribute.I_TYPE]="type";
HtmlAttribute.names[HtmlAttribute.I_VALUE]="value";

HtmlAttribute.defaultValues=new Array();
//HtmlAttribute.defaultValues[HtmlAttribute.I_CLASS]="class";
HtmlAttribute.defaultValues[HtmlAttribute.I_HREF]="#";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ID]="id";
//HtmlAttribute.defaultValues[HtmlAttribute.I_NAME]="name";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ON_CHANGE]=";";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ON_CLICK]=";";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ON_MOUSE_OUT]=";";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ON_MOUSE_OVER]=";";
//HtmlAttribute.defaultValues[HtmlAttribute.I_ON_MOUSE_UP]=";";// enable to select the only option
HtmlAttribute.defaultValues[HtmlAttribute.I_REL]="stylesheet";
HtmlAttribute.defaultValues[HtmlAttribute.I_SELECTED]="selected";
//HtmlAttribute.defaultValues[HtmlAttribute.I_SIZE]="1";
//HtmlAttribute.defaultValues[HtmlAttribute.I_SRC]=".";
HtmlAttribute.defaultValues[HtmlAttribute.I_TYPE]=HtmlAttribute.TEXT;

HtmlAttribute.defaultValues[HtmlAttribute.I_VALUE]="value";

/**
 * @author Timo 28.09.2007
 * 
 */
function HtmlTag(name,innerHTML){//static => can't create simultaneous instances. Yuo must consume them instantly.
	//var name=name; - protected static variable
	//this.name=innerHTML; - public static variable
	//doSomething=function(){return true;} - protected static method
	//this.doSomething=function(){return true;} - public static method

	this._name=name;
	this._innerHTML=innerHTML;
	this._attributes=new Array();
}//HtmlTag

//public nonStatic
HtmlTag.prototype.toString=function(){
	var _name=this._name;
	var _attributes=this._attributes;

	//private
	getEndTag=function(){
		var sResult=HtmlTag.END_TAG_START+_name+"\n"+HtmlTag.TAG_END;
		return sResult;
	}

	//private
	getStart=function(){
		var sResult=HtmlTag.TAG_START+_name+getHtmlAttributes();
		return sResult;
	}

	//private
	getHtmlAttributes=function(){
		var sResult="";
		if(_attributes!=null){
			var i_while=0;
			var i_wend=_attributes.length;
			while(i_while<i_wend){
				var attribute=_attributes[i_while];
				if(attribute!=null){
					sResult+="\n "+attribute;
				}
				i_while=i_while+1;
			}//while
		}//if
		return sResult;
	}

	var sResult=getStart();
	if(this._innerHTML!=null){
		sResult+="\n"+HtmlTag.TAG_END+this._innerHTML+getEndTag();
	}else{
		sResult+="/"+HtmlTag.TAG_END;
	}
	return sResult;
}//toString

//public
HtmlTag.prototype.addHtmlAttribute=function(iName,sValue){
	this._attributes[iName]=new HtmlAttribute(iName,sValue);
}

//private
HtmlTag.prototype.getSelectBox=function(id,name,aOptions){
	var sItems="";
	var i_while=0;
	var i_wend=aOptions.length;
	while(i_while<i_wend){
		var optionData=aOptions[i_while];
		var vOption=new HtmlTag(HtmlTag.OPTION,optionData[0]);
		vOption.addHtmlAttribute(HtmlAttribute.I_VALUE,optionData[1]);
		if(optionData[2]!=null){
			vOption.addHtmlAttribute(HtmlAttribute.I_ID,optionData[2]);
		}
		sItems+=vOption;
		i_while=i_while+1;
	}//while

	var sResult=new HtmlTag(HtmlTag.SELECT,sItems);
	sResult.addHtmlAttribute(HtmlAttribute.I_ID,id);
	sResult.addHtmlAttribute(HtmlAttribute.I_NAME,name);
	return sResult;
}//getSelectBox

//terminology
HtmlTag.ANCHOR="a";
HtmlTag.BOLD="b";
HtmlTag.BODY="body";
HtmlTag.BREAK="br";
HtmlTag.DIV="div";
HtmlTag.FORM="form";
HtmlTag.HTML="html";
HtmlTag.HEAD="head";
HtmlTag.IFRAME="iframe";
HtmlTag.IMG="img";
HtmlTag.INPUT="input";
HtmlTag.ITALIC="i";
HtmlTag.LINK="link";
HtmlTag.OPTION="option";
HtmlTag.PREFORMED="pre";
HtmlTag.SCRIPT="script";
HtmlTag.SELECT="select";
HtmlTag.SPAN="span";
HtmlTag.STYLE="style";
HtmlTag.TEXTAREA="textarea"
HtmlTag.TITLE="title";
HtmlTag.UNDERLINE="u";

//single tags
HtmlTag.LINE=new HtmlTag("hr");
HtmlTag.LINE.innerHTML=null;
HtmlTag.LINE_BREAK=new HtmlTag(HtmlTag.BREAK); // "<br/>";
HtmlTag.LINE_BREAK.innerHTML=null;
HtmlTag.PRINT_BREAK_AFTER=new HtmlTag(HtmlTag.BREAK); //'<br style="page-break-after:always;"/>';
HtmlTag.PRINT_BREAK_AFTER.addHtmlAttribute(HtmlAttribute.I_STYLE,new CssProperty(CssProperty.I_PAGE_BREAK_AFTER));
HtmlTag.PRINT_BREAK_BEFORE=new HtmlTag(HtmlTag.BREAK); //'<br style="page-break-before:always;"/>';
HtmlTag.PRINT_BREAK_BEFORE.addHtmlAttribute(HtmlAttribute.I_STYLE,new CssProperty(CssProperty.I_PAGE_BREAK_BEFORE));
//characters
HtmlTag.WHITE_SPACE="&nbsp;";
if(typeof(MathHandler)!="undefined"&&typeof(Log)!="undefined"&&typeof(Log.charTool)!="undefined"){
	HtmlTag.TABULATOR=Log.charTool.toUtf(MathHandler.changeBase(Log.charTool._I_TAB, 16));//transcribeFirstPart
} 

HtmlTag.TAG_END=">";// "> HtmlTag.TAG_END <"
HtmlTag.TAG_START="<";
HtmlTag.END_TAG_START=HtmlTag.TAG_START+"/";
HtmlTag.FILE_EXTENSION=".html";
//HtmlTag.HREF_JS="javascript:"+HtmlTag.ID;

HtmlTag.getScript=function(sJScript,jsSrc){
	if(sJScript==null){
		sJScript='';
	}//if
	var scriptTag=new HtmlTag(HtmlTag.SCRIPT,sJScript);
	scriptTag.addHtmlAttribute(HtmlAttribute.I_TYPE, 'text/javascript');
	if(jsSrc!=null){
		scriptTag.addHtmlAttribute(HtmlAttribute.I_SRC,jsSrc);
	}//if
	return scriptTag;
}//getScript

HtmlTag.getHead=function(title,style,jsSrcs){
	var result=new HtmlTag(HtmlTag.TITLE,title)+'';
	result+=new HtmlTag(HtmlTag.STYLE,style);
	var i_while=0;
	if(jsSrcs==null){
		jsSrcs=[];
	}//if
	var i_wend=jsSrcs.length;
	while(i_while<i_wend){
		var jsSrc=jsSrcs[i_while];
		var scriptTag=HtmlTag.getScript('',jsSrc);
		/*
		var scriptTag=new HtmlTag(HtmlTag.SCRIPT,'');
		scriptTag.addHtmlAttribute("language","javascript");
		scriptTag.addHtmlAttribute(HtmlAttribute.I_SRC,jsSrc);
		 */
		result+=scriptTag;
		i_while=i_while+1;
	}//while
	return new HtmlTag(HtmlTag.HEAD,result);
}//getHead

HtmlTag.getBody=function(body){
	return new HtmlTag(HtmlTag.BODY,body);
}//getBody

HtmlTag.getWindowHtml=function(head,body){
	return new HtmlTag(HtmlTag.HTML,''+head+body);
}//getWindowHtml

//public static 
HtmlTag.replaceInnerHtml=function(sHtmlTag,sInnerHtml){
	return sHtmlTag.replace(HtmlTag.TAG_END+HtmlTag.TAG_START,HtmlTag.TAG_END+sInnerHtml+HtmlTag.TAG_START);
}//replaceInnerHtml

//public static 
HtmlTag.disable=function(tag){
	var result=(tag+"");// .toLowerCase().
	while(result.indexOf(" on")!=-1){
		result=result.replace(" on","");
	}
	return result;
}//disable

HtmlTag.hasTagNameFrom=function(e_lement, aTagName){
	if(e_lement!=null&&e_lement.tagName!=null){
		var lowerCaseTagName=e_lement.tagName.toLowerCase();
		var i_while=0;
		var i_wend=aTagName.length;
		while(i_while<i_wend){
			var sTagName=(aTagName[i_while]+"").toLowerCase();
			if(lowerCaseTagName==sTagName){
				return true;
			}//if
			i_while=i_while+1;
		}//while
	}//if
	return false;
}//hasTagName  

HtmlTag.hasSingleTag=function(s_input, sTagName){//does not validate html // does not care, if the tag is followed or preceded by something
	if(s_input!=null){
		s_input=(s_input+"").toLowerCase();//ensure it's a string
		sTagName=sTagName.toLowerCase();
		if(
				(
						s_input.indexOf(HtmlTag.TAG_START+sTagName)!=-1
						&&
						s_input.indexOf(HtmlTag.TAG_START+sTagName)==s_input.indexOf(HtmlTag.TAG_START)//is the first tag
				)
				&&
				(
						(
								s_input.indexOf(HtmlTag.END_TAG_START)!=-1
								&&
								s_input.indexOf(HtmlTag.END_TAG_START)==s_input.lastIndexOf(HtmlTag.END_TAG_START)//has only one closing tag
						)
						||
						(
								s_input.indexOf(HtmlTag.TAG_END)!=-1
								&&
								s_input.indexOf(HtmlTag.TAG_END)==s_input.lastIndexOf(HtmlTag.TAG_END)//has nor closing tag neither innerHTML
						)
				)
		){
			return true;
		}//if
	}//if
	return false;
}//hasSingleTag  


