// ---- xml table column ----
function XmlTableColumn (id, title, xmlName, show) {
	this.id = id;
	this.title = title;
	this.xmlName = xmlName;
	this.show = show || 1;

  this.fromXml = function (n) {
    this.id = n.getA('id');
    this.title = n.getA('title');
    this.xmlName = n.getA('name');
    this.show = n.getA('show') == 1;
  }

  this.fromCell = function (cell) {
  	this.id = cell.getAttribute('xmlId');
  	this.title = cell.innerHTML;
  	this.xmlName = cell.getAttribute('xmlName');
  	this.show = true;
  }
}

// ---- xml table column list----
function XmlTableColumns () {
	XmlTableColumns.superclass.constructor.call(this);
}
extend(XmlTableColumns, SimpleArray);
mixin (XmlTableColumns.prototype, {
	fromXml : function (n) {
		var i = 0;
    n = n.getFC('column');
    while (n != undefined) {
      var column = new XmlTableColumn();
      column.fromXml(n);
      if (column.id == undefined) column.id = i++;
      this.addRow(column);
      n = n.getNS('column');
    }
	},
	fromRow : function (row) {
		for (var i = 0; i < row.cells.length; i++) {
			var column = new XmlTableColumn();
      column.fromCell(row.cells[i]);
      if (column.id == undefined) column.id = i++;
      this.addRow(column);
		}
	}
})

// ---- xml table data cell ----
function XmlTableDataCell (id, value) {
	this.id = id;
	this.value = value;
}

// ---- xml table data row ----
function XmlTableDataRow () {
	XmlTableDataRow.superclass.constructor.call(this);
}
extend(XmlTableDataRow, SimpleArray);
mixin (XmlTableDataRow.prototype, {
	fromXml : function (n, columns) {
  	for(var i = 0; i < columns.rows.length; i++)
  	{
  		var column = columns.rows[i];
  		if (column != undefined)
  		{
	  		var cell = new XmlTableDataCell(column.id, n.getA(column.xmlName));
		    this.addRow(cell);
		  }
    }
  }
})

// ---- xml table data  ----
function XmlTableData () {
	XmlTableData.superclass.constructor.call(this);
}
extend(XmlTableData, SimpleArray);
mixin (XmlTableData.prototype, {
	fromXml : function (n, columns) {
		var i = 0;
    n = n.getFC('row');
    while (n != undefined) {
      var row = new XmlTableDataRow();
      row.fromXml(n, columns);
      if (row.id == undefined) row.id = i++;
      this.addRow(row);
      n = n.getNS('row');
    }
	}
})

// ---- xml table data cell ----
function XmlTableTemplate (id, template) {
	this.id = id;
	this.template = template;
}
// ---- xml table templates  ----
function XmlTableTemplates () {
	XmlTableTemplates.superclass.constructor.call(this);
}
extend(XmlTableTemplates, SimpleArray);
mixin (XmlTableTemplates.prototype, {
	fromRow : function (row, columns) {
		for (var i = 0; i < row.cells.length; i++) {
			var cell = row.cells[i];
			if (cell.getAttribute('xmlId') != undefined)
			{
				var column = columns.getRow(cell.getAttribute('xmlId'));
				if (column != undefined)
				{
					var template = (new XMLSerializer()).serializeToString(cell);
					var cellTemplate = new XmlTableTemplate(column.id, template);
		      this.addRow(cellTemplate);
      	}
      }
		}
	}
})

var xmlTableTypes = { xmlTableHeader:0, xmlTableTemplate:1 }

// ---- xml table   ----
function XmlTable (self_name, container) {
	this.self_name = self_name;
	this.container = container;

	this.columns = new XmlTableColumns();
	this.data = new XmlTableData();

	this.templateRow = undefined;
	this.columnRow = undefined;

  this.init = function () {
    if (this.container != undefined && typeof(this.container) == 'string') {
      this.container = document.getElementById(this.container);
			this.initFromContainer();
			this.clearContainer();
		}	
  }

  this.initFromContainer = function () {
		if (this.container != undefined && this.container.rows != undefined) {
		  for (var i = 0; i < this.container.rows.length; i++)
		  {
		  	var row = this.container.rows[i];
		  	if (row.getAttribute('xmlTableType') == 'xmlTableHeader')
		  	{
		  		this.columnRow = row;
		  	  this.columns.fromRow(row);
		  	}
		  	if (row.getAttribute('xmlTableType') == 'xmlTableTemplate')
		  	  this.templateRow = row;
		  }
		}
  }

  this.clearContainer = function () {
		if (this.container != undefined && this.container.rows != undefined) {
		  var i = 0;
	    while ( this.container.rows.length > i )
	    {
	    	var row = this.container.rows[i];
	    	if (row.getAttribute('xmlTableType') == 'xmlTableHeader')
	    	  i++;
	    	else
			    this.container.deleteRow(i);
		  }
    }
  }

  this.clear = function () {
		this.columns = new XmlTableColumns();
		this.data = new XmlTableData();

		this.templateRow = undefined;
		this.columnRow = undefined;
  }

  this.fromXml = function (n) {
 		var node = n.getFC('columns');
 		if (node != undefined) this.columns.fromXml(node);

  	if (this.columns.rows.length > 0) {
			node = n.getFC('rows');
			if (node != undefined) 
			{
				this.data.clear();
				this.data.fromXml(node, this.columns);
			}
  	}
  }

  this.show = function () {
  	this.clearContainer();
  	var tbl = this.container;
	  if (this.columnRow == undefined) {
			this.columnRow = tbl.insertRow(tbl.rows.length);
	    for (var i = 0; i < this.columns.rows.length; i++) {
	    	var column = this.columns.rows[i];
	    	if (column.show)
	    	{
		    	var cell = this.columnRow.insertCell(this.columnRow.cells.length);
		    	cell.innerHTML = column.title;
		    }
	    }
	  }

    for (var i = 0; i < this.data.rows.length; i++) {
	    var dataRow = this.data.rows[i];
      if (this.templateRow != undefined) {
		    var newRow = this.templateRow.cloneNode(true); 
		    for (var j = 0; j < dataRow.rows.length; j++) {
		    	var dataCell = dataRow.rows[j];
		    	var column = this.columns.getRow(dataCell.id);
		    	if (column != undefined)
		    		for (var k = 0; k < newRow.cells.length; k++)
							newRow.cells[k].innerHTML = newRow.cells[k].innerHTML.replace(new RegExp('#' + column.xmlName + '#', 'g'), (dataCell.value || ''));
		    }
		    this.columnRow.parentNode.appendChild(newRow);
      }
      else {
      	var row = tbl.insertRow(tbl.rows.length);
		    for (var j = 0; j < this.columns.rows.length; j++) {
		    	var column = this.columns.rows[j];
	  	  	if (column.show)
	    		{
	    			var dataCell = dataRow.getRow(column.id);
		    		var cell = row.insertCell(row.cells.length);
	    			if (dataCell != undefined)
			    		cell.innerHTML = dataCell.value || '';
			    }
		    }
		  }

    }
  	
  }

  this.init();
}

