/*!
 * Includes jQuery.js
 */



/**
 * LIVE core namespace
 * @namespace  LIVE
 */
var LIVE = {}

/**
 * Classs for toggle-list
 *
 * @param    {String}       listId - name from the container-tag in jQuery notation
 * @param    {String}       parentTag - parent tagname from a.jsActive for setting the class 'jsActive' also - optional
 * @param    {String}       callback - callback-function, witch will be called after every toggle - optional
 * @returns  {Object}       the API with public members
 */
 LIVE.ToggleList = function(listId, parentTag, callback)
{
    var _instance = null;
    var _root = "";
    var _$r = null;
    var _$a = null;
    var _$c = null;
    var _$p = null;
    var _speed = "fast";
    var _unique = false;
    var _callback = false;


    /* --- public-area [API] -------------------------------------------------------------------- */


    var Public = {

        /**
         * Opens a toggle-list-element
         *
         * @param    {HTMLObject|Array}         index - index from the event-handler object (this)
         *                                      or Array with (indexes)
         * @returns  {Boolean}
         */
        toggle: function(index)
        {
            // toggle multiple lists
            if (index.constructor == Array)
            {
                _toggleByArray(index);
                _observe();
                return;
            }
            index = _$a.index(index);
            if (_unique)
            {
                _toggleUnique(index);
                _observe();
                return;
            }
            _toggle(index);
            _observe();
        },


        /**
         * Speed for the toggle-animation
         *
         * @param    {Mixed}         speed - based on jQuery-speed-handling
         * @returns  {void}
         */
        setSpeed: function(speed)
        {
            _speed = speed;
            return Public;
        },


        /**
         * If "_unique" ist "true", all other list-points will closed, when one is open
         *
         * @param    {Boolean}         value - true or false
         * @returns  {void}
         */
        setUnique: function(value)
        {
            if (value.constructor != Boolean) {throw "Parameter from setUnique must be from type 'Boolean'";}
            _unique = value;
            return Public;
        }
    }


    /* --- private-area [methods] --------------------------------------------------------------- */


    /**
     * Constructor - hides all toggle-list-elements
     *
     * @param    {String}         listId - name from the container-tag in jQuery notation
     * @param    {String}         parentTag - parent tagname from a.jsActive for setting the class 'jsActive' also - optional
     * @param    {Function}       callback - callback-function, witch will be called after every toggle - optional
     */
    function __construct(listId, parentTag, callback)
    {
        if (listId.constructor != String) {throw "Parameter 1 of the ToggleList-constructor must be from type 'String'";}
        if ((parentTag) && parentTag.constructor != String) {throw "Parameter 2 of the ToggleList-constructor must be from type 'String'";}
        if (callback !== undefined) {
            _callback = callback;
        }

        _root = listId;

        // init
        _$r = $(_root);
        _$a = $(_root + " a.jsToggle");
        _$c = $(_root + " .jsToggle:not(a.jsToggle)");
        _$p = (parentTag) ? _$a.parent(parentTag) : false;

        _$a.addClass("jsToggleInactive");
        _$c.hide(0);

        // save instance
        _$r.data(listId, Public);
        _instance = _$r.data(listId);

        // open tags and observe
        _createOnClickEvent()
        _openByCssJsOpen();
        _observe();
    }


    /**
     * Opens all toggle-elements witch has the class name "jsOpen"
     *
     * @returns  {void}
     */
    function _openByCssJsOpen()
    {
        var index = 0;
        _$a.each(function(){
            if ($(this).hasClass("jsOpen"))
            {
                $(this).removeClass("jsOpen");
                $(this).removeClass("jsToggleInactive");
                $(_root + " .jsToggle:not(a.jsToggle):eq("+index+")").show(0);
            }
            index++;
        });
    }


    /**
     * CORE - Toggles one list-point with 'index'
     *
     * @param    {Number}         index - number of the toggle-list-elements, witch sould be toggled
     * @returns  {void}
     */
    function _toggle(index)
    {
        _$c.eq(index).toggle(_speed, _callback);
        _$a.eq(index).toggleClass("jsToggleInactive");
        _$a.eq(index).toggleClass("jsActive");
    }


    /**
     * Close all list-points an toggles the list-point with 'currentIndex'
     *
     * @param    {Number}         currentIndex - number of the toggle-list-elements, witch sould be toggled
     * @returns  {void}
     */
    function _toggleUnique(currentIndex)
    {
        var index = 0;

        _$a.each(function() {
            if (index != currentIndex)
            {
                $(this).addClass("jsToggleInactive");
                $(_root + " .jsToggle:not(a.jsToggle):eq("+index+")").hide(_speed);
            }
            else
            {
                _toggle(index);
            }
            index++;
        });
    }


    /**
     * Opens toggle-list-elements by numbers
     *
     * @param    {Array}         listArray - numbers of the toggle-list-elements, witch sould be open
     * @returns  {void}
     */
    function _toggleByArray(listArray)
    {
        for (var i=0; i<listArray.length; i++)
        {
            _toggle(listArray[i]-1);
        }
    }


    /**
     * Calls all other observe-functions
     *
     * @returns  {void}
     */
    function _observe()
    {
        _observeParentActiveTag();
    }


    /**
     * If 'this._$p' is ture, this function sets for all parent-tags from a.jsToggle the
     * jsActive-class also
     *
     * @returns  {void}
     */
    function _observeParentActiveTag()
    {
        if (_$p === false) {
            return;
        }
        var index = 0;
        _$a.each(function() {
            if ($(this).hasClass("jsToggleInactive"))
            {
                _$p.eq(index).removeClass("jsToggleActiveParent");
            }
            else
            {
                _$p.eq(index).addClass("jsToggleActiveParent");
            }
            index++;
        });
    }


    /**
     * creates the conclick-events on the toggle-a-tags
     */
    function _createOnClickEvent()
    {
         _$a.each(function(){
            $(this).click(function() {
               _instance.toggle(this);
               return false;
            });
        });
    }


    __construct(listId, parentTag, callback);
    return Public;
}

