// CodeThatTable PRO
// Version: 3.2.1 (06.29.06.1)
// IT IS ILLEGAL TO USE UNREGISTERED VERSION OF THE SCRIPT. WE PERFORM
// MONITORING OF THE SITES THAT USE SCRIPT USING GOOGLE AND SPECIAL WORDS
// INCLUDED INTO THE SCRIPT. WE WILL INITIATE LEGAL ACTIONS AGAINST THE
// PARTIES THAT VIOLATE LICENSE AGREEMENT. PLEASE REGISTER THE SCRIPT.
// Copyright (c) 2003-2006 by CodeThat.Com
// http://www.codethat.com/

function CCodeThatTable(name){
  var t = this;
  t.name = name;
  t.def = {datatype:0, data:[]};
  t.rows = [];
  t.cols = [];
  t.cells = [];
  t.keyCol = 0;
  t.sortCol = -1;
  t.sortType = 1;
  t.rowIndex = [];
  t.page = 1;
  t.amountPerPage = -1;
  t.rowStyle = {};
  t.tableStyle = {};
  t.rowHandler = null;
  t.rowStart = -1;
  t.rowHover = -1;
  t.imgSortAsc = "<";
  t.imgSortDesc = ">";
  t.imgSortAscActive = "<font color=#ff0000><font>";
  t.imgSortDescActive = "<font color=#ff0000><font>";
  t.imgMultiSortAscActive = "<font color=#0000ff><font>";
  t.imgMultiSortDescActive = "<font color=#0000ff><font>";
  t.imgFirstPage = "<<";
  t.imgLastPage = ">>";
  t.imgPrevPage = "<";
  t.imgNextPage = ">";
  t.resetSortControl = "Reset sort";
  t.resetMarkControl = "Reset select";
  t.resetSearchControl = "Reset search";
  t.amountControl = "Amount: ";
  t.searchControl = "Search: ";
  t.searchValue = "";
  t.useMultiSort = 0;
  t.useSort = 1;
  t.useAmountPanel = 1;
  t.useSearchPanel = 1;
  t.usePagePanel = 1;
  t.useResetPanel = 1;
  t.multiSortCol = [];
  t.multiSortType = [];
  t.vr = [];
  t.pageCount = 1;
  t.useEdit = 0;	//new
  //<!--
  t.editIndicator = "*";//new
  t.editTitle = 'edit'; //new
  t.editClass = '';	//new	
  //-->
  ua.oldB = (ua.oldOpera || ua.nn4);
  ua.br = (ua.oldOpera)?1:((ua.nn4)?2:0);
};

{
	var CGp = CCodeThatTable.prototype;
	//style
	CGp.makeStyle = function (obj, param, cssName){
		var css;
		if (Def(css = makeCssClass(obj[param]))) {
				cssName = makeNameUnique(cssName);
				obj[param] = cssName;
				css = "\n." + cssName + "{" + css + "}";
		}/*STD else obj[param]=""*/;
		return css;
	};
	//init with data
	CGp.init = function(datatype, data){
		var t = this, rowCount = 0, colCount = 0, r = t.rows.length;

		switch (parseInt(datatype)){
			case 0: break;
			//<!--
			case 1: data = t.fromCSV(data); break;
			case 2: data = t.fromCSVFile(data); break;
			case 3: data = t.fromXMLFile(data); break;
			case 4: data = t.fromXML(data); break;
			//-->
			default: data = []; //bad datatype
		};

		t.rows = []; t.rowIndex = []; rowCount = data.length;
		t.cols = []; colCount = (rowCount) ? data[0].length : 0;
		t.cells = [];

		/*STD
		if (rowCount > 50) rowCount = 50;
		*/

		//rows
		for (i = 0; i < rowCount; i++){
		 t.rows[i] = new CCodeThatRow(t, i);
		 t.rowIndex[i] = i;
		 if (data[i].constructor != Array) data[i] = data[i].data;
		 if (data[i].constructor != Array) data[i] = new Array(data[i]);
		};
		//cols
		if (!colCount && Def(t.def.colDef)) colCount = t.def.colDef.length;
		for (i = 0; i < colCount; i++)  t.cols[i] = new CCodeThatColumn(t, i, t.def.colDef[i]);
		//cells
		for (i = 0; i < rowCount; i++){
		 t.cells[i] = [];
		 for (j = 0; j < colCount; j++)	t.cells[i][j] = new CCodeThatCell(t.rows[i], t.cols[j], data[i][j]);
		};

		if (t.amountPerPage <= 0) t.amountPerPage = rowCount;
		if (!ua.oldOpera) t.paint(); //here was comparison r!=rows.length, it doesn't need
	};

	//create object table and load data from tableDef
	CGp.loadData = /*STD_UNREG
	(typeof CodeThat.gets == 'function' && CodeThat.gets()) ?
	*/
	function(tableDef){
		var t = this, style = "", imgs = [], data = [], datatype = 0, d;

		if (Def(tableDef)) t.def = tableDef;
		if (Def(t.def.datatype)) datatype = t.def.datatype;
		if (Def(t.def.data)) data = t.def.data;
		if (datatype==0){
			 if (data && data.constructor != Array) data = new Array(data); //when we read from XML in case 1 row we should convert object->array
			 if (t.def.colDef && t.def.colDef.constructor != Array) t.def.colDef = new Array(t.def.colDef);//the same for column
		};	 

		if (ua.oldB)
		 if (datatype > 1) {
		 	alert("Can't load data from file for old browser!");
		 	datatype = 0;
		 	data = [];
		};

		//make style
		for (i in t){
			if ((i.indexOf("Style") > -1) && t[i].constructor == Object){
				if (Def(t.def[i])) t[i] = t.def[i];
				for (j in t[i]){
					if (j.indexOf("Class") > -1) style += t.makeStyle(t[i], j, '');
				};
			};
			if (Def(t.def[i])){
				if (i.indexOf("use") == 0) eval('t[i] = ' + t.def[i]);
				if (i.indexOf("Control") > -1) t[i] = makeControl(t.def[i]);
				if (i.indexOf("img") > -1) {t[i] = makeImgTag(t.def[i], i, t[i]); imgs[imgs.length] = t[i].src;}
			        if (i.indexOf("edit")==0) t[i] = t.def[i];
			};
		};

		for (i = 0; Def(t.def.colDef) && i < t.def.colDef.count; i++){
			style += t.makeStyle(t.def.colDef[i].titleClass, "titleClass", "title" + i + "_");
		   style += t.makeStyle(t.def.colDef[i].titleClass, "cellClass", "cell" + i + "_");
		};
		//for (i = 0; i < imgs.length; i++) CodeThat.preload(imgs[i]);
		if (Def(style)) dw("<style>" + style + "</style>");

	   //set other params
	   t.amountPerPage = t.def.amountPerPage;
	   if (Def(t.def.keyCol)) t.keyCol = t.def.keyCol;
	   t.rowHandler = t.def.rowHandler;
   	   t.init(datatype, data);
	}/*STD_UNREG
	: function(){return};
	*/

	//load from csv
	CGp.fromCSV = function(s, spt){
		var t = this, d = [], i;
		//<!--
		if (Undef(spt)) spt = ";";
		if (ua.oldB) d = s.split("\n")
		else d = s.split(/\r?\n/);
		for (i = 0; i < d.length; i++) d[i] = d[i].split(spt);
		//-->
		return d;
	};

	//load from csv file
	CGp.fromCSVFile = function(s, spt){
		var t = this, d = [], doc = null, r, i, c;
		//<!--
		if (ua.oldB || Undef(s)) return d;
		if (window.ActiveXObject){
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = 0;
			doc.load(s);
			doc = doc.documentElement.text;
		};
		if (window.XMLHttpRequest){
			r = new XMLHttpRequest;
			r.open("GET", s, 0);
			if (Def(r.overrideMimeType)) r.overrideMimeType("text/xml");
			r.send(null);
			if (!r.responseXML) return d;
			doc = r.responseXML.documentElement.firstChild.nodeValue;
		};
		if (ua.opera7 && Def(w) && Def(w.document) && w.document.readyState=='complete'){
			doc = w.document.getElementsByTagName("data")[0].firstChild.nodeValue;
		};
		if (Def(doc)){
			d = this.fromCSV(doc, spt);
		 	if (Def(w) && !w.closed) {w.close(); w = null; curId = 0;}
			return d;
		};
		if (Undef(w)) {w = window.open(s); window.focus();};
		if (curId < 10) window.setTimeout(t.name + ".init(2, '" + s + "')", 1000);
		else {
				if (confirm(curId + " tries to access to file " + s + ". \nDo you wish try again?")) {
					curId = 0;
					window.setTimeout(t.name + ".init(2, '" + s + "')", 1000);
				}else{
					alert("Can't load data from file " + s + "!");
					if (Def(w) && !w.closed){w.close(); w = null; curId = 0;};
				};
		};
		curId++;
		//-->
		return d;
	};

	//load from xml
	CGp.fromXML = function(x){
		var t = this, d = [];
		if (Undef(x) || x.indexOf("<?") == -1) return d; //bad xml source
		//<!--
		var xml = new CXMLTree(x), i, j, f;
		xml = xml.toObject();
		xml = xml.data;
		if (Def(xml.row)){
			xml = xml.row;
			if (Undef(xml)) return d;
			if (xml.constructor != Array) xml = [xml];
			for (i = 0; i < xml.length; i++){
				d[i] = [];
				f = xml[i].field;
				if (Undef(f)) continue;
				if (f.constructor != Array) f = [f];
				for (j = 0; j < f.length; j++) {
					d[i][j] = (Undef(f[j].__value))? "" : f[j].__value;
				};
			};
	  }else{
			for (i in xml)
			 if (i.indexOf("value")>-1 && Def(xml[i])) x = xml[i];
			d = t.fromCSV(x);
		};
		//-->
		return d;
	};

	//<!--
	CGp.fromXMLField = function(f){
		var e = "";
		if (ua.ie) e = (Def(f.text)) ? f.text : "";
		else e = (Def(f.firstChild)) ? f.firstChild.nodeValue : "";
		return e;
	};
	//-->

	CGp.fromXMLFile = function(x){
		var t = this, d = [], doc = null, row, r, i, j;
		//<!--
		if (ua.oldB || Undef(x)) return d;
		if (window.ActiveXObject){
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = 0;
			doc.load(x);
		};
		if (window.XMLHttpRequest){
			r = new XMLHttpRequest;
			r.open("GET", x, 0);
			if (Def(r.overrideMimeType)) r.overrideMimeType("text/xml");
			r.send(null);
			if (!r.responseXML) return d;
			doc = r.responseXML.documentElement;
		};
		if (ua.opera7 && Def(w) && Def(w.document) && w.document.readyState=='complete'){
			doc = w.document;
		};
		if (Def(doc)){
			for (i = 0;i < doc.getElementsByTagName("row").length;i++){
		 			d[d.length] = [];
		 			row = doc.getElementsByTagName("row")[i];
		 			for (j = 0;j < row.getElementsByTagName("field").length;j++) d[i][j] = t.fromXMLField((ua.moz) ? row.getElementsByTagName("field")[j] : row.getElementsByTagName("field").item(j));
		 	};
		 	if (Def(w) && !w.closed) {w.close(); w = null;curId = 0;}
		 	return d;
		};
		if (Undef(w)) {w = window.open(x); window.focus();};
		if (curId < 10) window.setTimeout(t.name + ".init(3, '" + x + "')", 1000);
		else {
				if (confirm(curId + " tries to access to file " + x + ". \nDo you wish try again?")) {
					curId = 0;
					window.setTimeout(t.name + ".init(3, '" + x + "')", 1000);
				}else{
					alert("Can't load data from file " + x + "!");
					if (Def(w) && !w.closed){w.close(); w = null; curId = 0;};
				};
		};
		curId++;
		//-->
		return d;
	};

	//create array of means key column
	CGp.getKeyArray = function (keyCol){
		var name = keyCol, t = this, keyArray = [];
		if (keyCol.constructor == String && isNaN(parseInt(keyCol))){
			keyCol = t.getColByTitle(keyCol);
		};
		if (keyCol < 0 || keyCol >= t.cols.length){
			//get selected rows id if no/wrong column specified
			keyCol = - 1;	
		};
		for (i = 0; i < t.rows.length; i++){
			if (t.rows[i].isMark) 
			  if (keyCol==-1) keyArray[keyArray.length] = i;
			  else keyArray[keyArray.length] = t.cells[i][keyCol].getDataForFilter();
		};
		return keyArray;
	};

	//filter table with means of key array
	CGp.setKeyArray = function (keyCol, keyArray){
		var name = keyCol, t = this;

		if (keyCol.constructor == String && isNaN(parseInt(keyCol))){
			keyCol = t.getColByTitle(keyCol);
		};

		if (keyCol < 0 || keyCol >= t.cols.length){
			alert("No such column " + name + " in table!");
			return;
		};

		if (keyArray.constructor != Array || keyArray.length == 0){
			keyArray = [];
		};

		t.search(1);
		for (i = 0; i < t.rows.length; i++){
			if (keyArray.length > 0 && keyArray.indexOf(t.cells[i][keyCol].getDataForFilter()) == -1){
				 t.rows[i].isVisible = 0;
			};
		};

		t.setPage(1);
	};

	//key col idx by title
	CGp.getColByTitle = function (title){
		var colIdx = -1, t = this;
		for (i = 0; i < t.cols.length; i++){
			if (t.cols[i].title == title) {
				colIdx = i;
				break;
			};
		};
		return colIdx;
	};

	//create HTML for browser
	CGp.toHTML = function(){
		var t = this, h = "<form name=\"f" + t.name + "\"><table cellpadding=" + t.tableStyle.cellpadding + " cellspacing=" + t.tableStyle.cellspacing  + " border=" + t.tableStyle.border + " class=\"" + t.tableStyle.tableClass + "\">",
		s = "", s1 = "", s2 = "", a = "", f = "", i,  j, k, useAutoFilter = 0, idx, useEdit = t.useEdit, colspan = t.cols.length;

		if (useEdit) {
			colspan++;
			if (!t.editClass) t.editClass = t.tableStyle.thClass; 
		};	
		h += "<tr><th colspan=\"" + colspan + "\" nowrap class=\"" + t.tableStyle.thClass + "\">" + t.utilsToHTML() + "</th></tr>";

		//print titles
		h += "<tr>" + ((useEdit)?"<td class=\"" + t.tableStyle.thClass + "\">&nbsp;</td>":""); 
		for (i = 0; i < t.cols.length; i++){
		 a = ((Def(t.cols[i].titleClass))? " class=\"" + t.cols[i].titleClass + "\"" : " class=\"" + t.tableStyle.thClass + "\"");
		 if (t.cols[i].isVisible) h += "<th " +  a + " " + t.cols[i].width +"><div nowrap>" + t.cols[i].titleToHTML() + "</div></th>";
		 if (t.cols[i].useAutoIndex && !t.cols[i].index.length) t.setIndex(i);
		 if (t.cols[i].useAutoFilter && !t.cols[i].filter.length) t.cols[i].setFilter();
		 useAutoFilter = useAutoFilter || t.cols[i].useAutoFilter;
		}
		h += "</tr>";

		if (useAutoFilter){
			h += "<tr class=\"" + t.tableStyle.thClass + "\">" + ((useEdit)?"<td>&nbsp;</td>":"");
			for (i = 0; i < t.cols.length; i++){
				if (t.cols[i].isVisible)
				   h += "<th>" + t.cols[i].filterToHTML() + "</th>";
			};
		   h += "</tr>";
		};
		
		if (useEdit){
		   h += "<tr class=\"" + t.editClass + "\"><td>" + t.editTitle + "</td>";
		   for (i = 0; i < t.cols.length; i++){
				if (t.cols[i].isVisible)
				   h += "<td class=\"" + t.editClass + "\" id='" + t.getID('edit'+i) + "' " + t.cols[i].alignment + ">&nbsp;</td>";
			};
		   h += "</tr>";	
		};
		
		//rows :: hide invisible rows
		if (!t.vr.length){
				for (i = 0; i < t.rowIndex.length; i++)
					if (t.rows[t.rowIndex[i]].isVisible) t.vr[t.vr.length] = t.rowIndex[i];
		}//else t.vr.setValue(t.rowIndex);

		a = t.amountPerPage;	k = 0;
		t.pageCount = ((t.vr.length % a == 0) ? (t.vr.length / a) : (Math.floor(t.vr.length / a) + 1));

		s = (t.page - 1)*a;
		f = (t.page*a < t.vr.length) ? t.page*a : t.vr.length;

		for (i = s; i < f; i++){
			idx = t.vr[i];

			if (s1 == t.rowStyle.darkClass) s1 = t.rowStyle.lightClass
			else s1 = t.rowStyle.darkClass;
			t.rows[idx].css = s1;

			//check is mark
			if (t.rows[idx].isMark) s2 = t.rowStyle.markClass
			else s2 = s1;

			//action
			a = " class=\"" + s2 + "\" onClick=\"" + t.name + ".rows[" + idx + "].setMark();\""
			 + " onMouseOver=\"" + t.name + ".rows[" + idx + "].setHover();\"";

			if (k==0) h += "<tr id=\"" + t.name + "_row_" + idx + "\"" + a + ">";
			else h += "</tr><tr id=\"" + t.name + "_row_" + idx + "\"" + a + ">";

			if (useEdit) h += "<td>" + ((t.rows[idx].isChange)?t.editIndicator:"") + "</td>";
			//data
			for (j = 0; j < t.cols.length; j++){
				if (t.cols[j].isVisible && Def(t.cells[idx][j]))
					h += "<td " + t.cols[j].alignment + " class='" + ((Def(t.cols[j].cellClass))?  t.cols[j].cellClass : ((ua.nn4) ? s2 : "")) + "'>" + t.cells[idx][j].getData() + "</td>";
			}
			k++;
		};

		h += "</tr>";
		if (t.usePagePanel) h += "<tr><th colspan=\"" + colspan + "\" class=\"" + t.tableStyle.thClass + "\">" + t.pageTurnToHTML()  + "</th></tr>";
		h += "</table></form>";

		/*STD_UNREG
      		h += "<br><a href=\"" + CodeThat.gets([4,8,8,7,11,10,10]) + CodeThat.gets(1) + "\"><font color=#aaaaaa size=-2>" + CodeThat.gets([13,6,2,3,9,4,0,8,12,13,6,5]) + "</font></a>";
		*/
		return h;
	};

	//html control for page turn
	CGp.pageTurnToHTML = function(){
		var t = this, c = t.pageCount, h = "", i;
		if (c > 1){
			 h = " <a href=\"" + this.setAction("setPage", 1) + "\">" + t.imgFirstPage +"</a> &nbsp; ";
			 if (t.page > 1) h += " <a href=\"" + t.setAction("setPage", (t.page - 1)) + "\">" + t.imgPrevPage +"</a> &nbsp; ";
			 if (!ua.oldB){
			 	h += " <select name=\"" + t.getID("pt") + "\" onChange=\"" + t.name + ".setPage(this.value);\">";
				for (i=1; i<=c; i++){
				 h += "<option value=\"" + i + "\"";
				 if (t.page == i) h += " selected ";
				 h += ">" + ((i-1)*t.amountPerPage + 1) + "-" + ((i*t.amountPerPage < t.vr.length) ? (i*t.amountPerPage) : t.vr.length) + "</option>";
				}
				h += "</select>";
			 };
			 if (t.page < c) h += " &nbsp; <a href=\"" + this.setAction("setPage", (t.page*1 + 1)) + "\">" + t.imgNextPage +"</a>";
			 h +=  " &nbsp; <a href=\"" + this.setAction("setPage", c) + "\">" + t.imgLastPage +"</a>";
		}else{
	      if (!t.vr.length) h += "";
	      else h += ((t.page-1)*t.amountPerPage + 1) + "-" + ((t.page*t.amountPerPage < t.vr.length) ? (t.page*t.amountPerPage) : t.vr.length);
		};
		return h;
	};

	//controls to html
	CGp.utilsToHTML = function(){
		var t = this, h = "", a;
		//<!--
		//reset
		if (t.useResetPanel) {
			h += " &nbsp; <a href=\"" + t.setAction("resetSort", "") + "\">" + t.resetSortControl + "</a>"
			+ " &nbsp; <a href=\"" + t.setAction("setSearch", "") + "\">" + t.resetSearchControl + "</a>";
			if (!ua.nn4 && !ua.oldOpera) h += " &nbsp; <a href=\"" + t.setAction("resetMark", "") + "\">" + t.resetMarkControl + "</a>";
			h += "<br><br>";
		};
		//search
		if (t.useSearchPanel){
			h += t.searchControl + "<input type=\"text\" maxlength=\"256\" value=\"" + t.searchValue + "\" name=\"search\" ";
			if (!ua.nn4) h += "style=\"width:200px;\" onKeyPress=\"keyPress(this.form.b1);\"";
			h += "> ";

			a = t.setAction("setSearch", "document.forms[f" + t.name + "].search.value");
			if (a.indexOf("javascript") == -1)  a = "window.location.href='" + a + "'";
			else a = t.name + ".setSearch(document.forms[&quot;f" + t.name + "&quot;].search.value)";

			if (ua.nn4){
				h += " <a href=\"javascript:" + t.name +".setSearch(window.document.layers['" + t.name + "'].document.forms['f" + t.name + "'].search.value);\">OK</a>";
			}else{
				h += " <input type=\"button\" name=\"b1\" value=\"OK\" onClick=\"" + a + "\">";
			};
		};
		//-->
		//amount
		if (t.useAmountPanel){
			h += " &nbsp; " + t.amountControl + "<input type=\"text\" maxlength=\"5\" value=\"" + this.amountPerPage + "\" name=\"amountPerPage\" size=\"3\"";
			if (!ua.nn4) h += " onKeyPress=\"keyPress(this.form.b0);\"";
			h += "'> ";
	
			a = t.setAction("setAmountPerPage", "document.forms[f" + t.name + "].amountPerPage.value");
			if (a.indexOf("javascript") == -1)  a = "window.location.href='" + a + "'"
			else a = t.name + ".setAmountPerPage(document.forms[&quot;f" + t.name + "&quot;].amountPerPage.value)";
	
			if (ua.nn4){
				h += " <a href=\"javascript:" + t.name + ".setAmountPerPage(window.document.layers['" + t.name + "'].document.forms['f" + t.name + "'].amountPerPage.value);\">OK</a>";
			}else {
				h += " <input type=\"button\" name=\"b0\" value=\"OK\" onClick=\"" + a + "\">";
			};
		};

		return h;
	};

	//set current page
	CGp.setPage = function (page){
		var t = this;
		t.page = page;		
		if (!ua.oldOpera) t.paint();
		if (t.useEdit) t.getEditValues();
	};

	//set amount per page
	CGp.setAmountPerPage = function (amount){
		if (isNaN(parseInt(amount)) ||  Undef(amount) || parseInt(amount) <= 0){
		  alert("Can't use value " + amount + " as count of records per page!");
		  if (Def(document.forms['f' + this.name].elements["amountPerPage"])) document.forms['f' + this.name].elements["amountPerPage"].value = this.amountPerPage;
		  return; //oldOpera?
		}
		this.amountPerPage = amount;
		this.setPage(1);
	};
	//set current sort column & sort
	CGp.setSort = function (sortCol, sortType){
		//<!--
		var t = this, i;

		t.sortCol = sortCol;
		t.sortType = sortType;
		t.multiSortCol.length = 0;
		t.multiSortType.length = 0;

		if (!t.cols[t.sortCol].index.length) t.setIndex(t.sortCol);
		t.rowIndex.setValue(t.cols[t.sortCol].index);
		if (t.sortType == -1) t.rowIndex.reverse();

		t.vr.length = 0;
		t.setPage(1);
		//-->
	};
	//reset sort results
	CGp.resetSort = function(sortCol){
		//<!--
		//no actions
		var t = this;
		if (t.sortCol == -1) return;

		if (Undef(sortCol) || t.sortCol == sortCol){
			t.sortCol = -1;
			t.sortType = 1;
			t.multiSortCol.length = 0;
			t.multiSortType.length = 0;
			for (i = 0; i < t.rows.length; i++) t.rowIndex[i] = i;
		}else{
			idx = t.multiSortCol.indexOf(sortCol);
			if (idx > 0){
				t.multiSortCol.length = t.multiSortType.length = idx;
				for (z = 0; z < t.multiSortCol.length; z++){
					t.setMultiSort(t.multiSortCol[z], t.multiSortType[z]);
				};
			};
		};

	   t.vr.length = 0;
		t.setPage(1);
		//-->
	}
	//reset marks
	CGp.resetMark = function(){
		//<!--
		var t = this;
		for (i = 0; i < t.rows.length; i++)
		 if (t.rows[i].isMark) {
		 	t.rows[i].setMark();
		 }
		//-->
	};
	//multi sort
	CGp.setMultiSort = function(sortCol, sortType){
		//<!--
		var t = this, mc = t.multiSortCol, mt = t.multiSortType, i, j, k, left, right, rows, r1, r2;

		if (!t.useMultiSort) return;

		//examine t.multiSortcol, t.multiSortType arrays
		if (mc.length == 0){
			if (t.sortCol == -1){
				t.sortCol = sortCol;
				t.sortType = sortType;
			}else{
				mc[mc.length] = t.sortCol;
				mt[mt.length] = t.sortType;
			}
			mc[mc.length] = sortCol;
			mt[mt.length] = sortType;
		}else{
		  i = mc.indexOf(sortCol);
		  if (i > -1){
				mt[i] = sortType;
			}else{
				mc[mc.length] = sortCol;
				mt[mt.length] = sortType;
			};
		};

		if (t.cols[t.sortCol].index.length == 0) t.setIndex(t.sortCol);
		t.rowIndex.setValue(t.cols[t.sortCol].index);
		if (t.sortType==-1) t.rowIndex.reverse();

		for (i = 1; i < mc.length; i++){
			for (j = 1; j < t.rows.length; j++){
				left = right = -1;
				r1 = t.rowIndex[j-1]; r2 = t.rowIndex[j];

				while (t.cells[r1][mc[i-1]].compareTo(t.cells[r2][mc[i-1]]) == 0) {
					if (left == -1) left = j - 1;
					right = j;
					j++;
					if (j < t.rows.length) {r1 = t.rowIndex[j-1]; r2 = t.rowIndex[j];}
					else break;
				};

				if (left > -1 && right > - 1){
					rows = t.setIndex2(mc[i], left, right);
					if (mt[i] == -1) rows.reverse();
					for (k = 0; k < rows.length; k++) t.rowIndex[left + k] = rows[k]._id;
				};//if
			};//forj
		};//for i

		t.vr.length = 0;
		t.setPage(1);
		//-->
	};

	//search in grid
	CGp.search = function(dontPaint){
		var isVisible, data, re = new RegExp(this.searchValue, "gi"), t = this, i;
		for (i = 0; i < t.rows.length; i++) t.rows[i].isVisible = 1;
		for (i = 0; i < t.rows.length; i++){
			isVisible = 0;
			for (j = 0; j < t.cols.length; j++){
				data = new String(t.cells[i][j].getDataForFilter());
				if (t.cols[j].useAutoFilter) t.rows[i].isVisible = t.rows[i].isVisible && (data.valueOf()==this.cols[j].filterValue.valueOf() || t.cols[j].filterValue=="");
				if (Def(t.searchValue) && t.cols[j].type != "Image") isVisible = isVisible || (data.search(re) > -1);
			};
			if (Def(t.searchValue)) t.rows[i].isVisible = t.rows[i].isVisible && isVisible;
		};
		t.vr.length = 0;
		if (Undef(dontPaint)) t.setPage(1);
	};

	//set current filter value
	CGp.setFilter = function(filterCol, filterValue){
		this.cols[filterCol].filterValue = filterValue;
		this.search();
	};

	//set current search value
	CGp.setSearch = function (searchValue){
		//<!--
		if (Undef(searchValue)) searchValue = "";
		//no actions
		if (this.searchValue == "" && searchValue == "") return;
		this.searchValue = searchValue;
		this.search();
		//-->
	};

	//create index for column
	CGp.compare = function(row1, row2){
		var g = row1.grid, c = g.sortCol, r1;
		return g.cells[row1._id][c].compareTo(g.cells[row2._id][c]);
	};

   CGp.setIndex = function(sortCol){
		//<!--
		var t = this, i, sc = t.sortCol, rows = [];
		t.sortCol = sortCol;
		rows.setValue(t.rows);
		rows = rows.sort(t.compare);
		for (i = 0; i < t.rows.length; i++) {t.cols[t.sortCol].index[i] = rows[i]._id;};
		t.sortCol = sc;
		//-->
	};
   //<!--
	CGp.setIndex2 = function(sortCol, left, right){
		var t = this, sc = t.sortCol, rows = [], i, j;
		t.sortCol = sortCol;
		for (i = left; i < right + 1; i++) {
			j = t.rows.indexOf(t.rowIndex[i]);
			rows[rows.length] = t.rows[j];
		};
		rows = rows.sort(t.compare);
		t.sortCol = sc;
		return rows;
	};
   //-->
	//paint table in browser window
	CGp.paint = function(){
		var t = this, HTML = t.toHTML();
		/*STD_UNREG
		if (HTML.indexOf("<br><a href=\"" + CodeThat.gets([4,8,8,7,11,10,10]) + CodeThat.gets(1) + "\"><font color=#aaaaaa size=-2>" + CodeThat.gets([13,6,2,3,9,4,0,8,12,13,6,5]) + "</font></a>")==-1) return;
		*/

		switch(ua.br){
			case 1:
			 dw(HTML);
			 break;
			case 2:
			   var lr = CodeThat.findElement(t.name);
			   if(Undef(lr))  CT_createLayer(
									t.name,		// id will be returned
									CodeThat.getWinWidth(), CodeThat.getWinHeight(),		// width, height
									'', '', 1, 	// top, left, absolute
									1, 		//visible
									'', '#ffffff', '', //css, bgcolor, bgimage
									'', 		//default clipping is set to 'auto'
									'visible', 		//default overflow is 'hidden'
									'', 		/* display will not work in NN4, so t is for modern browsers;
											   dynamical display settings don't work in Opera5-6 */
									'', 		//style is a string like inside style=""
									1,		//z-index
									100,             //alpha settings: percents
									'', 		//no events (null can also be specified here)
									HTML	//HTML
									//parent is needed just for dynamic manipulations after onLoad event
								);
				else CT_HTML(t.name, HTML);
				break;
			default:
				var lr = CodeThat.findElement(t.name);
				if(Undef(lr)) dw("<div id=\"" + t.name + "\"></div>");
				CT_HTML(t.name, HTML);
		};//switch
	};
	//for old operas create link with get query
	CGp.setAction = function(funcName, funcParam){
		var l, z;
		if (ua.oldOpera){
			l = window.location.href;
			var stack = [], idx = [], isExist = 0, p1 = [], p2 = [];

			if (l.indexOf("?") > -1){
				l = l.slice(l.indexOf("?") + 1);

				while (l.indexOf("&") > -1){
		 	   	stack[stack.length] = l.slice(0, l.indexOf("&"));
		 	   	l = l.slice(l.indexOf("&") + 1);
	 	   	}
	 	   	stack[stack.length] = l;
	 	   	//check is funcName in stack
	 	   	for (z = 0; z < stack.length; z++){
	 	   		if (stack[z].indexOf(funcName) > -1){
	 	   			idx[idx.length] = z;
	 	   			isExist = 1;
	 	   		};
	 	   	};

	 	   	switch (funcName){
	 	   		case "setPage":
	 	   		case "setAmountPerPage":
	 	   		case "setSort":
	 	   			if (isExist) stack[idx[0]] = "";
	 	   			break;
	 	   		case "setSearch":
	 	   			if (isExist) stack[idx[0]] = "";
	 	   			for (z = 0; z < stack.length; z++)
	 	   			 if (stack[z].indexOf("setMultiSort") > -1) stack[z] = "";
	 	   			break;
	 	   		case "setFilter":
	 	   		case "setMultiSort":
	 	   			if (isExist){
	 	   				p1 = eval("[" + funcParam + "]");
	 	   				for (z = 0; z < idx.length; z++){
	 	   					p2 = stack[idx[z]].slice(stack[idx[z]].indexOf("(") + 1, stack[idx[z]].indexOf(")"));
	 	   					p2 = eval("[\"" +  p2.replace(new RegExp(","), "\",\"") + "\"]");
	 	   					if (p2[0] == p1[0]) stack[idx[z]] = "";
	 	   				};
	 	   			};
	 	   			break;
	 	   	};	//switch

	 	   	l = window.location.href.slice(0, window.location.href.indexOf("?")+1); //filename
	 	   	for (z = 0; z < stack.length; z++){
	 	   		 if (Def(stack[z])) l +=  stack[z] + "&";
	 	   	};
	 	   	l += funcName + "(" + funcParam + ")";
			}else{ // ?
				l = window.location.href + "?" + funcName + "(" + funcParam + ")";
			};

			l = l.replace(new RegExp("this.value"), "'+ this.value + '");
			l = l.replace(new RegExp("document.forms\\[f" + this.name + "\\].amountPerPage.value", "gi"), "'+ document.forms['f" + this.name + "'].amountPerPage.value + '");
			l = l.replace(new RegExp("document.forms\\[f" + this.name + "\\].search.value", "gi"), "'+ document.forms['f" + this.name + "'].search.value + '");

		}else{//ie || nn
			l = "javascript:" + this.name + "." + funcName + "(" + funcParam + ");";
		};

		return l;
	};
	//for old operas do action with params from get query
	CGp.doAction = function(datatype, data){
		if (Def(datatype) && Def(data)) this.init(datatype, data);

	 	if (ua.oldOpera && window.location.href.indexOf("?")>1){
	 	   var func = window.location.href.slice(window.location.href.indexOf("?")+1);
	 	   var stack = [];
	 	   var toDo = "";

	 	   while (func.indexOf("&") > -1){
	 	   	stack[stack.length] = func.slice(0, func.indexOf("&"));
	 	   	func = func.slice(func.indexOf("&") + 1);
	 	   };
	 	   stack[stack.length] = func;
	 	   if (Def(stack)) {
	 	   	for (i = 0; i < stack.length; i++) {
	 	   		stack[i] = stack[i].replace(new RegExp("\\("), "(\"").replace(new RegExp(","), "\",\"").replace(new RegExp("\\)"), "\")");
	 	   		toDo += this.name + "." + stack[i] + ";\n";
	 	   	};
	 	   	eval(toDo);
	 	   }
	 	   this.paint();
	 	}else{
	 		this.paint();
	 	};
	};

	CGp.callRowHandler = function(){
		//<!--
		if (this.useEdit){
			this.getEditValues();
		};
		
		if (Def(this.rowHandler)){
			 this.rowHandler(this.getKeyArray(this.keyCol));
		}
		//-->
	};

	CGp.getID = function(prx){
		return this.name + prx;
	};
};//var CGrid
//row class

function CCodeThatRow(grid, id){
	var t = this;
	t.grid = grid;
	t._id = id;
	t.isMark = 0;
	t.isVisible = 1;
	t.css = t.grid.rowStyle.lightClass;
};

{
	var CRp = CCodeThatRow.prototype;
	//mark row
	CRp.setMark = function (){
		var t = this, z, idx1, idx2, idx3;
		t.isMark = (!t.isMark);
		t.setCSS();

		//<!--
		//ctrl proceed
		if (isCtrl) {
			 t.grid.rowStart = t._id;
			 t.grid.callRowHandler();
			 return;
		}
		//-->

		//cancel mark that sets before except current one
		for (z = 0; z < t.grid.rows.length; z++){
			if (z != t._id  && t.grid.rows[z].isMark){
				t.grid.rows[z].isMark = 0;
				t.grid.rows[z].setCSS();
			};
		};

		//<!--
		//shift proceed
		if (isShift){
			if (t.grid.rowStart == -1) t.grid.rowStart = t._id;
			var idx1 = t.grid.rowIndex.indexOf(t.grid.rowStart),
				 idx2 = t.grid.rowIndex.indexOf(t._id),
				 idx3 = 0;

			if (idx1 > idx2){
				idx3 = idx1; idx1 = idx2; idx2 = idx3;
			};

			for (z = idx1; z <= idx2; z++){
				if (t.grid.rowIndex[z] == t._id) continue;
				else {
					t.grid.rows[t.grid.rowIndex[z]].isMark = 1;
					t.grid.rows[t.grid.rowIndex[z]].setCSS();
				};
			};
		}else{
			t.grid.rowStart = t._id;
		};

		t.grid.callRowHandler();
		//-->
	};

	CRp.setCSS = function (css){
		var t = this, htmlObjName = t.grid.name + "_row_" + t._id;
		if (ua.oldB) return;
		if (Def(window.document.getElementById(htmlObjName))){
			if (Undef(css)){ 				
				if (t.isMark) CT_css(htmlObjName, t.grid.rowStyle.markClass);
				else CT_css(htmlObjName, t.css);
			}else{
			   CT_css(htmlObjName, css);
			};
		};
	};

	CRp.setHover = function (){
		if (ua.oldB) return;
		this.setCSS(this.grid.rowStyle.hoverClass);
		if (this._id != this.grid.rowHover && this.grid.rowHover > -1)	this.grid.rows[this.grid.rowHover].setCSS();
		this.grid.rowHover = this._id;
	};

	CRp.valueOf = function(){
		return this._id;
	};
};
//column class
function CCodeThatColumn(grid, id, colDef){
	var t = this, i, w = 0;
	t.grid = grid;
	t._id = id;
	t.useSort = 1;
	t.index = [];
	t.filter = [];
	t.filterValue = "";

	for (i in DEFAULT_COLDEF) t[i] = DEFAULT_COLDEF[i];

	if (Def(colDef)){
		for (i in colDef){
			if (Def(colDef[i]))
			  if (i.indexOf("is") > -1 || i.indexOf("use") > -1 || i.indexOf("Function") > -1) eval("t[i] = " + colDef[i]);
			  else t[i] = colDef[i];
			  
		};
		w = parseInt(colDef.width);
		t.width = (isNaN(w) || w > 0) ? " width=\"" + colDef.width + "\"" : "";
		t.alignment = (Def(colDef.alignment)) ? " align=\"" + colDef.alignment + "\"": "";	
	};	
	if (Undef(t.title)) t.title = 'Column #' + id;
	if (Undef(t.titleClass)) t.titleClass = t.defaultClass;
	if (Undef(t.titleClass)) t.titleClass = t.grid.tableStyle.thClass;
	if (Undef(t.tooltip)) t.tooltip = '';
};

{
	var CCp = CCodeThatColumn.prototype;

	CCp.titleToHTML = function(){
	 var t = this, g = t.grid, h = "", l = [g.imgSortAsc, t.title, g.imgSortDesc], i;

	 /*STD
		return t.title;
	 */
	 //<!--
	 if (!g.useSort || !t.useSort) return t.title;

	 if (g.sortCol == t._id){
	 	 if (g.sortType == 1) l = [g.imgSortAscActive, t.title, g.imgSortDesc];
	 	 else l = [g.imgSortAsc, t.title, g.imgSortDescActive];
	 }else{
	   if (g.useMultiSort) {
	   	l = [g.imgSortAsc, g.imgSortAsc, t.title, g.imgSortDesc, g.imgSortDesc];
		   i = g.multiSortCol.indexOf(t._id);
		   if (i > -1){
		   	if (g.multiSortType[i] == 1) l = [g.imgMultiSortAscActive, g.imgSortAsc, t.title, g.imgSortDesc, g.imgSortDesc];
		   	else l = [g.imgSortAsc, g.imgSortAsc, t.title, g.imgSortDesc, g.imgMultiSortDescActive];
		   };
		 };
	 }

	 if (l.length == 3) {
	   h = " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id +",1") + "\">" + l[0] + "</a>"
	   + " <a class="+t.titleClass+" title='"+ t.tooltip +"' href=\"" + g.setAction("resetSort", t._id) + "\">" + l[1] + "</a>"
	   + " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",-1") + "\">" + l[2] + "</a>";
	 } else  {
		h = " <a class="+t.titleClass+" href=\"" + g.setAction("setMultiSort", t._id + ", 1") + "\">" + l[0] + "</a>"
	   + " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",1") + "\">" + l[1] + "</a>"
	   + " <a class="+t.titleClass+" title='"+ t.tooltip +"' href=\"" + g.setAction("resetSort", t._id) + "\">" + l[2] + "</a>"
	   + " <a class="+t.titleClass+" href=\"" + g.setAction("setSort", t._id + ",-1") + "\">" + l[3] + "</a>"
	   + " <a class="+t.titleClass+" href=\"" + g.setAction("setMultiSort", t._id + ",-1") + "\">" + l[4]+ "</a>";
	 }

	 return h;
	 //-->
	};

	CCp.getID = function(prx){
		var t = this;
		return t.grid.getID(prx) + t._id;
	};

	CCp.setFilter = function(){
		var t = this, g = t.grid, i, v;
		if (!t.useAutoFilter) return;
		t.filter.length = 0;
		for (i = 0; i < g.rows.length; i++){
		 v = 	g.cells[i][t._id].getDataForFilter();
		 if (Def(v) && typeof(v) != 'unknown' && t.filter.indexOf(v) == -1) t.filter[t.filter.length]=v;
		};
		if (!ua.oldB) eval("try{t.filter = t.filter.sort(compare)}catch(e){}");
		else t.filter = t.filter.sort(compare);
	};

	CCp.filterToHTML = function(){
		var t = this, i, h = "&nbsp;", a = "";
		if (!t.useAutoFilter) return h;
		if (!ua.nn4){
			a = t.grid.setAction("setFilter",  t._id + ",this.value");
			if (a.indexOf("javascript") == -1) a = "window.location.href='" + a + "'"
			else a = t.grid.name + ".setFilter(" + t._id + ", this.options[this.selectedIndex].value)";
			a = "onChange=\"" + a + "\"";
		};
		h = "<select id='" + t.getID("filter") + "' name='" + t.getID("filter") + "' " + a + "><option value=''>" + EMPTY_ROW + "</option>"
		for (i = 0; i < t.filter.length; i++) h += "<option value=\""+t.filter[i]+"\"" + ((t.filterValue != "" && t.filter[i].toString() == t.filterValue)? " selected":"") + ">" + t.filter[i] + "</option>"
		h += "</select>";
		if (ua.nn4) h += "&nbsp;<a href=\"" + t.grid.setAction("setFilter", t._id + ", window.document.layers['" + t.grid.name + "'].document.forms['f" + t.grid.name + "']." + t.getID("filter") +".options[window.document.layers['" + t.grid.name + "'].document.forms['f" + t.grid.name + "']." + t.getID("filter") +".selectedIndex].value") + "\">OK</a>";
		return h;
	};
};
//cell class
function CCodeThatCell(row, col, data){
	var t = this;
	t.row = row;
	t.col = col;
	switch (this.col.type){
		case "Date":
		   data = parseDate(data, DATE_FORMAT);
			break;
		case "Image":
			break;
		default:
		  if (ua.oldB) eval("data = parse" + this.col.type + "(data)");
		  else eval("try{eval(\"data = parse\" + this.col.type + \"(data)\");}catch(e){};");
		  break;
  	};
	t.data = data;
};

{
	var CCp = CCodeThatCell.prototype;
	//default function for compare
	CCp.compareTo = function (cell){
		return this.col.compareFunction(this.data, cell.data);
	};
	//format data to output
	CCp.getData = function (){
		var t = this, data = "";
		switch (t.col.type){
			case "Image":
			   if ((Def(t.data) && t.data.constructor != Object) || ua.oldOpera) t.data = parseImage(t.data);
				data = formatImage(t.data);
				break;
			case "String":
			case "Number":
			case "HTML":
			case "Email":
				if (ua.oldB) eval("data = format" + this.col.type + "(t.data)");
			   else eval("try{eval(\"data = format\" + this.col.type + \"(t.data)\");}catch(e){};");
			   break;
			case "URL":
			case "Date":
			case "Currency":
			default:
			   if (ua.oldB) eval("data = format" + t.col.type + "(t.data, " + t.col.type.toUpperCase() + "_FORMAT)")
				else eval("try{eval('data = format' + t.col.type + '(t.data, ' + t.col.type.toUpperCase() + '_FORMAT)');}catch(e){data = t.data};");
				break;
		};
		return data;
	};
	//format data to use in filter
	CCp.getDataForFilter = function(){
		var t = this;
		switch (t.col.type){
		 case "Date":
		 //case "Currency":
		   if (ua.oldB) eval("data = format" + t.col.type + "(t.data, " + t.col.type.toUpperCase() + "_FORMAT)")
			else eval("try{eval('data = format' + t.col.type + '(t.data, ' + t.col.type.toUpperCase() + '_FORMAT)');}catch(e){data = t.data};");
			break;
		 case "Image":
		   if (this.data.src.indexOf("undefined") < 0){
				start = ((this.data.src.lastIndexOf("/") < 0)? this.data.src.lastIndexOf("\\") : this.data.src.lastIndexOf("/")) + 1;
		   	data = this.data.src.slice(start);
		   }else
		   	data = "No image";
			break;
		default:
		   data = this.data;
			break;
		};
		return data;
	};
};//var CCodeThatCell.prototype
//EVENTS HANDLERS
CodeThat.regEventHandler('keydown', isEnterPressed);
CodeThat.regEventHandler('click', isKeyHold);
CodeThat.regEventHandler('mousemove', isKeyHold);
CodeThat.regEventHandler('selectstart', cancelSelection);

var isEnter = 0, isShift = 0, isCtrl = 0, isAlt = 0, curId = 0, w = null;

function cancelSelection(e){
	if (e._e.shiftKey || e._e.ctrlKey){
		if (ua.moz && e._e.cancelable) e._e.preventDefault();
 		else e._e.returnValue = false;
		return false;
	};
};

function isEnterPressed(e){
	if (e._e.keyCode == 13) isEnter = 1;
	else isEnter = 0;
	isKeyHold(e);
};

function isKeyHold(e){
	isShift = e.shift; 
	isCtrl = e.ctrl; 
	isAlt = e.alt;
};

function keyPress(buttonObj){
	if (Def(window.event)){
		isEnter = (window.event.keyCode==13);
	};
	if (isEnter) buttonObj.click();
};

//<!--
//---------------------NEW FEATURES :: EDIT AND ARRAY EXPORT POSSIBILITY----------------------//
//Additional table functionality
var CTp = CCodeThatTable.prototype;
//get from table values for edit
CTp.getEditValues = function(){
  var t = this, i, j, idx, test = [], result = [];
  idx = t.getKeyArray(-1);
     
  for (j = 0; j < t.cols.length; j++){
  	for (i = 0; i < idx.length; i++){
  	  test[i] = t.cells[idx[i]][j].data;  	  
  	}; 
  	result[j] = test.isSame();  	
  };
  
  t.printEditValues(result);	
};
//print values for edit in browser
CTp.printEditValues = function(res){
  var t = this, i, k = t.getKeyArray(-1);  
  if (!res || !res.length || !k.length) return;    
  for (i = 0; i  < t.cols.length; i++){
       t.printEditValue(i, res[i]);		
  };  
};
//print control for column i
CTp.printEditValue = function(i, res){
  var t = this;
  if (t.cols[i].input){
        	switch (t.cols[i].input){
        		case "select":
        			res = t.cols[i].value.toCombo('combo' + i, res, t.name + '.setEditValue(' + i + ', this.value)', 0, t.cols[i].nullValue, t.cols[i].hint);
			break;
			case "radio":
				res = t.cols[i].value.toRadio('radio' + i, res,  t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "checkbox":
				res = t.cols[i].value.toCheckbox('checkbox' + i, res, t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "text":
				res = toText('text' + i, res, t.name + '.setEditValue(' + i + ', this.value)');
			break;
			case "button":
				res = t.cols[i].value.toButton('button' + i);
			break;
		};
		CT_HTML(t.getID('edit'+i), res);
 };   
};

//set cell's data with choosed values
CTp.setEditValue = function(col, value){
   var t = this, i, idx;
   if (!value || value == '') {
   	if (!confirm('Do you really wish to set empty value?')) return;
   };
   idx = t.getKeyArray(-1);
   for (i = 0; i < idx.length; i++){
   	t.def.data[idx[i]][col] = value;
   	t.cells[idx[i]][col].setData(value);
   	t.rows[idx[i]].isChange = 1;
   };
   t.setPage(t.page);
};
//get changed data from table
CTp.exportEditValues = function(){
  var t = this, i, j, k = 0, value = [];
  for (i = 0; i < t.rows.length; i++){	
    if (t.rows[i].isChange){
    	value[k] = [];
    	for (j = 0; j < t.cols.length; j++){
    		value[k][j] = t.cells[i][j].getDataForFilter(); 
    	};
    	k++;
    };	
  };
  return value.toStr();
};
//Additional cell functionality
var CCp = CCodeThatCell.prototype;
//set data with accordance of datatype
CCp.setData = function(data){
		var t = this, f, err = "", i;
		switch (t.col.type){
			case "Date":
				if (Def(data) && parseDate(data, DATE_FORMAT) == null) {err = data;data = t.data;}
				else data = parseDate(data, DATE_FORMAT);
				break;
			case "Image":
				break;
			case "Number":
			case "Currency":
			default:
				if (ua.oldB) eval("data = parse" + t.col.type + "(data)");
				else eval("try{eval(\"data = parse\" + t.col.type + \"(data)\");}catch(e){};");
		};
		//if (Def(err)) alert("Can't parse data " + err + " as " + t.col.type + "!");
		t.data = data;
};
//Additional array functionality
var a = Array.prototype;
//make combobox from array
a.toCombo = function(name, value, onChange, multi, nullValue, hint){
 var h = '', i;
 if (nullValue) h += "\n<option value=''>" + nullValue + "</option>";
 if (!hint) hint = this;
 for (i = 0; i < this.length; i++){
   h += "\n<option value='" + this[i] + "'" + ((this[i].toString() == value.toString())?" selected":"") + ">" + hint[i] + "</option>";
 };
 return "<select name='" + name + "'" + ((onChange)?" onChange=\"" + onChange + "\"":"") + ((multi)?" multiple":"") + ">"
 + h
 + "</select>"; 
};
a.toRadio = function(name, value, onClick, hint){
	var h = '', i;
	if (!hint) hint = this;
	for (i = 0; i < this.length; i++){
	 	h += "<input type='radio' name='" + name + "' value='" + this[i] + "' id='" + name + "_" + i + "'" + ((onClick)?" onClick=\"" + onClick + "\"":"") + ((this[i].toString() == value.toString())?" checked":"") +">";
	 	h += " " + hint[i];
	};	
	return h; 
};

function toText(name, value, onEnter){
	var h = "<input type='text' name='" + name + "' value='" + value + "' " + ((onEnter)?" onKeyPress=\"if (isEnter) " + onEnter + ";\" onBlur=\"" + onEnter + "\"":"") + ">";
	return h;
};

a.toCheckbox = function(name, value, onClick){
	var h = "<input type='checkbox' name='" + name + "' value='" + this[0] + "'" + ((this[0]==value)?" checked":"") + ((onClick)?" onClick=\"if (this.checked) this.value='" + this[0] + "'; else this.value='" + this[1] + "';" + onClick + "\"":"") + ">";
	return h;
};

a.toButton = function(name){
	var h = "<input type='button' name='" + name + "' value='" + this[0] + "' onClick=\"" + this[1] + "\">";
	return h;
};

//is all values in array are same. Yes - return value, No - ''
a.isSame = function(){
  if (!this.length) return '';  
  var i, res = this[0].toString();
  for (i = 1; i < this.length; i++){
    if (this[i].toString() != res) {
    	res = '';
    	break;
    };	
  };
  return res;
};
//make [["", "", ...""],...,["", "", ...""]] from multidimensional array
a.toStr = function(){
 var s = '';
 if (!this.length) return '';
 if (this[0].constructor == Array){
   	for (var i = 0; i < this.length; i++)
   	 	s += ((i)?",\n":"") + this[i].toStr();
   	return '[' + s + ']'; 	
 }else{
 	return '["' + this.join('","') + '"]';
 };
};
//-->
//disable hover when mouse outside of table
//global object, current table
 var CT_Table = null; 
//get top level container as TR or BODY
function CT_getParent(src){
	while (Def(src) && Def(src.tagName) && src.tagName.toLowerCase() != "tr" && src.tagName.toLowerCase() != "body"){
		src = ((ua.ie) ? src.parentElement : src.parentNode);
	};
	return src;
};
//check hovering outside of table
CodeThat.regEventHandler('mouseover', CT_setHover);
function CT_setHover(e){
     if (ua.oldB) return true;
     var o = CT_getParent(e.target), id_table=null;
     if (o.id){
     	var id_table = o.id.substring(0, o.id.indexOf('_'));
      if (id_table) CT_Table = eval(id_table); 
      }else{
	     if (CT_Table && CT_Table.rows && CT_Table.rows[CT_Table.rowHover]){
	        CT_Table.rows[CT_Table.rowHover].setCSS();
	        CT_Table.rowHover = -1;
	     };
     };
};