(function($){
	$.fn.tableCollapse = function(arg){
		
		arg = $.extend( {
				collapsed: -1,
				iconCollapsed: '/icons/resultset_next.png',
				iconOpen: '/icons/resultset_down.png'
			}, arg);

		function init(o, collapsed){
			var $ico = o.find('.tc-state-ico');
			if ($ico.length < 1){
				var obj = o.find('td,th').filter(':first');
				if (obj){
					obj.prepend('<img class="tc-state-ico" src="'
						+ (collapsed ? arg.iconCollapsed : arg.iconOpen)
						+ '" align="left">');
				}
			}
		}
		
		function showHide(o, collapse){
			var obj = o;
			var max_it = 128;
			while (max_it-- && (obj = obj.next())
				&& obj.length>0 && obj[0].tagName.toLowerCase() == 'tr'
				&& !obj.hasClass('th') && !obj.hasClass('splitter') && !obj.hasClass('buttonbar')
			){
				if (collapse){ obj.hide(); } else { obj.show(); }
			}
		}
		
		function updateState(o, collapse){
			if (collapse){
				if (!o.hasClass('collapsed')) o.addClass('collapsed');
			} else {
				if (o.hasClass('collapsed')) o.removeClass('collapsed');
			}
			var $ico = o.find('.tc-state-ico');
			if ($ico.length < 1){
				init(o, collapse);
			} else {
				$ico.attr('src', collapse ? arg.iconCollapsed : arg.iconOpen);
			}
		}
			
		this.each(function(){
			var $t = $(this);

			// disable select
			if($.browser.mozilla){
				$(this).css('MozUserSelect','none');
			}else if($.browser.msie){
				$(this).bind('selectstart',function(){return false;});
			}else{
				$(this).mousedown(function(){return false;});
			}

			var collapse = arg.collapsed < 0
				? ($t.hasClass('collapsed'))
				: (arg.collapsed > 0);
			if (!collapse){
				var $cb = $t.find('input[type=checkbox]');
				if ($cb.length > 0 && !($cb.is(':checked'))){
					collapse = true;
				}
			}
			init($t, collapse);
			if (collapse){
				showHide($t, collapse);
				if (!$t.hasClass('collapsed'))
					$t.addClass('collapsed');
			}
		});
		
		this.click(function(){
			var $t = $(this);
			var collapse = !($t.hasClass('collapsed'));
			if (!collapse){
				var $cb = $t.find('input[type=checkbox]');
				if ($cb.length > 0 && !($cb.is(':checked'))){
					collapse = true;
				}
			}
			updateState($t, collapse);
			showHide($t, collapse);
		});

		return this;
	};
})(jQuery);
