/******************************************************************************
* odfTableEditor.js
*******************************************************************************
Table Editor
*******************************************************************************
*                                                                             *
* Copyright 2006									                          *
*                                                                             *
******************************************************************************/


function OdfTableEditor()
{
	this._tableElement = null;
}


OdfTableEditor.prototype.bind = function(element)
{
	this._tableElement = null;
	this._rowElement = null;
	this._cellElement = null;
	this._colElement = null;
	this._clickElement = element;
	this._cells = null;
	this._rows = null;
	this._cols = null;
	this._captionElement = null;
	this._colgroupElement = null;
	this._tbodyElement = null;

	while(element && element.nodeType == 1) {
		switch(element.tagName) {
		case "TD":
		case "TH":
			this._cellElement = element;
			break;
		case "TR":
			this._rowElement = element;
			break;
		case "TABLE":
			this._tableElement = element;
			break;
		case "COL":
			this._colElement = element;
			break;
		}
		if(this._tableElement != null) break;
		element = element.parentElement;
	}
	if(this._tableElement == null) {
		this._tableElement = null;
		this._rowElement = null;
		this._cellElement = null;
		this._colElement = null;
		this._clickElement = null;
	} 
}

OdfTableEditor.prototype._buildLayout = function()
{
	if(this._cells != null) return;
	if(this._tableElement == null) return;
	this._cells = new Object();
	this._rows = new Array();
	this._cols = new Array();
	this._captionElement = null;
	this._colgroupElement = null;
	this._tbodyElement = null;
	this._nbCols = null;

	var msg = "";

	
	// 1) first Index existing Element;
	var table = this._tableElement;
	var children = table.childNodes;
	
	for(var i=0;i<children.length;i++) {
		var child = children.item(i);
		if(child.nodeType != 1) continue;
		switch(child.tagName) {
		case "CAPTION":
			this._captionElement = child;
			break;
		case "TBODY":
			this._tbodyElement = child;
			for(var j=0;j<child.childNodes.length;j++) {
				var tr = child.childNodes.item(j);
				if(tr.nodeType != 1) continue;
				if(tr.tagName != "TR") continue;
				this._rows[this._rows.length] = tr;
			}
			break;
		case "COLGROUP":
			if(this._colgroupElement == null) {
				this._colgroupElement = child;
				for(var j=0;j<child.childNodes.length;j++) {
					var col = child.childNodes.item(j);
					if(col.nodeType != 1) continue;
					if(col.tagName != "COL") continue;
					this._cols[this._cols.length] = col;
				}
			} else {
				// moving col element in existing colgroup element
				for(var j=0;j<child.childNodes.length;) {
					var col = child.childNodes.item(j);
					if(col.nodeType != 1) continue;
					if(col.tagName != "COL") continue;
					child.removeChild(col);
					this._colgroupElement.appendChild(col);
					this._cols[this._cols.length] = col;
				}
			}
			break;
		}
	}

	var horizon = new Array();
	var y = 0;
	for(var i=0;i<this._rows.length;i++) {
		var tr = this._rows[i];
		tr.y = y;
		tr.className = ((i%2) == 0) ? "even": "odd";
		var children = tr.childNodes;
		var x = 0;
		for(var j=0;j<children.length;j++) {
			var td = children.item(j);
			if(td.nodeType != 1) continue;
			if(td.tagName != "TD" && td.tagName != "TH") continue;
			/*
			if(td.tagName == "TH") {
				td.className = "headerCell";
			} else {
				td.className = "cell";
			}
			*/
			while(true) {
				var depth = horizon[x];
				if(depth == null) {
					depth = horizon[x] = 0;
				} 
				if(depth == 0) break;
				horizon[x] = depth-1;
				x++;			
			}
			var colSpan = td.colSpan;
			var rowSpan = td.rowSpan;
			td.x = x;
			td.y = y;
			for(var l=0;l<colSpan;l++) {
				for(var k=0;k<rowSpan;k++) {
					var key = (x + l) + " " + (y + k);
					this._cells[key] = td;
				}
				horizon[x + l] = rowSpan - 1;
			}
			x += colSpan;
		}
		while(x < horizon.length) {
			var depth = horizon[x];
			if(depth > 0) horizon[x] = depth - 1;
			x++;
		}
		y += 1;
		//msg += "h : " + horizon + "\n";
	}

	this._nbCols = horizon.length;

	// 2) repair missing rows
	if(this._tbodyElement == null) {
		msg += "missing tbody\n";
		this._tbodyElement = this.createElement("TBODY");
		this._tableElement.appendChild(this._tbodyElement);
	}
	var missingRows = 0;
	for(var i=0;i<horizon.length;i++) {
		if(missingRows < horizon) missingRows = horizon;
	}
	for(var i=0;i<missingRows;i++) {
		msg += "missing tbody\n";
		var tr = this.createElement("TR");
		tr.y = this._rows.length;
		this._rows[this._rows.length] = tr;
		this._tbodyElement.appendChild(tr);
	}

	
	// 3) repair missing cols
	if(this._colgroupElement == null) {
		this._colgroupElement = this.createElement("COLGROUP");
		this._tableElement.insertBefore(this._colgroupElement, this._tbodyElement);
	}
	if(this._cols.length < this._nbCols) {
		while(this._cols.length < this._nbCols) {
			var col = this.createElement("COL");
			col.width = 100;
			this._cols[this._cols.length] = col;
			this._colgroupElement.appendChild(col);
		}
	}

	// 4) repair missing cels
	for(var i=0;i<this._rows.length;i++) {
		var tr = this._rows[i];
		for(var j = 0;j<this._nbCols;j++) {
			var key = j + " " + i;
			var td = this.getCell(j, i);
			if(td == null) {
				var td = this.addCell(tr);
				msg += "missing cell " + j + " " + i + "\n";
				td.x = j;
				td.y = i;
				this._cells[key] = td;
			}
		}
	}
	//if(msg != "") alert(msg);
}
OdfTableEditor.prototype._dropLayout = function()
{
	this._cells = null;
	this._rows = null;
	this._cols = null;
	this._captionElement = null;
	this._colgroupElement = null;
	this._tbodyElement = null;
	this._nbCols = null;

}
function OdfTableLayout(tableElement, rowElement, cellElement, colElement, clickElement, cells, rows, cols, captionElement, colgroupElement, tbodyElement, nbCols)
{
	this.tableElement = tableElement;
	this.rowElement = rowElement;
	this.cellElement = cellElement;
	this.colElement = colElement;
	this.clickElement = clickElement;
	this.cells = cells;
	this.rows = rows;
	this.cols = cols;
	this.captionElement = captionElement;
	this.colgroupElement = colgroupElement;
	this.tbodyElement = tbodyElement;
	this.nbCols = nbCols;
}

OdfTableEditor.prototype.saveLayout = function()
{
	return new OdfTableLayout(this._tableElement, this._rowElement, this._cellElement, this._colElement, this._clickElement,
		this._cells, this._rows, this._cols, this._captionElement, this._colgroupElement, this._tbodyElement, this._nbCols);
}

OdfTableEditor.prototype.restoreLayout = function(layout)
{
	this._tableElement = layout.tableElement;
	this._rowElement = layout.rowElement;
	this._cellElement = layout.cellElement;
	this._colElement = layout.colElement;
	this._clickElement = layout.clickElement;
	this._cells = layout.cells;
	this._rows = layout.rows;
	this._cols = layout.cols;
	this._captionElement = layout.captionElement;
	this._colgroupElement = layout.colgroupElement;
	this._tbodyElement = layout.tbodyElement;
	this._nbCols = layout.nbCols;
}

OdfTableEditor.prototype.getColumnCell = function()
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var x = this._cellElement.x;
	var column = this._cols[x];
	this._dropLayout();
	return column;
}
OdfTableEditor.prototype.createElement = function(tagName)
{
	return this._tableElement.ownerDocument.createElement(tagName);
}

OdfTableEditor.prototype.createTextNode = function(text)
{
	return this._tableElement.ownerDocument.createTextNode(text);
}

OdfTableEditor.prototype.addText = function(text, p, pivot)
{
	var t = this.createTextNode(text);
	if(pivot == null) {
		p.appendChild(t);
	} else {
		p.insertBefore(t, pivot);
	}
}

OdfTableEditor.prototype.addCell = function(tr, pivot)
{
	var td = this.createElement("TD");
	if(pivot == null) {
		tr.appendChild(td);
	} else {
		tr.insertBefore(td, pivot);
	}
	var p = this.createElement("P");
	td.appendChild(p);
	p.appendChild(this.createTextNode("\240"));
	return td;
}

OdfTableEditor.prototype.addHeadCell = function(tr, pivot)
{
	var td = this.createElement("TH");
	if(pivot == null) {
		tr.appendChild(td);
	} else {
		tr.insertBefore(td, pivot);
	}
	var p = this.createElement("P");
	td.appendChild(p);
	p.appendChild(this.createTextNode("\240"));
	return td;
}

OdfTableEditor.prototype.addRow = function(isAfter)
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var y = this._cellElement.y;
	if(isAfter) y += this._cellElement.rowSpan;
	if(y == 0) {
		var tr = this.createElement("TR");
		this._tbodyElement.insertBefore(tr, this._tbodyElement.firstChild);
		for(var i=0;i<this._nbCols;i++) {
			var td = this.addCell(tr);
		}
	} else {
		var previousY = y-1;
		var nextTr = this._rows[y];
		var tr = this.createElement("TR");
		if(nextTr) {
			this._tbodyElement.insertBefore(tr, nextTr);
		} else {
			this._tbodyElement.appendChild(tr);
		}
		for(var x=0;x<this._nbCols;) {
			var previousTd = this.getCell(x, previousY);
			var colSpan = previousTd.colSpan;
			var rowSpan = previousTd.rowSpan;
			if(previousTd.y + rowSpan > y) {
				previousTd.rowSpan = previousTd.rowSpan + 1;
			} else {
				for(var i=0;i<colSpan;i++) {
					var td = this.addCell(tr);
				}
			}
			x += colSpan;
		}
	}
	this._dropLayout();
	this._buildLayout();
	this._dropLayout();
}

OdfTableEditor.prototype.deleteRow = function()
{
	if(this._rowElement == null) return;
	this._buildLayout();
	var y = this._rowElement.y;
	var nextTr = this._rows[y+1];
	for(var x=0;x<this._nbCols;) {
		var td = this.getCell(x, y);
		var colSpan = td.colSpan;
		var rowSpan = td.rowSpan;
		if(rowSpan == 1) {
			this._rowElement.removeChild(td);
		} else {
			td.rowSpan = rowSpan - 1;
			if(td.parentElement == this._rowElement) {
				// move cell to next row
				this._rowElement.removeChild(td);
				var pivotTd = null;
				var children = nextTr.childNodes;
				for(var i=0;i<children.length;i++) {
					var child = children.item(i);
					if(child.tagName != "TD" && child.tagName != "TH") continue;
					if(child.x > x) {
						pivotTd = child;
						break;
					}
				}
				if(pivotTd != null) {
					nextTr.insertBefore(td, pivotTd);
				} else {
					nextTr.appendChild(td);
				}
			}
		}
		x += colSpan;
	}
	this._tbodyElement.removeChild(this._rowElement);
	this._rowElement = null;
	this._dropLayout();
	this._buildLayout();
	this._dropLayout();
}

OdfTableEditor.prototype.isHeadingRow = function(y)
{
	var n = 0;
	for(var x=0;x<this._nbCols;x++) {
		var td = this.getCell(x, y);
		if(td.tagName == "TH") n++;
	}
	return (2 * n > this._nbCols);
}

OdfTableEditor.prototype.addColumn = function(isAfter)
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var x = this._cellElement.x;
	if(isAfter) x += this._cellElement.colSpan;
	var nextCol = this._cols[x];
	var col = this.createElement("COL");
	col.width = 100;
	if(nextCol == null) {
		this._colgroupElement.appendChild(col);
	} else {
		this._colgroupElement.insertBefore(col, nextCol);
	}
	for(var y=0;y<this._rows.length;y++) {
		var tr = this._rows[y];
		if(x > 0) {
			var td = this.getCell(x - 1, y);
			if(td != null) {
				var colSpan = td.colSpan;
				var rowSpan = td.rowSpan;
				if(td.x + colSpan > x) {
					td.colSpan = colSpan + 1;
					y += rowSpan - 1;
					continue;
				}
			}
		}
		var nextTd = null;
		for(var i=0;i<tr.childNodes.length;i++) {
			var child = tr.childNodes[i];
			if(child.tagName != "TD" && child.tagName != "TH") continue;
			if(child.x >= x) {
				nextTd = child;
				break;
			}
		}
		if(this.isHeadingRow(y)) {
			this.addHeadCell(tr, nextTd);
		} else {
			this.addCell(tr, nextTd);
		}
	}
	this._dropLayout();
}

OdfTableEditor.prototype.deleteColumn = function()
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var x = this._cellElement.x;
	var col = this._cols[x];
	this._colgroupElement.removeChild(col);
	for(var y=0;y<this._rows.length;y++) {
		var tr = this._rows[y];
		var td = this.getCell(x, y);
		var colSpan = td.colSpan;
		var rowSpan = td.rowSpan;
		if(colSpan == 1) {
			tr.removeChild(td);
			y += rowSpan - 1;
			continue;
		}
		td.colSpan = colSpan - 1;
	}
	this._dropLayout();
}

OdfTableEditor.prototype.deleteTable = function(control)
{
	if(this._tableElement == null) return;
	this._buildLayout();
	this._tableElement.parentElement.removeChild(this._tableElement);
	this._dropLayout();	
	this._tableElement = null;
	this._rowElement = null;
	this._cellElement = null;
	this._colElement = null;
	this._clickElement = null;

}

OdfTableEditor.prototype.moveCellContent = function(cell, td)
{
	if(cell == td) return;
	while(cell.firstChild) {
		var node = cell.firstChild;
		cell.removeChild(node);
		td.appendChild(node);
	}
}

OdfTableEditor.prototype.getCell = function(x, y)
{
	var td = this._cells[x + " " + y];
	if(td == null) {
		alert("missing cell " + x + " " + y);
	}
	return td;
}
OdfTableEditor.prototype.incrementColspan = function()
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var shadowedCells = new Array();
	var td = this._cellElement;
	var colSpan = td.colSpan;
	var rowSpan = td.rowSpan;
	var x = td.x + colSpan;
	var ok = true;
	var incrementColspan = null;
	if(x > this._nbCols) {
		ok = false;
	}
	else {
		for(var y=td.y;y<td.y+rowSpan;) {
			var cell = this.getCell(x, y);
			if(incrementColspan == null) incrementColspan = cell.colSpan;
			if(cell.colSpan != incrementColspan) {
				ok = false;
				break;
			}
			if(cell.y < td.y) {
				ok = false;
				break;
			}
			y += cell.rowSpan;
			if(cell.y + cell.rowSpan > td.y+rowSpan) {
				ok = false;
				break;
			}
			shadowedCells[shadowedCells.length] = cell;
		}
	}
	if(ok) {
		for(var i=0;i<shadowedCells.length;i++) {
			var cell = shadowedCells[i];
			this.moveCellContent(cell, td);
			cell.parentElement.removeChild(cell);
		}
		td.colSpan = colSpan + incrementColspan;
	}
	this._dropLayout();
}

OdfTableEditor.prototype.incrementRowspan = function()
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var shadowedCells = new Array();
	var td = this._cellElement;
	var colSpan = td.colSpan;
	var rowSpan = td.rowSpan;
	var y = td.y + rowSpan;
	var ok = true;
	var incrementRowspan = null;
	if(y > this._rows.length) {
		ok = false;
	}
	else {
		var done = {};
		for(var x=td.x;x<td.x+colSpan;x++) {
			var cell = this.getCell(x, y);
			if(incrementRowspan == null) incrementRowspan = cell.rowSpan;
			if(cell.rowSpan != incrementRowspan) {
				ok = false;
				break;
			}
			if(cell.x < td.x) {
				ok = false;
				break;
			}
			if(cell.x + cell.colsSpan > td.x+colSpan) {
				ok = false;
				break;
			}
			var key = cell.x + " " + cell.y;
			if(done[key]) continue;
			done[key] = true;
			shadowedCells[shadowedCells.length] = cell;
		}
	}
	if(ok) {
		for(var i=0;i<shadowedCells.length;i++) {
			var cell = shadowedCells[i];
			this.moveCellContent(cell, td);
			cell.parentElement.removeChild(cell);
		}
		td.rowSpan = rowSpan + incrementRowspan;
	}
	this._dropLayout();
}

OdfTableEditor.prototype.splitCell = function()
{
	if(this._cellElement == null) return;
	this._buildLayout();
	var td = this._cellElement;
	var colSpan = td.colSpan;
	var rowSpan = td.rowSpan;
	if(colSpan != 1 || rowSpan != 1) {
		for(var y = td.y;y < td.y + rowSpan;y++) {
			var tr = this._rows[y];
			var nextTd = null;
			for(var i=0;i<tr.childNodes.length;i++) {
				var child = tr.childNodes[i];
				if(child.tagName != "TD") continue;
				if(child.x > td.x) {
					nextTd = child;
					break;
				}
			}
			for(var x = td.x;x < td.x + colSpan;x++) {
				if(x == td.x && y == td.y) continue;
				var newTd = this.addCell(tr, nextTd);
			}
		}
		td.rowSpan = 1;
		td.colSpan = 1;
	}
	this._dropLayout();
}

OdfTableEditor.prototype.attributeString = function(str)
{
	str = "" + str;
	return str.replace(/"/g,"&quot;");
}

OdfTableEditor.prototype.formatAttribute = function(name, value)
{
	if(value == null) return "";
	return " " + name + "=\"" + this.attributeString(value) + "\"";
}
OdfTableEditor.prototype.formatText = function(str)
{
	if(str == null) return "";
	return str.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}

OdfTableEditor.prototype.createTable = function(headRows, rows, columns, width, style, align, caption, summary)
{
	var html = "<table";
	var className = "clear " + style + " tabTable";
	html += this.formatAttribute("class", className);
	html += this.formatAttribute("width", width);
	html += this.formatAttribute("align", align);
	html += this.formatAttribute("summary", summary);
	html += ">";
	html += "<caption";
	html += this.formatAttribute("align", "top");
	html +=">";
	html += this.formatText(caption);
	html += "</caption>";
	html += "<colgroup>";
	for(var i=0;i<columns;i++) {
		html += "<col";
		html += this.formatAttribute("width", "100px");
		html += this.formatAttribute("span", "1");
		html += "/>";
	}
	html += "</colgroup>\n";
	html += "<tbody>\n";
	for(var j=0;j<headRows;j++) {
		html += "<tr";
		html += this.formatAttribute("class", j % 2 == 0 ? "even": "odd");
		html += ">";
		for(var i=0;i<columns;i++) {
			html += "<th"
			if(isXHTMLEditor) {
				html += this.formatAttribute("style", "text-align:left;vertical-align:middle");
			} else {
				html += this.formatAttribute("align", "left");
				html += this.formatAttribute("valign", "middle");
			}
			html += this.formatAttribute("class", "headerCell");
			html += ">";
			html += "<p>";
			html += "&nbsp;";
			html += "</p>";
			html += "</th>";
		}
		html += "</tr>\n";
	}
	for(var j=0;j<rows;j++) {
		html += "<tr";
		html += this.formatAttribute("class", (j + headRows) % 2 == 0 ? "even": "odd");
		html += ">";
		for(var i=0;i<columns;i++) {
			html += "<td"
			if(isXHTMLEditor) {
				html += this.formatAttribute("style", "text-align:left;vertical-align:middle");
			} else {
				html += this.formatAttribute("align", "left");
				html += this.formatAttribute("valign", "middle");
			}
			html += this.formatAttribute("class", "cell");
			html += ">";
			html += "<p>";
			html += "&nbsp;";
			html += "</p>";
			html += "</td>";
		}
		html += "</tr>\n";
	}
	html += "</tbody>\n";
	html += "</table>\n";
	return html;
}

OdfTableEditor.prototype.convertToXHTML = function(tableElement, control)
{
	this.bind(tableElement);
	this._buildLayout();
	var cellAlignEditor = richTextAttributeEditor.getAttributeEditor("cellAlign");
	var cellVAlignEditor = richTextAttributeEditor.getAttributeEditor("cellVAlign");
	var widthEditor = richTextAttributeEditor.getAttributeEditor("width");
	var html = "<table";
	var className = "clear ";
	className = "";
	var align;
	switch(tableElement.align) {
	case "center":
		className += "isoBlockPosition-center";
		break;
	case "right":
		className += "isoBlockPosition-floatRight";
		break;
	default:
		className += "isoBlockPosition-floatLeft";
		break;
	}
	className += (tableElement.className.toLowerCase().indexOf("oddeven") >= 0) ? " tabOddEvenTable":" tabStandardTable";
	className += " tabTable";
	html += this.formatAttribute("class", className);
	html += this.formatAttribute("width", widthEditor.getValue(tableElement));
	html += this.formatAttribute("summary", tableElement.summary);
	var style = "";
	if(this.normalizeClear(tableElement.style.clear) == "none") style += "clear:none;";
	html += this.formatAttribute("style", style);
	html += ">";
	if(this._captionElement) {
		html += "<caption";
		var captionAlign = "top";
		if(this._captionElement.align == "bottom") captionAlign = "bottom";
		html += this.formatAttribute("align", captionAlign);
		html +=">";
		html += this.formatText(this._captionElement.innerText);
		html += "</caption>";
	}
	html += "<colgroup>";
	for(var i=0;i<this._cols.length;i++) {
		var col = this._cols[i];
		html += "<col";
		html += this.formatAttribute("width", col.width);
		html += this.formatAttribute("span", "1");
		html += "/>";
	}
	html += "</colgroup>\n";
	html += "<tbody>\n";
	for(var j=0;j<this._rows.length;j++) {
		var tr = this._rows[j];
		html += "<tr";
		html += this.formatAttribute("class", j % 2 == 0 ? "even": "odd");
		html += ">";
		var cells = tr.childNodes;
		for(var k=0;k<cells.length;k++) {
			var td = cells[k];
			var tagName = td.tagName.toLowerCase();
			var className = "";
			var align = cellAlignEditor.getValue(td);
			var vAlign = cellVAlignEditor.getValue(td);
			switch(align) {
			case "left":
				className += "textAlignLeft";
				break;
			case "right":
				className += "textAlignRight";
				break;
			case "center":
				className += "textAlignCenter";
				break;
			}
			switch(vAlign) {
			case "top":
				className += " verticalAlignTop";
				break;
			case "bottom":
				className += " verticalAlignBottom";
				break;
			case "middle":
				className += " verticalAlignMiddle";
				break;
			}
			if(tagName == "td") {
				className += " cell";
			} else {
				className += " headerCell";
			}
			html += "<" + tagName
			html += this.formatAttribute("class", className);
			html += this.formatAttribute("colspan", td.colSpan);
			html += this.formatAttribute("rowspan", td.rowSpan);
			html += ">";
			td.innerHTML = td.innerHTML.replace(/>&nbsp;</g, ">いい<");
			var children = td.childNodes;
			var content = "";
			for(var l=0;l<children.length;l++) {
				content += control.convertToXHTML(children[l], false);
			}
			html += content.replace(/>いい</g, ">&nbsp;<");
			td.innerHTML = td.innerHTML.replace(/>いい</g, ">&nbsp;<");
			html += "</" + tagName + ">";
		}
		html += "</tr>\n";
	}
	html += "</tbody>\n";
	html += "</table>\n";
	this._dropLayout();

	return html;
}

OdfTableEditor.prototype.normalizeClear = function(value)
{
	return value == "none" ? value : "both";
}

OdfTableEditor.prototype.convertToHTML = function(tableElement, control, needNormalize)
{
	this.bind(tableElement);
	this._buildLayout();
	var layout = this.saveLayout();
	var flatten = false;
	if(tableElement.innerHTML.indexOf("<TABLE") >= 0) {
		flatten = true
	}
	var html = "";
	if(flatten) {
		for(var j=0;j<this._rows.length;j++) {
			var tr = this._rows[j];
			var cells = tr.childNodes;
			for(var k=0;k<cells.length;k++) {
				var td = cells[k];
				var children = td.childNodes;
				for(var l=0;l<children.length;l++) {
					if(needNormalize) {
						html += control.normalizeImportedHTML(children[l], false, true);
					} else {
						html += control.convertToHTML(children[l], false, true);
					}
					this.restoreLayout(layout);
				}
			}
		}
	} else {
		var cellAlignEditor = richTextAttributeEditor.getAttributeEditor("cellAlign");
		var cellVAlignEditor = richTextAttributeEditor.getAttributeEditor("cellVAlign");
		html += "<table";
		var className = "clear ";
		className = "";
		var srcClassName = tableElement.className.toLowerCase();
		var align = "left";
		var containsTable = false;
		if(srcClassName.indexOf("left")>=0) {
			align = "left";
		} else if(srcClassName.indexOf("right")>=0) {
			align = "right";
		} else if(srcClassName.indexOf("center")>=0) {
			align = "center";
		} 
		className += (srcClassName.indexOf("oddeven") >=0)? " tabOddEvenTable":" tabStandardTable";
		className += " tabTable";
		html += this.formatAttribute("class", className);
		html += this.formatAttribute("width", tableElement.width);
		html += this.formatAttribute("align", align);
		html += this.formatAttribute("summary", tableElement.summary);
		var style = "";
		if(this.normalizeClear(tableElement.style.clear) == "none") style += "clear:none;";
		if(align != "center") {
			style += "float:" + align + ";";
			if(align == "left") style += "margin-right:5px;"
			else style += "margin-left:5px;"
		} 
		html += this.formatAttribute("style", style);
		html += ">";
		if(this._captionElement) {
			html += "<caption";
			var captionAlign = "top";
			if(this._captionElement.align == "bottom") captionAlign = "bottom";
			html += this.formatAttribute("align", captionAlign);
			html +=">";
			html += this.formatText(this._captionElement.innerText);
			html += "</caption>";
		}
		html += "<colgroup>";
		for(var i=0;i<this._cols.length;i++) {
			var col = this._cols[i];
			html += "<col";
			html += this.formatAttribute("width", col.width);
			html += this.formatAttribute("span", "1");
			html += "/>";
		}
		html += "</colgroup>\n";
		html += "<tbody>\n";
		for(var j=0;j<this._rows.length;j++) {
			var tr = this._rows[j];
			html += "<tr";
			html += this.formatAttribute("class", j % 2 == 0 ? "even": "odd");
			html += ">";
			var cells = tr.childNodes;
			for(var k=0;k<cells.length;k++) {
				var td = cells[k];
				var tagName = td.tagName.toLowerCase();
				var srcClassName = td.className.toLowerCase();
				var className = "";
				var align = cellAlignEditor.getValue(td);
				var vAlign = cellVAlignEditor.getValue(td);
				if(tagName == "td") {
					className += " cell";
				} else {
					className += " headerCell";
				}
				html += "<" + tagName
				html += this.formatAttribute("class", className);
				if(isXHTMLEditor) {
					html += this.formatAttribute("style", "text-align:" + align + ";vertical-align:" + vAlign);
				} else {
					html += this.formatAttribute("align", align);
					html += this.formatAttribute("valign", vAlign);
				}
				html += this.formatAttribute("colspan", td.colSpan);
				html += this.formatAttribute("rowspan", td.rowSpan);
				html += ">";
				var children = td.childNodes;
				for(var l=0;l<children.length;l++) {
					if(needNormalize) {
						html += control.normalizeImportedHTML(children[l], false, true);
					} else {
						html += control.convertToHTML(children[l], false, true);
					}
					this.restoreLayout(layout);
				}
				html += "</" + tagName + ">";
			}
			html += "</tr>\n";
		}
		html += "</tbody>\n";
		html += "</table>\n";
	}
	this._dropLayout();
	return html;
}


var objTableEditor = new OdfTableEditor();