// Author: Jerome Clyde C. Bulanadi

jQuery.fn.scrollableFixedHeaderTable = scrollableFixedHeaderTable;

sfht = {};
function scrollableFixedHeaderTable(widthpx, heightpx, showSelect, cookie, headerRowSize) {
	/* table initialization */
	if (!jQuery(this).hasClass('scrollableFixedHeaderTable'))
		return;
	var $this = jQuery(this);
	/* fix width for tables witout width attribute */
	$this.attr('width', $this.width());

	$this.wrap('<div style="text-align: left"></div>');
	$this.parent().before('<div class="noDivBounds"><div class="sfhtColumnSelectButton_unPressed" title="Select Columns"></div><div class="sfhtColumnSelect"></div></div>')

 	headerRowSize = headerRowSize ? headerRowSize - 1: 0;
	headerRowSize = Math.floor(headerRowSize < 0 ? 0 : isNaN(headerRowSize) ? 0 : headerRowSize) ;

	var $parentDiv = $this.parent();
	var $fixedHeaderHtml = sfht.cloneHeader($parentDiv, headerRowSize);
	var $srcTableHtml = $parentDiv.html();

	$this.before('<table cellspacing="0" cellpadding="0" class="sfhtTable"><tr><td><div class="sfhtHeader"></div></td></tr><tr><td><div class="sfhtData"></div></td></tr></table>');
	$parentDiv.find('div:nth(0)').html($fixedHeaderHtml);
	$parentDiv.find('div:nth(1)').html($srcTableHtml);

	var headerId = $this.attr('id') + '_header';
	var $sfhtHeader = $parentDiv.find('.sfhtHeader');
	var $sfhtTable = $sfhtHeader.find('table').attr('id', headerId);

	$this.remove();

	var $sfhtData = $parentDiv.find('.sfhtData');
	$sfhtData.height(heightpx).width(widthpx);
	var $mainTable = $sfhtData.find('table');
	var mainTableId = $mainTable.attr('id');
	
	/* synchronized scrolling */
	$sfhtData.scroll(function() {
		$sfhtHeader.scrollLeft(jQuery(this).scrollLeft());
	});
	
	/* adjustments */
	sfht.adjustTables($sfhtTable, $mainTable, headerRowSize);
	sfht.adjustHeader($sfhtHeader, $sfhtData, $mainTable, headerRowSize);

	if (!showSelect) {
		$parentDiv.prev().remove();
		return;
	}
	
	/* column select check boxes */
	$parentDiv.prev().find('div:nth(0)').attr('id', mainTableId + '_columnSelectButton');
	$parentDiv.prev().find('div:nth(1)').attr('id', mainTableId + '_columnSelect');
	
	
	sfht.loadColumnSelect(jQuery(sfht.getColumnSelect(mainTableId)), $sfhtHeader, mainTableId, $sfhtData, $mainTable, cookie);
	
	var $columnSelect = sfht.getColumnSelect(mainTableId);
	var $columnSelectButton = sfht.getSelectButton(mainTableId);
	
	$columnSelectButton.toggle(function() {
		$columnSelect.show(250);
		$columnSelectButton.attr('class','sfhtColumnSelectButton_Pressed');
		}, function() {
			$columnSelect.hide(250);
			$columnSelectButton.attr('class','sfhtColumnSelectButton_unPressed');
	});	
	
	$columnSelect.hide();
	
	/* cookie */
	if (cookie == null || cookie == '') {
		return;
	}
	var cSize = $sfhtHeader.find('td, th').length;
	if (cSize == 0) {
		return;
	}
	
	var storedCookie = jQuery.cookie(cookie);
	if (storedCookie) {
		// synch the size
		storedCookie = storedCookie.substring(0, cSize);
		for (var index = 0; index < cSize; index++) {
			var indexState = parseInt(storedCookie.charAt(index));
			if (indexState != 1) {
				sfht.hideColumn(mainTableId, index);
				$columnSelect.find('input:nth(' + index + ')').removeAttr('checked');
			}
		}
	} else { // make new cookie
		var initState = sfht.fillState(cSize);
		jQuery.cookie(cookie, initState);
	}
}

sfht.loadColumnSelect = function ($container, $sfhtHeader, mainTableId, $sfhtData, $mainTable, cookie) {
	var myInnerHtml = "<ul>";
	$sfhtHeader.find('td, th').each(function(index) {
		myInnerHtml += '<li><input type="checkbox" class="columnCheck" checked="checked">' + jQuery(this).text() + '</input></li>';
	});
	myInnerHtml += '</ul>';
	$container.html(myInnerHtml);
	$container.find('.columnCheck').each(function(index) {
		var $this = jQuery(this);
		$this.click(function() {
			var checked = $this.attr('checked');
			if (!checked) {
				sfht.hideColumn(mainTableId, index);
				if (cookie != null && cookie != '') {
					var cookieStr = jQuery.cookie(cookie);
					cookieStr = replaceOneChar(cookieStr, '0', index + 1);
					jQuery.cookie(cookie, cookieStr);
				} 
			} else {
				sfht.showColumn(mainTableId, index);
				if (cookie != null && cookie != '') {
					var cookieStr = jQuery.cookie(cookie);
					cookieStr = replaceOneChar(cookieStr, '1', index + 1);
					jQuery.cookie(cookie, cookieStr);
				} 
			}
			sfht.adjustHeader($sfhtHeader, $sfhtData, $mainTable);
		});
	});
}

sfht.hideColumn = function(id, index) {
	var $mainTable = jQuery('table[id=' + id + "]");
	var $headerTable = sfht.getFixedHeader(id);
	$mainTable.find('tr').each(function() {
		//jQuery(this).find('td:nth(' + index + ')').hide();
		jQuery(jQuery(this).find('td,th')[index]).hide();
	});
	$headerTable.find('tr').each(function() {
		//jQuery(this).find('td:nth(' + index + ')').hide();
		jQuery(jQuery(this).find('td,th')[index]).hide();
	});
	var jqKey = sfht.getSfhtVar(id);
	var lastWidth = sfht[jqKey]['lastWidth'];
	var indexWidth = sfht[jqKey]['tdWidths'][index];
	lastWidth -= indexWidth;
	sfht[jqKey]['lastWidth'] = lastWidth;
	$mainTable.width(lastWidth);
	$headerTable.width(lastWidth);
}

sfht.showColumn = function (id, index) {
	var $mainTable = jQuery('table[id=' + id + "]");
	var $headerTable = sfht.getFixedHeader(id);
	$mainTable.find('tr').each(function() {
		//jQuery(this).find('td:nth(' + index + ')').show();
		jQuery(jQuery(this).find('td,th')[index]).show();
	});
	$headerTable.find('tr').each(function() {
		//jQuery(this).find('td:nth(' + index + ')').show();
		jQuery(jQuery(this).find('td,th')[index]).show();
	});
	var jqKey = sfht.getSfhtVar(id);
	var lastWidth = sfht[jqKey]['lastWidth'];
	var indexWidth = sfht[jqKey]['tdWidths'][index];
	lastWidth += indexWidth;
	sfht[jqKey]['lastWidth'] = lastWidth;
	$mainTable.width(lastWidth);
	$headerTable.width(lastWidth);
}

sfht.adjustHeader = function($sfhtHeader, $sfhtData, $mainTable) {
	var containerWidth = $sfhtData.width();
	var containerInnerWidth = $sfhtData.innerWidth();
	var scrollBarSize = containerWidth - containerInnerWidth;
	var dataTableWidth = $mainTable.width();

	if (!(jQuery.browser.mozilla || jQuery.browser.msie || jQuery.browser.opera)) {
		containerInnerWidth = dataTableWidth >= containerWidth ? containerWidth - 17 : containerWidth;
	}

	if (dataTableWidth >= containerInnerWidth) {
		$sfhtHeader.width(containerInnerWidth);
	} else {
		$sfhtHeader.width(dataTableWidth);
	}
}


sfht.adjustTables = function($sfhtTable, $mainTable, headerRowSize) {
	var tdWidthArr = new Array();
	var adjTableWidth = 0;

	var totalWidth = 0;
	var idAdjWidth = sfht.getSfhtVar($mainTable.attr('id'));

	//var id = '#' + $mainTable.attr('id'); // IE compatibility
	var id = $mainTable.attr('id');
	//var queryStr = id + ' tr:nth(0) td';
	var idPrefix = 'table[id=' + id + '] tr:lt(' + (headerRowSize + 1) + ')';
	jQuery(idPrefix).find('td, th').each(function(index) {
		var $this = jQuery(this);
		var actualWidth = parseInt($this.width());
		var attrWidth = parseInt($this.attr('width'));
		var plusWidth = attrWidth > actualWidth ? attrWidth : actualWidth;
		totalWidth += plusWidth;
		tdWidthArr[index] = plusWidth;
		$this.width(plusWidth);
		$sfhtTable.find('td:nth(' + index + '), th:nth(' + index + ')').width(plusWidth);
	});
	
	adjTableWidth = totalWidth;
	// $sfhtTable.width(totalWidth);
	// $mainTable.width(totalWidth);
	
	/* Register this variable to sfht globals */
	sfht[idAdjWidth] = {'lastWidth': adjTableWidth, 'tdWidths': tdWidthArr};
}

sfht.getSfhtVar = function(id) {
	return id + 'Widths';
}

sfht.getSelectButton = function(id) {
	return(jQuery('div[id=' + id + '_columnSelectButton]'));
}

sfht.getColumnSelect = function(id) {
	var selector = '';
	return(jQuery('div[id=' + id + '_columnSelect]'));
}

sfht.getFixedHeader = function(id) {
	return (jQuery('table[id=' + id + '_header]'));
}

sfht.fillState = function (i) {
	  if (i == 0) {
	    return;
	}
	state = '';
	for (var x = 0; x < i; x++) {
	    state += '1';
	}
	return state ;
}

sfht.loadAttributes = function(dest, source) {
	var attributes = jQuery(source).listAttrs();
	jQuery(attributes).each(function(){
		var at = this + '';
		jQuery(dest).attr(at, jQuery(source).attr(at));
	});
}

sfht.cloneHeader = function(parentDiv, headerRowSize) {
	var rowIndex = headerRowSize;
	if (jQuery.fn.listAttrs) {
	  var $container = jQuery("<div><table><thead></thead></table></div>");
		var $clone = $container.find('table:eq(0)');
		var tableNode = jQuery(parentDiv).children().first();
		sfht.loadAttributes($clone,tableNode);
		sfht.loadAttributes($clone.children().first(),tableNode.children().first());

		var $thead = $clone.find('thead');
		for (var _i = 0; _i <= rowIndex; _i++) {
			var $rowHeaderNode = tableNode.children().first().children(':nth(' + _i + ')');
			var $cloneRow = jQuery('<tr></tr>');
			sfht.loadAttributes($cloneRow,$rowHeaderNode);
			$cloneRow.html($rowHeaderNode.html());
			$cloneRow.appendTo($thead);
		}
	  return $container.html();
	} else {
		var $cloned = jQuery(parentDiv).clone();
		$cloned.children().first().children().children('tr:gt(' + headerRowSize + ')').remove();
		return $cloned.html();
	}
}

function replaceOneChar(s,c,n){
	var re = new RegExp('^(.{'+ --n +'}).(.*)$','');
	return s.replace(re,'$1'+c+'$2');
};



