var JSDC_DAO_TABLE_EXISTS = true;

// tableoptions() - Settingsobject for data_aware_object. Note character casing.
function tableoptions()
{
	this.header = true;
	this.headerClass = null; // Default CSS class for headers. 
	this.valueClass = null; // Default CSS class for values.  
	this.editClass = null; // Default CSS class for editors.  
	this.deleteBtnImgURL = null;
//	this.moveupBtnImgURL = null;
//	this.movedownBtnImgURL = null;
	this.header_row = null;
	this.onPopulateSelect = null;
	
	this.PopulateSelect = function PopulateSelect(col_idx, curr_col, curr_input)
	{
		var pop_result = false;
		if (this.onPopulateSelect)
		{
			pop_result = this.onPopulateSelect(col_idx, curr_col, curr_input)
		
		}
		if (!pop_result)
		{
			var curr_option, curr_lookup;
			for (var opt_idx in curr_col.lookup_values)
			{
				curr_lookup = curr_col.lookup_values[opt_idx];
				makeOptionElement(curr_lookup.value,curr_lookup.name, curr_input)
			}	
		}
	}
}
function makeOptionElement(value, name, parentNode)
{

	var curr_option = document.createElement("option");
	curr_option.value = value;
	curr_option.innerHTML = name;
	if (parentNode)
	{
		parentNode.appendChild(curr_option);
	}
}
function table_update_node_refs(objects, index)
{
	var object_count = objects.length;
	var row_idx;
	for (row_idx in objects)
	{
		objects[row_idx].lastChild.value = row_idx;
	}
}

function table_make_data_row(dest, row_idx, colstyles)
{
	var new_td, celldata, curr_input;	
	var new_tr = document.createElement("tr");
	if (!colstyles) {colstyles = make_column_styles(dest);}
	for (col_idx in dest.dataview.columns)
	{
		curr_col = dest.dataview.columns[col_idx];
		if (curr_col.visible==true)
		{
			new_td = document.createElement("td"); 
			celldata = curr_col.getdata(row_idx);
			if (curr_col.editable)
			{

				if (curr_col.datatype == "custom" || curr_col.datatype == "multiple")
				{					
					curr_input = document.createElement("input");
					curr_input.type = "button";
					curr_input.value = "Edit";
					if (curr_input.attachEvent) 
					{
						curr_input.attachEvent("onclick", dest.DoOnEdit);
					}
					else
					{
						curr_input.addEventListener("click", dest.DoOnEdit, false); // standards compliant; doesn't work in IE
					}	
				}
				else
				if (curr_col.lookup_values.length > 0)
				{
					curr_input = document.createElement("select");
					dest.options.PopulateSelect(col_idx, curr_col, curr_input);
					curr_input.selectedIndex = celldata;
					if (curr_input.attachEvent) 
					{
						curr_input.attachEvent("onchange", dest.DoOnEdit);
					}
					else
					{
						curr_input.addEventListener("change", dest.DoOnEdit, false); // standards compliant; doesn't work in IE
					}	
					curr_input.className = dest.options.editClass;
				}
				else
				{
					curr_input = document.createElement("input"); 
					curr_input.value = celldata;

					if (curr_input.attachEvent) 
					{
						curr_input.attachEvent("onkeyup", dest.DoOnEdit);
					}
					else
					{
						curr_input.addEventListener("keyup", dest.DoOnEdit, false); // standards compliant; doesn't work in IE
					}
					curr_input.className = dest.options.editClass;				
				}

				
			
	
				new_td.appendChild(curr_input);
		
			}
			else
			{				
				if (colstyles[col_idx])
				{
					new_td.innerHTML = MakeSpanned(celldata, colstyles[col_idx]);
				}
				else
				{
					new_td.innerHTML = celldata;	
				}
			}					
			new_tr.appendChild(new_td);
		}
	}
  
	if (dest.DeleteBtn)
	{
		var evnt_obj;
		new_td = document.createElement("td"); 

		if (!dest.options.deleteBtnImgURL)
		{
			
			evnt_obj = document.createElement("input");
			evnt_obj.type = "button";
			evnt_obj.value = dest.DeleteBtn;
			new_td.appendChild(evnt_obj);
		}
		else
		{
			evnt_obj = document.createElement("img");
			evnt_obj.src = dest.options.deleteBtnImgURL;
			evnt_obj.alt = dest.DeleteBtn;
			evnt_obj.id	= "del_img";

			new_td.appendChild(evnt_obj);
		}

		if (evnt_obj.attachEvent) 
		{
			evnt_obj.attachEvent("onclick", dest.DoOnDelete);
		}
		else
		{
			evnt_obj.addEventListener("click", dest.DoOnDelete, true); // standards compliant; doesn't work in IE
		}
		new_tr.appendChild(new_td);	  

	}
	var row_ref = document.createElement("input");
	row_ref.type = "hidden"; 
	row_ref.id 	= "row_ref";
	row_ref.value = row_idx;
	new_tr.appendChild(row_ref);

	dest.data_row_objects.splice(row_idx, 0, new_tr);
	return new_tr;
}

function table_make_aggregates(dest, parent)
{
	
	var curr_col, col_idx;
	if (!dest.aggregate_object) // New row means that there are no aggregates right now but should be at new_row.
	{
		var agg_row = null;
		if (dest.dataview.selection.length > 0)
		{
			for (col_idx in dest.dataview.columns) 
			{
				if (dest.dataview.columns[col_idx].aggregate) 
				{
					agg_row = document.createElement("tr");
					break;
				}
			}
			if (agg_row)
			{
				dataview_recalculate_aggregates(dest.dataview);
				
				for (col_idx in dest.dataview.columns)
				{
					curr_col = dest.dataview.columns[col_idx];
					if (curr_col.visible == true)
					{
						new_td = document.createElement("td"); 
						if (curr_col.aggregate)
						{
							new_td.innerHTML = dest.dataview.aggregate_values[col_idx];	
						}
						agg_row.appendChild(new_td);
					}
				}	
				dest.aggregate_object = agg_row;
				if (parent)
				{
					add_tr_to_table(parent, agg_row);
				}
				return agg_row;
			}
		}
	}
	else
	{
		dataview_recalculate_aggregates(dest.dataview);
		var curr_td, agg_row;
		var visible_col = 0;
		for (col_idx in dest.dataview.columns)
		{
			curr_col = dest.dataview.columns[col_idx];
			if (curr_col.visible == true) 
			{
				curr_td = dest.aggregate_object.childNodes[visible_col]; 
				if (curr_col.aggregate)
				{
					curr_td.innerHTML = dest.dataview.aggregate_values[col_idx];	
				}
				visible_col++;
			}
		}	
	}
}

function table_refresh(dest) 
{
	// Clear data_row_objects. Data row objects are, for example the tr:s in a table.
	dest.data_row_objects.length = 0;
	
	// To speed up performance, make tabledata in memory, then switch it for the current.
	// Create new tbody
	var new_tbody = document.createElement("tbody");
	// Create fragment container
	var docFragment = document.createDocumentFragment();  
	// Make header
		
	var row_idx, new_tr, col_idx, new_td, row_ref, del_img, evnt_obj, curr_col;
	var new_td_HTML = "";
	if (dest.options.header == true)
	{
		new_tr = document.createElement("tr");
		for (col_idx in dest.dataview.columns)
		{
			curr_col = dest.dataview.columns[col_idx];  
			if (curr_col.visible == true)
			{
				new_td = document.createElement("td"); 
				if (curr_col.headerclass) 
				{
					new_td.innerHTML = MakeSpanned(curr_col.column_name, curr_col.headerclass); // TODO: set className on TD instead
				}
				else
				if (dest.options.headerClass) 
				{
					new_td.innerHTML = MakeSpanned(curr_col.column_name, dest.options.headerClass); // TODO: set className on TD instead
				}
				else
				{
					new_td.innerHTML = curr_col.column_name;
				}
				new_tr.appendChild(new_td);
			}
		}
		docFragment.appendChild(new_tr);
		dest.options.header_row = new_tr;
	}
	// Make datarows
	var sel_length = dest.dataview.selection.length;
	var curr_data;
	var curr_input;
	
	if (sel_length > 0) 
	{	  
		// Generate column styles
		var colstyles = make_column_styles(dest); 
		
		for (row_idx = 0;row_idx<sel_length;row_idx++) 
		{
			// Insert Row
			docFragment.appendChild(table_make_data_row(dest, row_idx, colstyles));
		}
	}	  
	// Make aggregates.
	table_make_aggregates(dest, docFragment);
	
	new_tbody.appendChild(docFragment);	
	if (dest.daobj.childNodes.length > 0)
	{
		dest.daobj.replaceChild(new_tbody, dest.daobj.childNodes[0]);
	}
	else
	{
		dest.daobj.appendChild(new_tbody);
	}

}


function table_update(dest, row_idx, col_idx)
{
	// Find row
	var curr_td, curr_nodeName, curr_data, curr_lookup_idx;
	if (dest.data_row_objects.length > 0)
	{
		var curr_column = src_idx_to_column(dest.dataview, col_idx);

		if (curr_column && curr_column.visible == true) 
		{
			var row_obj = dest.data_row_objects[row_idx];
			var visible_col = col_idx_to_visible(col_idx, dest.dataview);
			curr_td = row_obj.childNodes[visible_col];
			if (curr_column.datatype != "custom" && curr_column.datatype != "multiple")
			{

	
				if (curr_column.lookup_values.length > 0) 
				{ 
					// Loop to find lookup_value
					var lookup_idx = 0
					var lookuplength = curr_column.lookup_values.length;
					while (lookup_idx < lookuplength)
					{
						if (curr_column.lookup_values[lookup_idx].value == curr_column.getdata(row_idx))
						{
							curr_lookup_idx = lookup_idx;
							curr_data = curr_column.lookup_values[lookup_idx].name;
		
							break;
						}
						lookup_idx++;
					}
				}
				else
				{
					curr_data = curr_column.getdata(row_idx);
				}	
				
				if (curr_td.childNodes.length > 0)
				{
					curr_nodeName = curr_td.firstChild.nodeName;
					if (curr_nodeName == "SELECT") // The only case is when there are lookups.
					{ 	// TODO: Here maybe the onPopulateSelect event should be called. Not sure though..			
						curr_td.firstChild.selectedIndex = curr_lookup_idx;
					}
					else
					if (curr_nodeName == "SPAN")
					{
						curr_td.firstChild.innerHTML = curr_data;
					}
					else
					if (curr_nodeName == "#text")
					{
						curr_td.innerHTML = curr_data;
					}
					else
					if (curr_nodeName == "INPUT")
					{
						curr_td.firstChild.value = curr_data;
					}
					else
				
					{
						curr_td.innerHTML = curr_data;
					}
	
				}
				else
				{
					curr_td.innerHTML = curr_data;
				}
			}
			else
			if (curr_column.datatype == "multiple")
			{					
				// Should this editor be visible? 
				var find_row_idx = 0;
				var editor = curr_column.multiple_editor;
				var typesetid = editor.typesetid_column.getdata(row_idx);
				var typesetslength = editor.typesets.length;
				var typeset = null;					
				while (find_row_idx < typesetslength)
				{
					if (editor.typesets[find_row_idx].id == typesetid)
					{
						typeset = editor.typesets[find_row_idx];
						break;
					}
					
					find_row_idx++;
				}
				if (typeset)
				{
					curr_td.firstChild.style.visibility = "visible";	
				}
				else
				{
					curr_td.firstChild.style.visibility = "hidden";	
				}
			}
		}
	}	
	table_make_aggregates(dest);
	
}

function table_insert(dest, row_idx)
{
	if (dest.options.header_row) {var offset = 1;} else { var offset = 0;}
	var new_tr = table_make_data_row(dest, row_idx);
	if ((Number(row_idx)+Number(offset)) < dest.daobj.rows.length)
	{
		add_tr_to_table(dest.daobj, new_tr, dest.daobj.rows[Number(row_idx)+Number(offset)]);
	}
	else
	{
		add_tr_to_table(dest.daobj, new_tr);
	}
	table_update_node_refs(dest.data_row_objects, row_idx);
	table_make_aggregates(dest, dest.daobj);
}

function table_change(dest, action, row_idx, col_idx)
{
  if (dest.daobj)
  {
		switch (action)
		{
			case "refresh":
				table_refresh(dest);  
			break;
			case "remove":
				
				var node_to_delete =  dest.data_row_objects[row_idx];
				node_to_delete.parentNode.removeChild(node_to_delete); 
				dest.data_row_objects.splice(row_idx,1);
				table_update_node_refs(dest.data_row_objects, row_idx);
				table_make_aggregates(dest, dest.daobj);
				
			break;
			case "insert":
				table_insert(dest, row_idx);
			break;
			case "update":
				table_update(dest, row_idx, col_idx);
			break;
		}
	}
	else
	{ 
		alert("daobj not assigned"); 
	}
   
}
