//R. Andrew Lamonica
//Copyright 2005, 2006, & 2007
//Automation Library for http://lamonica.info/

function GridDataHolder(formField, 
	rows,
	cols,
	defaultValue, //Optional
	dataWidth, //Optional Default = 1
	outOfRangeValue) //Optional
	 
{
	this.Data = formField;
	this.Rows = rows;
	this.Cols = cols;
	this.DefaultValue = defaultValue;
	this.OutOfRangeValue = outOfRangeValue;
	if(dataWidth == null)
		this.DataWidth = 1;
	else
		this.DataWidth = dataWidth;
	
	this.Get = function(row, col)
	{
		if(col<0 || row<0 || col>=this.Cols || row>=this.Rows)
		{
			if(null == this.OutOfRangeValue)
				alert("Data Out Of Range " + row + " " + col + " " + value);
			else
				return this.OutOfRangeValue;
		}
		return this.Data.value.substr((row*this.Cols + col)*this.DataWidth, this.DataWidth);
	}
	
	this.Set = function(row, col, value)
	{
		if(col<0 || row<0 || col>=this.Cols || row>=this.Rows)
		{
			if(null == this.OutOfRangeValue)
				alert("Data Out Of Range " + row + " " + col + " " + value);
			else
				return;
		}
		if(value.length > this.DataWidth)
			alert("Data Not correct width " + value);
		else if(value.length < this.DataWidth)
		{
			var neededChars = this.DataWidth - value.length;
			var newValue = " ";
			for(var i=1; i<neededChars; i++)
				newValue = newValue + " ";
			value = newValue + value;
		}
		
		this.Data.value = this.Data.value.substr(0, (row*this.Cols + col)*this.DataWidth) 
			+ value
			+ this.Data.value.substr((row*this.Cols + col + 1)*this.DataWidth);
	}
	
	this.GetValue = function()
	{
		return this.Data.value;
	}
	
	this.SetValue = function(newValue)
	{
		if(this.Rows*this.Cols*this.DataWidth != newValue.length)
			alert("Bad value");
		else
			this.Data.value = newValue;
	}
	
	this.Reset = function()
	{
		if(null != this.DefaultValue)
			this.Data.value = this.DefaultValue;
	}
	
	//Constructor
	if(this.Data==null || this.Rows<1 || this.Cols<1)
		alert("Bad Parameter");
	if(this.Data.value.length != this.Rows*this.Cols*this.DataWidth)
		this.Reset();
}


//clickUpdateFunction = function(
//					current_value, <-- the value at this location
//					row, col, <-- Where was clicked
//					data, <-- the data grid
//					tableCell <-- the cell that was clicked
//					theBoard
//					) returns new value <--text string of the new value
//table <-- table to populate
//gridDataHolder <-- the data
//pictureList <-- an object with relating values to the pictures they should display
//    Example var pictureList = {"X" : "X.gif", "Y" : "uglyy.gif"}
function DynamicBoard(clickUpdateFunction, table, gridDataHolder, pictureList)
{
	this.hasFinishedLoading = false;
	this.Data = gridDataHolder;
	this.Table = table;
	this.ClickUpdateFunction = clickUpdateFunction;
	this.Pictures = pictureList;
	
	this.ClickHandler = function(e)
	{
		if(!e) var e = window.event;
		var target = (e.target) ? e.target : e.srcElement;
		
		var clickedRow = target.Row;
		var clickedCol = target.Col;
		var storedState = this.Data.GetValue();
		
		var returnedValue = this.ClickUpdateFunction(
			this.Data.Get(clickedRow, clickedCol), 
			clickedRow, clickedCol, 
			this.Data,
			target.parentNode,
			this);
		
		var refresh = (storedState != this.Data.GetValue());
		var singleValueUpdated = (returnedValue!=null && returnedValue.length==this.Data.DataWidth);
		
		if(singleValueUpdated)
			this.Data.Set(clickedRow, clickedCol, returnedValue);
		
		if(refresh)
			this.Refresh();
		else if(singleValueUpdated)
			target.src = this.Pictures[returnedValue];
		
		if(e.preventDefault)
			e.preventDefault();
		return false;
	}
	
	//Refreshes the board
	this.Refresh = function()
	{
		//If we are not done loading then ignore this call 
		//(we will refresh when done loading)
		if(!this.hasFinishedLoading)
			return;
			
		var r,c;
		for(r=0; r<this.Data.Rows; r++)
		{
			for(c=0; c<this.Data.Cols; c++)
			{
				var img = this.Table.rows[r].cells[c].childNodes[0];
				img.Row = r;
				img.Col = c;
				img.src = this.Pictures[this.Data.Get(r,c)];
			}
		}
	}
	
	this.CreateBoard = function()
	{
		var r,c;
		for(r=0;r<this.Data.Rows;r++)
		{
			var newRow = this.Table.insertRow(r);
			for(c=0;c<this.Data.Cols;c++)
			{
				var newCell = newRow.insertCell(c);
				var newIMG = document.createElement("img");
				var evnt = this;
				AttachEvent(newIMG, "click", function(e) { return evnt.ClickHandler(e); });
				newCell.appendChild(newIMG);
			}
		}
		this.hasFinishedLoading = true;		
		this.Refresh();
	}
	//constructor
		
	//pre-load images then call CreateBoard
	var preloadArray = new Array();
	var toBeLoaded = 0;
	for(var key in pictureList)
		toBeLoaded++;
	var i=0;
	var currentBoard = this;
	for(var key in pictureList)
	{
		preloadArray[i] = document.createElement("img");
		preloadArray[i].src = pictureList[key];
		AttachEvent(
			preloadArray[i], 
			"load", 
			function() 
			{ 
				if(--toBeLoaded<=0) 
					currentBoard.CreateBoard(); 
			}
		);
		i++;
	}
}
