/**
 * Accordeon class
 * Manages configuration and 
 * displaying of the accordeon
 */
function Accordeon() {
//    this.construct(clazz, params);
//}

/**
 * Class itself. The accordeon converts
 * children of a given class to an accordeon
 * element.
 * The parameter Object may contain
 * following items:
 *
 * {
 *     animation    : true               -> whether to animate
 *                                          the transition
 *     handler      : "click"            -> reaction handler
 *                                          to open the layer
 *     elementClass : "element"          -> one accordeon element
 *     arrowClass   : "arrow"            -> nested arrow. gets
 *                                          active on selection
 *     headerClass  : "header"           -> headline of accordeon
 *     contentClass : "accordeonContent" -> content of the element
 *     singleOpen   : true               -> only one layer can be
 *                                          open at a time
 *     duration     : 0.2                -> length of animation
 *     minHeight    : 5                  -> 
 * }
 */
//Accordeon.prototype = {

    this._params = {
        animation   : true,
        handler     : "click",
        elementClass: "element",
        arrowClass  : "arrow",
        headerClass : "header",
        contentClass: "accordeonContent",
        singleOpen  : true,
        duration    : 0.2,
        minHeight   : 5,
        openOnStart : null
    };
    
    this._activeElement = null;
    this._clazz = null;
    this._heights = null,

    /**
     * Constructor.
     * Instantiates the accordeon
     *
     * @param clazz String
     * @param params String
     */
    this.construct = function(clazz, params) {		
        this._clazz = clazz;
        //overwrite params, if given
        if (params != null || params != undefined) jQuery.extend(true, this._params, params);
        this._init();
    };
    
    /**
     * Private initialization
     */
    this._init = function() {
        var elements = $('.' + this._clazz + ' .' + this._params.elementClass + ' .' + this._params.contentClass);
        //hide all the elements underneath the headers, if there is no min-height
        //do this only if there is more than one element
        if (elements.length > 1) {
            if (elements.css('min-height') != "0px" && elements.css('min-height') != "auto") {			
                this._heights = {};
                //remember the heights
                for (var i = 0; i < elements.length; i++) {
                	// add "close" bar at the end of element
                	                  
                  this._heights[$(elements[i]).parent().attr('id')] = $(elements[i]).height();        
                  
                  //hide other elements, activate the first
                  $(elements[i]).parent().find('.' + this._params.arrowClass).addClass("active");
                  this._animateHeight($(elements[i]).parent().attr('id'));
                  
                  var min_height_val = ($(elements[i]).css('min-height')).replace("px", '') - 23 ;
                  //if its high enough show "..." else hide arrow
                  if( $(elements[i]).height() > $(elements[i]).css('min-height').replace("px", '') ){                  	
                  	$(elements[i]).append('<div id="more" style="top:'+min_height_val+'px;" class="bg_bottom font18b DarkGreen"></div>');             		
                	}
                	else{
                		$(elements[i]).parent().find('.' + this._params.arrowClass).hide();	
                	}
                }
            } else {
            	if(this._params.openOnStart != null){
            		for (var i = 0; i < elements.length; i++){
            			if(i != this._params.openOnStart){            				
            				$(elements[i]).hide();	
            			}
            			else{            				
            				this._activeElement = $(elements[i]);
            				$(elements[i]).parent().find('.' + this._params.arrowClass).addClass("active");
            			}
            		}
            	}
            	else{
                elements.hide();
              }
            }
            //activate the headers
            var header = $('.' + this._clazz + ' .' + this._params.elementClass + ' .' + this._params.headerClass);     
            //if there is an arrow included
            if (header.find('.' + this._params.arrowClass).length > 0) {
                header.bind(this._params.handler, jQuery.proxy(this._headerActivated, this));     
            } else {
                //bind the arrow in the content class
                $('.' + this._clazz + ' .' + this._params.contentClass + ' .' + this._params.arrowClass).bind(this._params.handler, jQuery.proxy(this._headerActivated, this)); 
            }
        } else {
            //disable those arrows
            $('.' + this._clazz + ' .' + this._params.headerClass + ' .' + this._params.arrowClass).hide();
        }
    };
    
    /**
     * Header activated, open the element
     *
     * @param ev Mouse Event
     */
    this._headerActivated = function(ev) {
    	
        var contentParent = $(ev.target).parent();
        
        if (!$(ev.target).hasClass(this._params.headerClass)) {
            contentParent = contentParent.parent();
        }
        var content = contentParent.find('.' + this._params.contentClass);        
        //in case we have a minimum height, call another function for convenience
        if (this._heights != null) {
            this._animateHeight(contentParent.attr('id'));
        } else {
            //if active and in settings defined, close the older element
            if (this._activeElement != null && this._params.singleOpen) {
                this._activeElement.slideUp(this._params.duration * 1000);
                this._activeElement.parent().find('.' + this._params.arrowClass).removeClass("active");
            }
            else if(this._activeElement != null){
            		content.slideUp(this._params.duration * 1000);
                contentParent.find('.' + this._params.arrowClass).removeClass("active");
            }
            //if opened, toggle it, change arrow graphics
            if (content.height() < this._params.minHeight || content.css('display') == "none") {
                content.slideDown(this._params.duration * 1000);
                contentParent.find('.' + this._params.arrowClass).addClass("active");
            } else {
                content.slideUp(this._params.duration * 1000);
                contentParent.find('.' + this._params.arrowClass).removeClass("active");
            }
            //activate
            this._activeElement = content;
        }
    };
    
    /**
     * Animates the height of the element to match the min-
     * height (or the base height)
     *
     * @param value String the parent elements id
     */
    this._animateHeight = function(value) {
        var contentParent = $('#' + value);
        var content = contentParent.find('.' + this._params.contentClass);
        //deflate?
        if (contentParent.find('.' + this._params.arrowClass).hasClass("active")) {
            content.animate({height: content.css('min-height')}, this._params.duration * 1000);
            contentParent.find('.' + this._params.arrowClass).removeClass("active");
            contentParent.find('#more').show();
        } else {
            content.animate({height: this._heights[contentParent.attr('id')]}, this._params.duration * 1000); 
            contentParent.find('.' + this._params.arrowClass).addClass("active");
            contentParent.find('#more').hide();          
        }
    };
}
