/*
 * TODO:
 * FIXED: 1. fix scoping issue with 'maintainState' function -> binding does not maintainState: when there are 2+ instances on a page the
 * 		table and filter container objects are overwritten.
 * 2. inefficient callback in 'toggleColumn' -> callback is rendered multiple times, should only be once
 */

;(function($){
	
	$.fn.customColumns = function( options ){
		
		//support multiple instances
		if ( this.length > 1 ){
			this.each(function(){ $(this).customColumns(options); });
			return this;
		}
		
		var table = $(this);
		
		var settings = $.extend({
			defaultHidden:		[],
			filters:			[],
			filterContainer: 	$("#" + table.attr("id") + "_filters"),
			checkboxClass:		"table-filter-checkbox",
			selectedClass:		"selected",
			animDelay:			400
		}, options );
		
		initializeFilters();
		initializeTable();
		
		//onchange, reset state
		table.bind("change", function(event){
			maintainState();
		});
		
		//functions
		
		function initializeTable(){
			if ( settings.defaultHidden.length >= 0 ){
				for ( var i = 0; i < settings.defaultHidden.length; i++ ){
					settings.filterContainer.find("li."+settings.defaultHidden[i]).click();
				}
			}
		};
		
		function initializeFilters(){
			if ( settings.filters.length == 0 ){
				table.find("th").each(function(){
					settings.filters[ settings.filters.length ] = $(this).html();
				});
			}
			
			buildFilters();
		};
		
		function buildFilters(){
			var ul = $("<ul></ul>");
			var li = null;
			var div = null;
			var text = null;
			var input = null;
			for( var i = 0; i < settings.filters.length; i++ ){
				li = 	$("<li class="+i+"></li>");
				//AUGMENTED THIS LINE FOR CHECKBOX
				div = 	$("<div class=" + settings.checkboxClass + "></div>");
				input = $("<input class=\""+i+"\" type=\"checkbox\" checked=\"checked\"></input>");
				textDiv = $("<div class=\"text\"></div>");
				textDiv.html(settings.filters[i]);
				div.append(input);
				div.append(textDiv);
				div.appendTo(li);
				li.appendTo(ul);
			}
			ul.find("input").click(function(event){
				event.stopPropagation();
				var checked = $(this).attr("checked");
				$(this).attr("checked", !checked);
				$(this).parent().parent().click();
			});
			ul.find("li").click(function(){
				toggleClick($(this), $(this).attr("class").split(" ").slice(0,1));
			});
			ul.appendTo(settings.filterContainer);
		};
		
		function toggleClick(obj, index){
			obj.find("." + settings.checkboxClass).toggleClass(settings.selectedClass);
			//AUGMENTED THIS LINE FOR CHECKBOX
			if ( obj.attr("type") == "checkbox" ){
				obj = obj.parent().parent();
			} else {
				var checked = obj.find("input").attr("checked");
				obj.find("input").attr("checked", !checked );
			}
			toggleColumn(obj, index);
		};
		
		function toggleColumn(obj, index){
			var rows = table.find("tr");
			var state = null;
			if ( table.find("th:eq("+index+")").is(":visible") ){
				state = "hide";
			} else {
				state = "show";
			}
			table.find("th:eq("+index+")").animate( {opacity: state}, settings.animDelay );
			rows.each(function(){
				$(this).find("td").eq(index).animate( {opacity: state}, settings.animDelay, function(){ table.change();} );
			});
		};
		
		function maintainState(obj){
			//assign filters properly
			var hidden = [];
			var visible =[];
			
			//iterate over the filters to grasp the state of the columns
			settings.filterContainer.find("li").each(function(index){
				if($(this).find("div").hasClass(settings.selectedClass)){
					hidden[hidden.length] = $(this).attr("class").split(" ").slice(0,1);
				} else {
					visible[visible.length] = $(this).attr("class").split(" ").slice(0,1);
				}
			});
			
			var rows = table.find("tr");
			
			//hide the columns that should be hidden
			for(var i = 0; i < hidden.length; i++){
				rows.each(function(){
					$(this).find("td").eq(hidden[i]).hide();
				});
			}
			
			//show the columns that should be visible
			for(var i = 0; i < visible.length; i++){
				rows.each(function(){
					$(this).find("td").eq(visible[i]).show();
				});
			}
		};
	};
	
})(jQuery);