/* 
 * jQuery - Collapser - Plugin v1.0
 * http://www.aakashweb.com/
 * http://www.aakashweb.com/resources/pages/demos/jquery-collapser/
 * Copyright 2010, Aakash Chakravarthy
 * Released under the MIT License.
 */

(function($){
    $.fn.collapser= function(options, beforeCallback, afterCallback) {
        
        var defaults = {
            target: 'next',
			targetOnly: null,
            effect: 'slide',
			changeText: true,
			expandHtml: 'Expand',
			collapseHtml: 'Collapse',
			expandClass: '',
			collapseClass:''
        };
        
        var options = $.extend(defaults, options);
		
		var expHtml,collHtml, effectShow, effectHide;
		
		if(options.effect == 'slide'){
			effectShow = 'slideDown';
			effectHide = 'slideUp';
		}else{
			effectShow = 'fadeIn';
			effectHide = 'fadeOut';
		}
		
		if(options.changeText == true){
			expHtml = options.expandHtml;
			collHtml = options.collapseHtml;
		}
		
		function callBeforeCallback(obj){
			if(beforeCallback !== undefined){
				beforeCallback.apply(obj);
			}
		}
		
		function callAfterCallback(obj){
			if(afterCallback !== undefined){
				afterCallback.apply(obj);
			}
		}
		
		function hideElement(obj, method){
			callBeforeCallback(obj);
			if(method == 1){
				obj[options.target](options.targetOnly)[effectHide]();
				obj.html(expHtml);
				obj.removeClass(options.collapseClass);
				obj.addClass(options.expandClass);
			}else{
				$(document).find(options.target)[effectHide]();
				obj.html(expHtml);
				obj.removeClass(options.collapseClass);
				obj.addClass(options.expandClass);
			}
			callAfterCallback(obj);
		}
		
		function showElement(obj, method){
			callBeforeCallback(obj)
			if(method == 1){
				obj[options.target](options.targetOnly)[effectShow]();
				obj.html(collHtml);
				obj.removeClass(options.expandClass);
				obj.addClass(options.collapseClass);
			}else{
				$(document).find(options.target)[effectShow]();
				obj.html(collHtml);
				obj.removeClass(options.expandClass);
				obj.addClass(options.collapseClass);
			}
			callAfterCallback(obj);
		}
		
		function toggleElement(obj, method){
			if(method == 1){
				if(obj[options.target](options.targetOnly).is(':visible')){
					hideElement(obj, 1);
				}else{
					showElement(obj, 1);
				}
			}else{
				if($(document).find(options.target).is(':visible')){
					hideElement(obj, 2);
				}else{
					showElement(obj, 2);
				}
			}
		}
		
		return this.each(function(){
		   
		   if($.fn[options.target] && $(this)[options.target]()){
				$(this).toggle(function(){		
					toggleElement($(this), 1);
				},function(){
					toggleElement($(this), 1);
				});	
				
		   }else{
			   
			   $(this).toggle(function(){
					toggleElement($(this), 2);
				},function(){
					toggleElement($(this), 2);
				});
		   }
		   
		   // Initialize  
		   if($.fn[options.target] && $(this)[options.target]()){
				if($(this)[options.target]().is(':hidden')){
					$(this).html(expHtml);
					$(this).removeClass(options.collapseClass);
					$(this).addClass(options.expandClass);
				}else{
					$(this).html(collHtml);
					$(this).removeClass(options.expandClass);
					$(this).addClass(options.collapseClass);
				}
			}else{
				if($(document).find(options.target).is(':hidden')){
					$(this).html(expHtml);
				}else{
					$(this).html(collHtml);
				}
			}
		   
        });
    };
    
})(jQuery);
