	/*
	 * Accordion 1.6pre - jQuery menu widget
	 *
	 * Copyright (c) 2007 Jörn Zaefferer
	 *
	 * http://bassistance.de/jquery-plugins/jquery-plugin-accordion/
	 *
	 * Dual licensed under the MIT and GPL licenses:
	 *   http://www.opensource.org/licenses/mit-license.php
	 *   http://www.gnu.org/licenses/gpl.html
	 *
	 * Revision: $Id$
	 *
	 */


(function($) {
	
	$.fn.extend({
	    makeAccordion: function(settings) {
	        return this.each(function() {
				$.data(this, "ui-accordion") || $.data(this, "ui-accordion", new $.ui.accordion(this, settings));
	        });
	    },
	    changeAccordion: function(key, value) {
	        return this.trigger(key + ".ui-accordion", [value]);
	    },
	    enableAccordion: function() {
	        return this.trigger("enable.ui-accordion");
	    },
	    disableAccordion: function() {
	        return this.trigger("disable.ui-accordion");
	    },
	    removeAccordion: function() {
	        return this.trigger("remove.ui-accordion");
	    },
	    // deprecated, use makeAccordion instead
	    accordion: function() {
	        return this.makeAccordion.apply(this, arguments);
	    },
	    // deprecated, use changeAccordion("activate", index) instead
	    activate: function(index) {
	        return this.changeAccordion("activate", index);
	    },
	    // deprecated, use removeAccordion instead
	    unaccordion: function() {
	        return this.removeAccordion.apply(this, arguments);
	    }
		
	});
	
	// If the UI scope is not available, add it
	$.ui = $.ui || {};
	
	$.ui.accordion = function(container, settings) {
	   
	   
	    // setup configuration
	    this.settings = settings = $.extend({}, $.ui.accordion.defaults, settings);
	   
	    if ( settings.navigation ) {
	        var current = $(container).find("a").filter(settings.navigationFilter);
	        if ( current.length ) {
	            if ( current.filter(settings.header).length ) {
	                settings.active = current;
	            } else {
	                settings.active = current.parent().parent().prev();
	                current.addClass("current");
	            }
	        }
	    }
	   	
	    // calculate active if not specified, using the first header
	    settings.headers = $(container).find(settings.header);
		settings.active = findActive(settings.headers, settings.active);
		var resultSet;
		if( settings.closePrev)
			resultSet= settings.headers.prev();
		else
		    resultSet= settings.headers.next();
	    if ( settings.fillSpace ) {
			var maxHeight = $(container).parent().height();
	        settings.headers.each(function() {
	            maxHeight -= $(this).outerHeight();
	        });
	        var maxPadding = 0;
	        //settings.headers.prev()
			resultSet.each(function() {
	            maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
	        }).height(maxHeight - maxPadding);
	    } else if ( settings.autoheight ) {
	        var maxHeight = 0;
			
	        //settings.headers.prev().
			resultSet.each(function() {
				
	            maxHeight = Math.max(maxHeight, $(this).outerHeight());
				
	        }).height(maxHeight);
	    }
	
		if( settings.closePrev)
	    	settings.headers.not(settings.active || "").prev().hide();
		else
			settings.headers.not(settings.active || "").next().hide();
		
		if( ! settings.selectedOnChild)
		    settings.active.parent().andSelf().addClass(settings.selectedClass);
		else
		    settings.active.children().eq(0).addClass(settings.selectedClass);
	   
	    $(container)
	    .bind((settings.event || "") + ".ui-accordion", clickHandler)
	    .bind("activate.ui-accordion", activateHandler)
	    .bind("enable.ui-accordion", function() {
	        $.data(this, "ui-accordion").settings.disabled = false;
	    })
	    .bind("disable.ui-accordion", function() {
	        $.data(this, "ui-accordion").settings.disabled = true;
	    })
	    .one("remove.ui-accordion", function() {
	        var settings = $.data(this, "ui-accordion").settings;
	        $(this)
	        .unbind( settings.event + ".ui-accordion" )
	        .unbind( "activate.ui-accordion" )
	        .unbind( "enable.ui-accordion" )
	        .unbind( "disable.ui-accordion" );
			if( settings.closePrev)
				resultSet= settings.headers.prev();
			else
		    	resultSet= settings.headers.next();
			resultSet.css("display", "");
	        if ( settings.fillSpace || settings.autoheight ) {
	            resultSet.css("height", "");
	        }	       
			
	        $.removeData(this, "ui-accordion");
	    });
	};
	
	function scopeCallback(callback, scope) {
	    return function() {
	        return callback.apply(scope, arguments);
	    };
	}
	
	function completed(cancel) {
	    // if removed while animated data can be empty
	    if (!$.data(this, "ui-accordion"))
	        return;
	    var settings = $.data(this, "ui-accordion").settings;
	    settings.running = cancel ? 0 : --settings.running;
	    if ( settings.running )
	        return;
	    if ( settings.clearStyle ) {
	        settings.toShow.add(settings.toHide).css({
	            height: "",
	            overflow: ""
	        });
	    }
	    $(this).trigger("changed.ui-accordion", settings.data);
	}
	
	function toggle(toShow, toHide, data, clickedActive, down) {
	    var settings = $.data(this, "ui-accordion").settings;
	    settings.toShow = toShow;
	    settings.toHide = toHide;
	    settings.data = data;
	    var complete = scopeCallback(completed, this);
	   
	    // count elements to animate
	    settings.running = toHide.size() == 0 ? toShow.size() : toHide.size();
	   
	    if ( settings.animated ) {
	        if ( !settings.alwaysOpen && clickedActive ) {
	            $.ui.accordion.animations[settings.animated]({
	                toShow: jQuery([]),
	                toHide: toHide,
	                complete: complete,
	                down: down,
	                autoheight: settings.autoheight,
					hideHeader : settings.hideHeader
	            });
	        } else {
	            $.ui.accordion.animations[settings.animated]({
	                toShow: toShow,
	                toHide: toHide,
	                complete: complete,
	                down: down,
	                autoheight: settings.autoheight,
					hideHeader : settings.hideHeader
	            });
	        }
	    } else {
	        if ( !settings.alwaysOpen && clickedActive ) {
	            toShow.toggle();
	        } else {
	            toHide.hide();
	            toShow.show();
	        }
	        complete(true);
	    }
	}
	
	function clickHandler(event) {
	    var settings = $.data(this, "ui-accordion").settings;
	    if (settings.disabled)
	        return false;
	   
	    // called only when using activate(false) to close all parts programmatically
	    if ( !event.target && !settings.alwaysOpen ) {
			if( ! settings.selectedOnChild)
		        settings.active.parent().andSelf().toggleClass(settings.selectedClass);
			else
				settings.active.children().eq(0).toggleClass(settings.selectedClass);
	        var toHide;
			if( settings.closePrev)
				toHide = settings.active.prev();
			else
				toHide = settings.active.next();
	        var toShow = settings.active = $([]);
	        toggle.call(this, toShow, toHide );
	        return false;
	    }
	    // get the click target
	    var clicked = $(event.target);
	   
	    // due to the event delegation model, we have to check if one
	    // of the parent elements is our actual header, and find that
	    if ( clicked.parents(settings.header).length )
	        while ( !clicked.is(settings.header) )
	            clicked = clicked.parent();
	   
	    var clickedActive = clicked[0] == settings.active[0];
	   
	    // if animations are still active, or the active header is the target, ignore click
	    if (settings.running || (settings.alwaysOpen && clickedActive))
	        return false;
	    if (!clicked.is(settings.header))
	        return;
	
	    // switch classes
	    //settings.active.parent().andSelf().toggleClass(settings.selectedClass);
		if( ! settings.selectedOnChild)
		   settings.active.parent().andSelf().toggleClass(settings.selectedClass);
		else
			settings.active.children().eq(0).toggleClass(settings.selectedClass);
				
	    if ( !clickedActive ) {
	        //clicked.parent().andSelf().addClass(settings.selectedClass);
			if( ! settings.selectedOnChild)
			   clicked.parent().andSelf().addClass(settings.selectedClass);
			else
			   clicked.children().eq(0).addClass(settings.selectedClass);
	    }

	    // find elements to show and hide
	    var toShow, toHide;
		if(settings.closePrev)
		{
		    toShow = clicked.prev();
	        toHide = settings.active.prev();
		}
		else
		{
			toShow = clicked.next();
	        toHide = settings.active.next();
		}
	    
		var data = [clicked, settings.active, toShow, toHide],
	    down = settings.headers.index( settings.active[0] ) > settings.headers.index( clicked[0] );
	   
	    settings.active = clickedActive ? $([]) : clicked;
	    toggle.call(this, toShow, toHide, data, clickedActive, down );
	
	    return false;
	};
	
	function activateHandler(event, index) {
	    // IE manages to call activateHandler on normal clicks
	    if ( arguments.length == 1 )
	        return;
	    // call clickHandler with custom event
	    clickHandler.call(this, {
	        target: findActive( $.data(this, "ui-accordion").settings.headers, index )[0]
	    });
	};
	
	function findActive(headers, selector) {
	    return selector != undefined
	        ? typeof selector == "number"
	            ? headers.filter(":eq(" + selector + ")")
	            : headers.not(headers.not(selector))
	        : selector === false
	            ? $([])
	            : headers.filter(":eq(0)");
	};
	function myAnim( prop, speed, easing, callback )
	{
		var optall = jQuery.speed(speed, easing, callback);

		return this[ optall.queue === false ? "each" : "queue" ](function(){
			if ( this.nodeType != 1)
				return false;

			var opt = jQuery.extend({}, optall);
			var hidden = jQuery(this).is(":hidden"), self = this;
			
			for ( var p in prop ) {
				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
					return jQuery.isFunction(opt.complete) && opt.complete.apply(this);

				if ( p == "height" || p == "width" ) {
					// Store display property
					opt.display = jQuery.css(this, "display");

					// Make sure that nothing sneaks out
					opt.overflow = this.style.overflow;
				}
			}

			if ( opt.overflow != null )
				this.style.overflow = "hidden";

			opt.curAnim = jQuery.extend({}, prop);
			
			jQuery.each( prop, function(name, val){
				var e = new jQuery.fx( self, opt, name );

				if ( /toggle|show|hide/.test(val) )
					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
				else {
					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
						start = e.cur(true) || 0;

					if ( parts ) {
						var end = parseFloat(parts[2]),
							unit = parts[3] || "px";

						// We need to compute starting value
						if ( unit != "px" ) {
							self.style[ name ] = (end || 1) + unit;
							start = ((end || 1) / e.cur(true)) * start;
							self.style[ name ] = start + unit;
						}

						// If a +=/-= token was provided, we're doing a relative animation
						if ( parts[1] )
							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;

						e.custom( start, end, unit );
					} else
						e.custom( start, val, "" );
				}
			});

			// For JS strict compliance
			return true;
		});
	};
	
	
	$.extend($.ui.accordion, {
	    defaults: {
			selectedOnChild: false,
	        selectedClass: "selected",
	        alwaysOpen: true,
	        animated: 'slide',
	        event: "click",
	        header: "a",
	        autoheight: true,
	        running: 0,
			closePrev: false,
			hideHeader : false,
	        navigationFilter: function() {
	            return this.href.toLowerCase() == location.href.toLowerCase();
	        }
	    },
	    animations: {
	        slide: function(settings, additions) {
	            settings = $.extend({
	                //easing: "swing",
					easing:"easeInQuad",
	                duration: 600,
					hideHeader : false
	            }, settings, additions);
				
				
	            if ( !settings.toHide.size() ) {
									
					if( settings.hideHeader)
					{
						 settings.toShow.prev().fadeOut(settings.duration/2, 
												   function()
												   {																							 
													 settings.toShow.animate({height: "show"}, settings.duration,  settings.complete());														
													
													});	
					}
					else
					{
						settings.toShow.animate({height: "show"}, settings.duration,  settings.complete());
					}
					return;
	            }				  			 	
								
			    var hideHeight = settings.toHide.height(),
	                showHeight = settings.toShow.height(),
	                difference = showHeight / hideHeight;
				
				settings.toShow.css({ height: 0, overflow: 'hidden' }).show();
				settings.toHide.css({ overflow: 'hidden' });
				if( settings.hideHeader)
				{
					settings.toShow.prev().fadeOut(settings.duration/2);							
					settings.toHide.animate({height: 30}, 
										{
											duration: settings.duration,
											step: function(now, fx){
												var current = (hideHeight - now) * difference;
												
												if ($.browser.msie || $.browser.opera) {
													current = Math.ceil(current);
												}
												if( current > showHeight)
													current = showHeight;
												settings.toShow.height( current );													 										
													  													  
											},											
											complete: function(){	
												settings.toHide.height(hideHeight).hide();
												settings.toShow.height(showHeight);		
												settings.toHide.prev().fadeIn(settings.duration/2, settings.complete());																											
																				  
											}
										});
				}
				else
				{
					settings.toHide.animate({height: 'hide'}, 
											{
												duration: settings.duration,
												step: function(now, fx){
													var current = (hideHeight - now) * difference;
													
													if ($.browser.msie || $.browser.opera) {
														current = Math.ceil(current);
													}
													if( current > showHeight)
														current = showHeight;
													settings.toShow.height( current );													 										
																											  
												},											
												complete: function(){	
													if ( !settings.autoheight ) {
														settings.toShow.css("height", "auto");
													}
													settings.toShow.height(showHeight);		
													settings.complete();
												}
											});
				
				}
			    },
	        bounceslide: function(settings) {
	            this.slide(settings, {
	                easing: settings.down ? "bounceout" : "swing",
	                duration: settings.down ? 1000 : 200
	            });
	        },
	        easeslide: function(settings) {
	            this.slide(settings, {
	                easing: "easeinout",
	                duration: 700
	            })
	        }
	    }
	});
	
})(jQuery);
