/**
 * Item Toggler allows to show/hide individual and all items.
 * @author NOSE
 *
 * @requires jquery.js 
 * @example $("#menu").itemToggler({classShowHide:"showhide",classToggler:"toggler",classCollapsed:"collapsed"}); 
 * @before  
	<div id="menu">
	<a href="#" class="showhide">show all</a>
	<h3 class="toggler collapsed"><a href="#" >link a</a></h3>
	<dl style="display: none;" class="item">
	content a
	</dl>
	<h3 class="toggler collapsed"><a href="#">link b</a></h3>
	<p>something inbetween</p>
	<p style="display: none;" class="item">content b</p>
	<h3 class="toggler collapsed"><a href="#">link c</a></h3>
	<p style="display: none;" class="item"> content c</p>
	</div>
 *
 * @option classShowHide 	Class name show hide link.
 * @option classToggler 	Class name toggler.
 * @option classItem 		Class name item.
 * @option classCollapsed 	Class name collapsed.
 * @option classExpanded 	Class name show all.
 * @option msgShowAll 		Message show all.
 * @option msgHideAll 		Message hide all.
 * @option slideDownSpeed 	Values slow or fast.
 * @option slideUpSpeed 	Values slow or fast.
 * @option expanded			Initially expanded items (e.g. 0;2;5;).
 * @option accordion 		Set to true for accordion behaviour.
 * 
 * 
 * @version 1.1.1	fix for expanding table rows
 * @version 1.1.0	added accordion behaviour
 * @version 1.0.0	initial version			
 */
jQuery.fn.itemToggler = function(op) {	
	// defaults
	var defaults =  {
			classShowHide: "showhide",
			classToggler: "toggler",
			classItem: "item",			
			classCollapsed: "collapsed",
			classExpanded: "expanded",
			msgShowAll: "show all",
			msgHideAll: "hide all",
			slideDownSpeed: "slow",
			slideUpSpeed: "slow",
			slideAll: false,
			slideItem: true,
			expanded:null,
			accordion:false
	};
	jQuery.extend(defaults, op);
	
	// params
	var sAll = true;
	var showHideAll = new Array();
	jQuery(this).find("."+defaults.classShowHide).each(function(i){
		jQuery(this).bind("click", toggleAll);	
		showHideAll.push(this);
	});	
	
	// items
	var togglers = new Array();
	var items = new Array();
	var expanded = new Array();
	jQuery(this).find("."+defaults.classItem).each(function(i){
		// store
		items.push(this);
		// hide
		jQuery(this).css("visibility","visible");
		jQuery(this).hide();
	});
	jQuery(this).find("."+defaults.classToggler).each(function(i){
		// store
		jQuery(this).attr("rel",i.toString());
		togglers.push(this);
		expanded.push(false);
		
		// event
		jQuery(togglers[i]).bind("click",function() {
			// link
			toggleItem((jQuery(this).attr("rel")));
		});
	});	
	
	// initialize
	if (defaults.expanded) {
		var values = defaults.expanded.split(";");
		for (var i = 0; i < values.length; i++) {
			var v = values[i];
			if (v) {
				showItem(v,false);
			}
		}
	}	


	/*
	 * Toggles all items.
	 */
	function toggleAll() {
		if (sAll) {
			showAll();
		}
		else {
			hideAll();
		}
	}
	
	/*
	 * Shows all items.
	 */
	function showAll() {
			// items
			for (var i = 0; i < items.length; i++) {
				if (! expanded[i]) {
				  showItem(i,defaults.slideAll);
				}
			}
		    setShowAll(false);
	}
	/*
	 * Hides all items.
	 */
	function hideAll() {
		// items
		for (var i = 0; i < items.length; i++) {
			if (expanded[i]) {
			  hideItem(i,defaults.slideAll);
			}
		}
		setShowAll(true);
	}
	
	/*
	 * Toggles an item.
	 */
	function toggleItem(i) {
		// item
		if (expanded[i]) {
			hideItem(i,defaults.slideItem);
		}
		else {
			showItem(i,defaults.slideItem);
			
		}
		
		// accordion
		if (defaults.accordion) {
			for (var j = 0; j < items.length; j++) {
				if (j != i && expanded[j]) {
					hideItem(j,defaults.slideItem);
				}
			}
		 }
		
		// check
		if(isAllExpanded()) {
			setShowAll(false);
		}
		if(isAllCollapsed()) {
			setShowAll(true);
		}

	}
	
	/*
	 * Sets the show/hide title.
	 */
	function setShowAll(v) {
		// set html
		if (v) {
			for (var i = 0; i < showHideAll.length; i++) {
				jQuery(showHideAll[i]).html(defaults.msgShowAll);
			}
		}
		else {
			for (var i = 0; i < showHideAll.length; i++) {
				jQuery(showHideAll[i]).html(defaults.msgHideAll);
			}
		}	
		// flag
		sAll = v;
	}
	
	/*
	 * Indicates if all expanded.
	 */
	function isAllExpanded() {
		var allExpanded = true;
		for (var i = 0; i < expanded.length; i++) {
			if (! expanded[i]) {
				allExpanded = false;
				break;
			}			
		}
		return allExpanded;
	}
	
	/*
	 * Indicates if all collapsed.
	 */
	function isAllCollapsed() {
		var allCollapsed = true;
		for (var i = 0; i < expanded.length; i++) {
			if (expanded[i]) {
				allCollapsed = false;
				break;
			}			
		}
		return allCollapsed;
	}
	
	/*
	 * Shows an item.
	 */
	function showItem(i,slide) {
		var t = togglers[i];
		var e = items[i];
		// class
		jQuery(t).removeClass(defaults.classCollapsed);
		jQuery(t).addClass(defaults.classExpanded);
		// content
		if (slide) {
			jQuery(e).slideDown(defaults.slideDownSpeed);
		}
		else {
			jQuery(e).show();
		}
		// item
		expanded[i] = true;
	}
	
	/*
	 * Hides an item.
	 */
	function hideItem(i,slide) {
		var t = togglers[i];
		var e = items[i];
		
		// class
		jQuery(t).addClass(defaults.classCollapsed);
		jQuery(t).removeClass(defaults.classExpanded);
		// content
		if (slide) {
			jQuery(e).slideUp(defaults.slideUpSpeed);
		}
		else {
		    jQuery(e).hide();
		}

		// item
		expanded[i] = false;
	}
  
    // return
    return this;
};