/*
 * 	TODO
 * 	1. add comments
 * 	2. rectify column widths
 * 	3. animate column toggle
 * 	4. create totaling function (iterate down rows)
 */

;(function($){
	
	$.fn.tableTotals = function( options ){
	
		if ( this.length > 1 ){
			this.each(function(){ $(this).tableTotals(options); });
			return this;
		}
		
		var table = $(this); 
		var footerTable;
		
		var settings = $.extend({
			subTotalClass: "subtotal",
			totalClass: "total",
			hasTotal: false
		}, options );
		
		buildTable();
		calculateTotals();
		initializeEvents();
		
		//bind change event to update footer rows on table change
		table.bind("change", function(){
			renderColumns();
		});
		
		function initializeEvents(){
			//any row or cell click events
		};
		
		function buildTable(){
			//build footer rows, attach new table to bottom of this.table
			//count columns and create appropriately
			//style appropriately
			
			var parent = table.parent();
			footerTable = $("<table class=" + table.attr("class") + " cellpadding=\"0\" cellspacing=\"0\"></table>");
			var subTotalRow = $("<tr class=\"subtotal\"></tr>");
			var totalRow = $("<tr class=\"total\"></tr>");
			
			var cell;
			var subtotal = 0;
			
			var columns = table.find("tr:eq(1) > td");
			columns.each( function(index){
				
				//subtotal += parseInt($(this).html());
				width = $(this).outerWidth();
				padding = parseInt($(this).css("paddingLeft")) + parseInt($(this).css("paddingRight")) + 2;
				cell = $("<td width=\""+ (width - padding) +"\">" + subtotal + "</td>");
				
				if ( index == columns.size() - 1 ){
					cell.addClass("last");
					var cellWidth = cell.css("width");
					cell.css("width", parseInt(cellWidth)+1);
				}
				
				subTotalRow.append(cell);
			});
			
			footerTable.append(subTotalRow);
			
			if (settings.hasTotal == true){
				for( var i = 0; i < columns.length; i++ ){
					cell = $("<td>totals</td>");
					totalRow.append(cell);
				}
				footerTable.append(totalRow);
			};
			
			parent.append(footerTable);
		};
		
		function renderColumns(){
			var columns = table.find("tr:eq(1) > td");
			columns.each( function(index){
				if( $(this).is(":hidden")){
					footerTable.find("tr").each(function(){
						$(this).find("td:eq(" + index + ")").animate({opacity:"hide"}, settings.animDelay);
					});
				} else if( $(this).is(":visible")){
					footerTable.find("tr").each(function(){
						$(this).find("td:eq(" + index + ")").animate({opacity:"show"}, settings.animDelay);
					});
				}
			});
		};
		
		function calculateTotals(){
			//for totals:
			//iterate down rows, across columns, populate totals array
			
			var totals = [];
			
			var rows = table.find("tr");
			//iterate down rows
			rows.each( function( i ){
				//iterate across columns in each row
				columns = $(this).find("td");
				columns.each( function( j ){
					var value = $(this).html();
					totals[j] = parseAndSum(value, totals[j]);
				});
			});
				
			for( var i = 0; i < totals.length; i++ ){
				var totalCell = footerTable.find("tr.subtotal > td:eq(" + i + ")");
				totalCell.css({ fontWeight : "bold", borderTop : "3px solid #eee" });
				
				if ( totals[i] != undefined && i != 0){
					format = getFormat(table.find("tr:eq(1) > td:eq("+ i + ")").html());
					totals[i] = prepareTotal(totals[i]);
					totalCell.html(totals[i]);
				} else {
					if ( i == 0 ){
						totalCell.html("Totals").addClass("first align-left");
					} else {
						totalCell.html("");
					}
				}
			}
			
		};
		
		function parseAndSum( value, total ){
			var format = getFormat(value);
			
			if ( format == "percentage" ){
				
				return "n/a";
				
			} else if ( format == "comma" ){
				
				total = prepareValue(total);
				value = value.split(",").join("");
				value = Number(value);
				total += value;
				return total;
				
			} else if ( format == "currency" ){
				
				total = prepareValue(total);
				value = value.replace(/./,"").replace(/$/,"");
				value = Number(value);
				total += value;
				return total;
				
			} else if ( format == "string" ){
				
				//text
				
			}
		};
		
		function prepareValue( value ){
			if ( value == undefined ){
				return 0;
			} else {
				//total = total.split(",").join("");
				return Number(value);
			}
		};
		
		function prepareTotal( value ){
			switch(format){
			case "comma" :
				value = addCommas(value);
				break;
			case "currency" : 
				value = formatCurrency(value);
				break;
			}
			
			return value;
		};
		
		function getFormat( value ){
			if ( value.search("%") != -1 ){
				return "percentage";
			} else if ( value.search(",") != -1 ){
				return "comma";
			} else if ( value.search("$") != -1 ){
				return "currency";
			} else {
				return "string";
			}
		};

		function update( tableBody, data ){
			tableBody.find("tr").remove();
			tableBody.append( data );
		};
		
		//---------------------------------- formatting functions  ----------------------------------- 
		
		function addCommas(nStr)
		{
			nStr += '';
			x = nStr.split('.');
			x1 = x[0];
			x2 = x.length > 1 ? '.' + x[1] : '';
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1)) {
				x1 = x1.replace(rgx, '$1' + ',' + '$2');
			}
			return x1 + x2;
		};
		
		function formatCurrency(amount)
		{
			var i = parseFloat(amount);
			if(isNaN(i)) { i = 0.00; }
			var minus = '';
			if(i < 0) { minus = '-'; }
			i = Math.abs(i);
			i = parseInt((i + .005) * 100);
			i = i / 100;
			s = new String(i);
			if(s.indexOf('.') < 0) { s += '.00'; }
			if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
			s = minus + s;
			return "$" + s;
		};

	};
	
})(jQuery);