function XTable (oHParent,sName) {
	this.oHParent_ = gid(oHParent);
	this.aCols_ = [];
	this.hashCols_ = {};
	this.oHTable_ = null;
	this.iNextRSer_ = 0;
	this.iNextCSer_ = 0;
	this.sName_ = sName;
	this.bInit_ = false;
}

XTable.prototype.setHStyles = function (s) {
	this.sHStyles_ = s;
}
XTable.prototype.setCStyles = function (s) {
	this.sCStyles_ = s;
}
XTable.prototype.setHNames = function (s) {
	this.sHNames_ = s;
}
XTable.prototype.setStyle = function (s) {
	this.sStyle_ = s;
}
XTable.prototype.defCol = function (name, jsclass, s) {
    var oProps = XTable.decodeMap (s);
    oProps["name"] = name;
    oProps["jsclass"] = jsclass;
    var oCol = XCol.create (oProps);
    oCol.serial_ = this.iNextCSer_++;
    this.aCols_.push(oCol);
    this.hashCols_[oCol.name_] = oCol;
}
XTable.prototype.getCol = function (sColName) {
	return this.hashCols_[sColName];
}
XTable.prototype.getColIndex = function (sColName) {
	var oCol = this.hashCols_[sColName];
	if (!oCol) throw new Error ("unknown column " + sColName);
	return oCol.serial_;
}
XTable.prototype.getCell = function (nRowIdx, sColName) {
	var aRows = this.rows();
	var oRow = aRows[nRowIdx];
	return oRow.childNodes[this.getColIndex(sColName)];
}
XTable.prototype.getCellValue = function (nRowIdx, sColName) {
	var oCol = this.getCol (sColName);
	var oCell = this.getCell (nRowIdx, sColName);
	return oCol.getCellValue (oCell);
}
XTable.prototype.setCellValue = function (nRowIdx, sColName, oValue) {
	var oCol = this.getCol (sColName);
	var oCell = this.getCell (nRowIdx, sColName);
	return oCol.setCellValue (oCell, oValue);
}
XTable.prototype.getControl = function (nRowIdx, sColName) {
	return this.getCell(nRowIdx, sColName).control_;
}
XTable.prototype.init = function (sContent) {
	this.oHTable_ = document.createElement("table");
	this.oHParent_.appendChild(this.oHTable_);
	this.oHTable_.cellSpacing = 0;
	this.oHTable_.cellPadding = 0;
	this.oHTable_.border = 0;
	if (this.sStyle_) this.oHTable_.style.cssText = this.sStyle_;
	var oHead = document.createElement("thead");
	this.oHTable_.appendChild(oHead);
	var oRow = document.createElement("tr");
	oHead.appendChild(oRow);
	var aHNames = XTable.decodeArray (this.sHNames_);
	var aHStyles = XTable.decodeStyles (this.sHStyles_);
	for (var i=0;i<this.aCols_.length;i++) {
	    var col = this.aCols_[i];
    	var oTH = document.createElement("th");
    	oRow.appendChild(oTH);
    	if (aHStyles.length > 0) {
    	    oTH.style.cssText = aHStyles[i%aHStyles.length];
    	}
    	if (!col.visible_) oTH.style.display = "none";
    	var oTxt = document.createTextNode (aHNames[i]);
    	oTH.appendChild(oTxt);
	}
	var oBody = document.createElement ("tbody");
	this.oHTable_.appendChild(oBody);
	if (sContent) {
		this.setContent (sContent);
	}
	this.bInit_ = true;
}
XTable.prototype.isInitialized = function () {
    return this.bInit_;
}
XTable.prototype.setContent = function (sContent) {
	var oBody = findDomNode (this.oHTable_, "tbody");
	oBody.length = 0;
	aLines = XTable.decodeArray (sContent);
	for (var i=0; i<aLines.length; i++) {
		this.addRow (aLines[i]);
	}
}
XTable.prototype.addRow  = function (sContent) {
	var conti = sContent;
	if (!conti) conti = "";
	var aCellValues = XTable.decodeArray (conti);
	XTable.prototype.addRowV.apply (this, aCellValues);
}
XTable.prototype.addRowV  = function (/**vargs**/) {
	var aCellValues = arguments;
	var oBody = findDomNode (this.oHTable_, "tbody");
	var oRow = document.createElement ("tr");
	oBody.appendChild (oRow);
	oRow.rowSerial_ = this.iNextRSer_++;
	var aCStyles = XTable.decodeStyles (this.sCStyles_);
	for (var i=0;i<this.aCols_.length;i++) {
	    var col = this.aCols_[i];
    	var oCell = document.createElement ("td");
    	if (aCStyles.length > 0) oCell.style.cssText = aCStyles[i%aCStyles.length];
    	if (!col.visible_) oCell.style.display = "none";
    	oRow.appendChild (oCell);
	}
	for (var i=0;i<this.aCols_.length;i++) {
	    var col = this.aCols_[i];
    	var oCell = oRow.childNodes[i];
    	col.init (oCell, oRow, this);
	}
	for (var i=0;i<this.aCols_.length;i++) {
	    var col = this.aCols_[i];
    	var oCell = oRow.childNodes[i];
    	col.init2 (oCell, oRow, this);
    	if (i < aCellValues.length) col.setCellValue (oCell, aCellValues[i]);
	}	
}
XTable.prototype.delRow = function (oTR) {
	var oBody = findDomNode (this.oHTable_, "tbody");
	oBody.removeChild (oTR);
}
XTable.prototype.rows = function () {
	var oBody = findDomNode (this.oHTable_, "tbody");
	return oBody.childNodes;
}


XTable.trim = function (s) {
	return s.replace (/^\s*(\S*)\s*$/, "$1");
}

XTable.decodeStyles = function (sStyles) {
	if (typeof sStyles == "undefined") return [];
	var a1 = sStyles.split("||");
	var sComm = "";
	if (a1.length > 1) {
		sComm = XTable.trim(a1[0]);
		sStyles = a1[1];
	}
	var a2 = sStyles.split("|");
	for (i=0; i<a2.length; i++) {
		if (sComm.length > 0) {
			a2[i] = sComm + ";" + XTable.trim(a2[i]);
		} else {
		    a2[i] = XTable.trim(a2[i]);
		}
	}
	return a2;
}

XTable.decodeArray  = function (s) {
	var a = s.split ('|');
	for (i=0;i<a.length;i++) {
	    a[i] = a[i].replace(/&a/g, '&');
	    a[i] = a[i].replace(/&b/g, '|');
	    a[i] = a[i].replace(/&q/g, '"');
	}
	return a;
}

XTable.decodeMap = function (s) {
    var oRet = new Object();
	var a = s.split ('|');
	for (i=0;i<a.length;i++) {
	    var eq = a[i].indexOf('=');
	    var k = a[i].substr(0,eq);
	    var v = a[i].substr(eq+1);
	    v = v.replace(/&a/g, '&');
	    v = v.replace(/&b/g, '|');
	    v = v.replace(/&q/g, '"');
	    oRet[k] = v;
	}
	return oRet;
}

XTable.props = function (o) {
 	var s = "";
    for (var p in o) {
        s += p + ":" + o[p] + "\n";
    }
    return s;
}


function XCol (oMap) {
	this.oInit_ = oMap;
    this.visible_ = true;
    this.serial_ = 0;
	if (oMap) {
	    this.visible_ = !(oMap["visible"]=="false"); 
	    this.name_ = oMap["name"];
	    var sOnchange = oMap["onchange"];
	    if (sOnchange) this.fOnchange_ = new Function ("obj", sOnchange);
	}
}
XCol.create = function (oMap) {
	var ctr = "new " + oMap["jsclass"] + "(oMap)";
    var oCol = eval(ctr);
    return oCol;
}
XCol.prototype.createFieldName = function (oTR,oTable) {
	return oTable.sName_ + "_" + oTR.rowSerial_ + ":" + this.name_;
} 
XCol.prototype.getControl = function (oCell) {
	return oCell.control_;
}
XCol.prototype.setCellValue = function (oCell, oValue) {
} 
XCol.prototype.getCellValue = function (oCell) {
}
XCol.prototype.init2 = function (oCell,oTR,oTable) {
}



function COText (oMap) {
	XCol.call (this,oMap);
}
COText.prototype = new XCol();
COText.prototype.constructor = COText;

COText.prototype.init = function (oCell,oTR,oTable) {
	var oTxt = document.createTextNode("");
	oCell.appendChild (oTxt);
}
COText.prototype.setCellValue = function (oCell, oValue) {
	oCell.firstChild.data = oValue;
} 
COText.prototype.getCellValue = function (oCell) {
	return oCell.firstChild.data;
}
COText.prototype.getControl = function (oCell) {
	return oCell.firstChild;
}



function COTextHI (oMap) {
	XCol.call (this,oMap);
}
COTextHI.prototype = new XCol();
COTextHI.prototype.constructor = COTextHI;

COTextHI.prototype.init = function (oCell,oTR,oTable) {
	var oTxt = document.createTextNode("");
	oCell.appendChild (oTxt);
	var oInput = document.createElement("input");
	oInput.type = "hidden";
	oInput.name = this.createFieldName (oTR,oTable);
	oCell.appendChild (oInput);
	oCell.control_ = oInput;
}
COTextHI.prototype.setCellValue = function (oCell, oValue) {
	oCell.firstChild.data = oValue;
	oCell.control_.value = oValue;
} 
COTextHI.prototype.getCellValue = function (oCell) {
	return oCell.control_.value;
}
COTextHI.prototype.getControl = function (oCell) {
	return oCell.control_;
}




function CSlider (oMap) {
	XCol.call (this,oMap);
}
CSlider.prototype = new XCol();
CSlider.prototype.constructor = CSlider;

CSlider.prototype.init = function (oCell,oTR,oTable) {
	var oInput = document.createElement("input");
	oInput.type = "hidden";
	oInput.name = this.createFieldName (oTR,oTable);
	oCell.appendChild (oInput);
	var oDiv = document.createElement ("div");
	oCell.appendChild(oDiv);
	var style = this.oInit_["style"];
	if (style) oDiv.style.cssText = style;
	else throw Error ("need css-style with width/height in px");
	var nW = parseInt(oDiv.style.width);
	var nH = parseInt(oDiv.style.height);
	var oSlider = new Slider (oDiv, oInput, nW, nH);
	oCell.control_ = oSlider;
	var step = this.oInit_["step"];
	if (step) oSlider.setStep(parseInt(step));
	var min = this.oInit_["min"];
	if (min) oSlider.setMinimum(parseInt(min));
	var max = this.oInit_["max"];
	if (max) oSlider.setMaximum(parseInt(max));
	var value = this.oInit_["value"];
	oSlider.setValue(value ? value : 0);
}
CSlider.prototype.init2 = function (oCell,oTR,oTable) {
	if (this.fOnchange_) oCell.control_.onchange = this.fOnchange_;
}
CSlider.prototype.setCellValue = function (oCell, oValue) {
	oCell.control_.setValue(parseInt(oValue));
} 
CSlider.prototype.getCellValue = function (oCell) {
	return oCell.control_.getValue();
}



function CDelButton (oMap) {
	XCol.call (this,oMap);
}
CDelButton.prototype = new XCol();
CDelButton.prototype.constructor = CDelButton;

CDelButton.prototype.init = function (oCell,oTR,oTable) {
	var oImg = document.createElement("img");
	oCell.appendChild (oImg);
	oImg.src = "/jv/ext/images/delete.gif";
	oImg.onclick = function () {
	    oTable.delRow (oTR);
	}
	oImg.style.cursor = "pointer";
	oCell.control_ = oImg;
}



function CInput (oMap) {
	XCol.call (this,oMap);
}
CInput.prototype = new XCol();
CInput.prototype.constructor = CInput;

CInput.prototype.init = function (oCell,oTR,oTable) {
	var oInput = document.createElement("input");
	oInput.name = this.createFieldName (oTR,oTable);
	oCell.appendChild (oInput);
	oCell.control_ = oInput;
	var type = this.oInit_["type"];
	if (type) oInput.type = type;
	var style = this.oInit_["style"];
	if (style) oInput.style.cssText = style;
}
CInput.prototype.init2 = function (oCell,oTR,oTable) {
	if (this.fOnchange_) oCell.control_.onchange = this.fOnchange_;
}
CInput.prototype.setCellValue = function (oCell, oValue) {
	oCell.control_.value = oValue;
} 
CInput.prototype.getCellValue = function (oCell) {
	return oCell.control_.value;
}

