String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
};

function test() {
	//	alert('testing budget worksheets');
}

function eraseAllInput() 
{
		for (var i=0; i<cats.length; i++)
		{
			var c = cats[i];
			for (var j=0; j<c.lines.length; j++)
			{
				c.lines[j].actual.value = null;
				displayCell(c.lines[j].actual);
				c.lines[j].budget.value = null;
				displayCell(c.lines[j].budget);				
				c.lines[j].difference.value = null;				
				displayCell(c.lines[j].difference);
			}
			c.actual.value = null;
			c.budget.value = null;
			c.difference.value = null;

			displayCell(c.actual);
			displayCell(c.budget);
			displayCell(c.difference);			
		}
		$("#total_difference").text("$");
	  $("#total_budget").text("$");	
	  $("#total_actual").text("$");	
}

function sumTotals() {
  var budget = 0;
  var actual = 0;
  var diff = 0;

	i = cats.length
	while(i--) {
	  if (cats[i].difference.value) 
	    diff += cats[i].difference.value;
	  if (cats[i].actual.value) 
	    actual += cats[i].actual.value;
	  if (cats[i].budget.value) 
	    budget += cats[i].budget.value;
	}
	//alert('budgeted: '+budget+' actual: '+actual+' difference: '+diff);
	if (diff && diff.toFixed) {
	  $("#total_difference").text("$" + diff.toFixed(2));
	} else {
	  $("#total_difference").text("$0.00");
	}
	if (budget && budget.toFixed) {
	  $("#total_budget").text("$" + budget.toFixed(2));
	} else {
	  $("#total_budget").text("$0.00");	
	}
	if (actual && actual.toFixed) {
	  $("#total_actual").text("$" + actual.toFixed(2));
	} else {
	  $("#total_actual").text("$0.00");	
	}

}

$(document).ready(function() {

	//index lines
	for (var i=0; i<cats.length; i++)
	{
		var c = cats[i];
		for (var j=0; j<c.lines.length; j++)
		{
			var x = c.lines[j];
			lines[x.id] = x;
		}
	}
	for (var i=0; i<cats.length; i++)
	{
		var c = cats[i];
		for (var j=0; j<c.lines.length; j++)
		{
			var x = c.lines[j];
			// set up initial values

			if (x.actual.value != null) {
				x.actual.value = getValueFromString(x.actual.value);
       	//$("#cell_" + x.actual.id).show();
	      displayCell( x.actual );
	      //calcLine( x );
			} else {
			  x.actual.value = new Number(0);
	      displayCell( x.actual );
			}
			if (x.budget.value != null) {
				x.budget.value = getValueFromString(x.budget.value);
       	//$("#cell_" + x.budget.id).show();
	      displayCell( x.budget );
	      calcLine( x );			
			} else {
				x.budget.value = new Number(0);
	      displayCell( x.budget );			
 	      calcLine( x );			
			}
			
			$("#cell_" + x.budget.id  ).bind("click focus", { cell: x.budget }, 
				function(event) {
					editCell( event.data.cell );
				}
			);
			$("#cell_" + x.actual.id  ).bind("click focus", { cell: x.actual }, 
				function(event) {
					editCell( event.data.cell );
				}
			);
			$("#input_" + x.budget.id  ).bind("blur", { cell: x.budget }, 
				function(event) {
					blurCell( event.data.cell );
				}
			);
			$("#input_" + x.actual.id  ).bind("blur", { cell: x.actual }, 
				function(event) {
					blurCell( event.data.cell );
				}
			);
			$("#input_" + x.budget.id  ).bind("keyup", { cell: x.budget }, 
				function(event) {
					keyupCell( event, event.data.cell );
				}
			);
			$("#input_" + x.actual.id  ).bind("keyup", { cell: x.actual }, 
				function(event) {
					keyupCell( event, event.data.cell );
				}
			);
		}
	}

});


// If the value to add is null, then set the sum to null as well
var addCatSum = function(oldVal, toAdd)
{
	if ( oldVal === null || toAdd === null ) {
		return null;
	}
	return oldVal + toAdd;
};

var calcCat = function(cat)
{
	cat.actual.value = 0;
	cat.budget.value = 0;
	cat.difference.value = 0;

	for (var j=0; j<cat.lines.length; j++)
	{
		var x = cat.lines[j];
		cat.actual.value = addCatSum( cat.actual.value, x.actual.value );
		cat.budget.value = addCatSum( cat.budget.value, x.budget.value );
		cat.difference.value = addCatSum( cat.difference.value, x.difference.value );
	}
	displayCell( cat.actual );
	displayCell( cat.budget );
	displayCell( cat.difference );
};

var calcLine = function(line)
{
	if ( line.budget.value !== null && line.actual.value !== null ) {
		line.difference.value = line.budget.value - line.actual.value;
	}
	else {
		line.difference.value = null;
	}
	displayCell( line.difference );
	calcCat( cats[ line.catId ] );
	sumTotals();
};

var editCell = function(cell)
{
	$("#cell_" + cell.id).hide();
	$("#input_" + cell.id).show();
	var v = "";
	if ( cell.value !== null ) {
		v = cell.value;
	}	
	$("#input_" + cell.id).val( v );
	$("#input_" + cell.id).focus();
};

var blurCell = function(cell)
{
	$("#input_" + cell.id).hide();
	var s = $("#input_" + cell.id).val(); 
	cell.value = getValueFromString(s);
	$("#cell_" + cell.id).show();
	displayCell( cell );
	calcLine( lines[ cell.lineId ] );
};

// shift focus to next editable element
var editNext = function(cell) 
{
  if (cell.id==lines[cell.lineId].budget.id) {
    editCell(lines[cell.lineId].actual);
  } 
  else if (cell.lineId == (lines.length-1))  {
    // nothing
  }
  else { 
    editCell(lines[(cell.lineId+1)].budget); 
  }
};

// (arnie) don't really like the shifting of the display left <=> right
var displayCell = function(cell)
{
	if ( cell.value === null ) {
		$("#cell_" + cell.id).text("$");
/*		$("#cell_" + cell.id).attr("textAlign", "left"); */
	}
	else if (cell.value.toFixed) {
			$("#cell_" + cell.id).text("$" + cell.value.toFixed(2));
  } else {
  		$("#cell_" + cell.id).text("$0.00");
  }
/*		$("#cell_" + cell.id).css("text-align", "right");  */
};
var displayBlankCell = function(cell)
{
		$("#cell_" + cell.id).text("$");
}

var getValueFromString = function(s)
{
	s = s.trim();
	if ( s == "" ) {
		return 0;
	}
	s = s.replace(/\$/g, "");
	s = s.replace(/,/g, "");
	if ( s == "" )	{
		return 0;
	}
	v = parseFloat(s);
	if ( isNaN(v) ) {
		return new Number(0);
	}
	return v;
};

var getKeyCode = function(e)
{
	if (document.all) {
		return window.event.keyCode;
	}
	else { 
		return e.which;
	}
};

var keyupCell = function(e,cell)
{
	var code = getKeyCode(e);
	if ( code == 13 ) {
		blurCell(cell);
		editNext(cell)
	} else if ( code == 27 ) {
		blurCell(cell);
	}
};



