/*
 * (c) 2011 David Krause, Interaktive Gestaltung
 * http://www.interaktive-gestaltung.de
 */

/**
 * View of the Navigation.
 *
 * @param controller
 * @param naviMainSelector
 * @param naviMetaSelector
 * @param animItems
 */
function NaviView(controller, naviMainSelector, naviMetaSelector, animItems)
{
    var controller = controller;

    var naviMainSelector = naviMainSelector;
    var naviMetaSelector = naviMetaSelector;

    var animItems = animItems;

    var titleButtonsFirstInit = false;

    /**
     * Inits the View.
     */
    this.init = function()
    {
        initCategoryButtons();
    }

    /**
     * Handles the event, when the application is reset.
     * The event also occurs, when the application is inited
     * whith no preselected navi items.
     *
     * Shows the intro animation.
     */
    this.onReset = function()
    {
        this.showIntroAnimation();
    }

    /**
     * Handles the event, when the navi state in the model has changed
     *
     * @param obj Object containing the ids of the active navi elements
     */
    this.onNaviChanged = function(obj)
    {
        var categoryId = obj.category;
        var sectionId = obj.section;
        var titleId = obj.title;

        /*
            Hide all except categories
         */
        dimAllSections();
        hideAllSections();
        dimAllTitles();
        hideAllTitles();

        if (categoryId != 0)
        {
            showSectionsOfCategory(categoryId);
            initSectionButtons(categoryId);
        }

        if (sectionId != 0)
        {
            showTitlesOfSection(categoryId, sectionId);
            initTitleButtons(categoryId, sectionId);
        }

        if (categoryId) highlightCategory(categoryId);
        if (sectionId) highlightSection(categoryId, sectionId);
        if (titleId) highlightTitle(categoryId, sectionId, titleId);
    }

    /**
     * Handles the event, when a title is temporarily set active
     * (i.e. MouseOver)
     *
     * @param obj
     */
    this.onTemporaryActiveTitleChanged = function (obj)
    {
        highlightTitle(obj.category, obj.section, obj.title);
    }

    /**
     * Inits the buttons of category.
     * Category buttons are "photography film ..."
     * and the meta-navi buttons.
     * The buttons are simply numbered consecutively with ids = (1, 2, 3 ...)
     */
    var initCategoryButtons = function ()
    {
        var buttonsMain = $(naviMainSelector + ' ' + 'ul.categories li a');
        var buttonsMeta = $(naviMetaSelector + ' ' + 'ul.categories li a');

        buttonsMain.unbind('click');
        buttonsMeta.unbind('click');

        var id = 1;
        for (var i = 0; i < buttonsMain.length; i++)
        {
            var button = $(buttonsMain[i]);
            bindCategoryButton(button, id);
            id ++;
        }

        // Meta-navi buttons (changed: only vita, others via standardContent)
        for (var i = 0; i < buttonsMeta.length - 3; i++)
        {
            var button = $(buttonsMeta[i]);
            bindCategoryButton(button, id);
            id ++;
        }
    }

    /**
     * Attach the event handlers to a category button.
     *
     * @param button
     * @param id
     */
    var bindCategoryButton = function (button, id)
    {
        button.click(function(event)
        {
            controller.onCategoryButtonClick(id);
            event.preventDefault();
        });
    }

    /**
     * Inits the buttons of section.
     * The buttons are simply numbered consecutively with ids = (1, 2, 3 ...)
     */
    var initSectionButtons = function (cat)
    {
        var buttons = $(naviMainSelector + ' .category' + cat + ' ul.sections li a');
        buttons.unbind('click');

        var id = 1;
        for (var i = 0; i < buttons.length; i++)
        {
            var button = $(buttons[i]);
            bindSectionButton(button, id);
            id ++;
        }
    }

     /**
     * Attach the event handlers to a section button.
     *
     * @param button
     * @param id
     */
    var bindSectionButton = function (button, id)
    {
        button.click(function(event)
        {
            controller.onSectionButtonClick(id);
            event.preventDefault();
        });
    }

    /**
     * Inits the buttons of title.
     * The buttons are simply numbered consecutively with ids = (1, 2, 3 ...)
     */
    var initTitleButtons = function (cat, sect)
    {
        var buttons = $(naviMainSelector + ' .category' + cat + ' div.section' + sect + ' .titles li a');
        buttons.unbind('click');

        var id = 1;
        for (var i = 0; i < buttons.length; i++)
        {
            var button = $(buttons[i]);
            bindTitleButton(button, id);

            // Create newline after the sixth title
            if (id == 6)
            {
                button.parent().addClass('newLine' + cat + sect);

                var titles = $(naviMainSelector + ' .category' + cat + ' div.section' + sect + ' .titles');
                var htmlCode = titles.html();
                // insert br. Note: '<br />' gets converted to <br> by jQuery
                // only insert br if not yet inserted
                if (htmlCode.search(/(<br>)+/) == -1 && htmlCode.search(/(<BR>)+/) == -1)
                    $('<br />').insertAfter('.newLine' + cat + sect);
            }
            id ++;
        }
    }

    /**
     * Attach the event handlers to a title button.
     *
     * @param button
     * @param id
     */
    var bindTitleButton = function (button, id)
    {
        button.click(function(event)
        {
            controller.onTitleButtonClick(id);
            event.preventDefault();
        });

        button.mouseenter(function()
        {
            controller.onTitleButtonMouseenter(id);
        });

        button.mouseleave(function()
        {
            controller.onTitleButtonMouseleave(id);
        });
    }

    /**
     * Highlight a category.
     *
     * @param cat Id of the category
     */
    var highlightCategory = function(cat)
    {
        dimAllCategories();
        var item = getCategory(cat);
        item.addClass('selected');
    }

    /**
     * Dims all categories.
     */
    var dimAllCategories = function()
    {
        $(naviMainSelector + ' ' + 'ul.categories li').removeClass('selected');
        $(naviMetaSelector + ' ' + 'ul.categories li').removeClass('selected');
    }

    /**
     * Highlights a section.
     *
     * @param cat Id of the category
     * @param sect Id of the section
     */
    var highlightSection = function(cat, sect)
    {
        trace("highlightSection cat=" + cat + " sect=" + sect);
        dimAllSections();
        var item = getSectionOfCategory(cat, sect);
        item.addClass('selected');
    }

    /**
     * Dims all sections
     */
    var dimAllSections = function()
    {
        $(naviMainSelector + ' ' + 'ul.sections li').removeClass('selected');
    }

    /**
     * Highlights a title.
     *
     * @param cat Id of the category
     * @param sect Id of the section
     * @param tit Id of the title
     */
    var highlightTitle = function(cat, sect, tit)
    {
        dimAllTitles();
        var item = getTitleOfSection(cat, sect, tit);
        item.addClass('selected');
    }

    /**
     * Dims all titles.
     */
    var dimAllTitles = function()
    {
        $(naviMainSelector + ' ' + 'ul.titles li').removeClass('selected');
    }

    /**
     * Gets a category.
     * Searches in naviMain and naviMeta
     * @param id
     * @returns {Object} The category.
     */
    var getCategory = function(id)
    {
        var naviMetaOffset = 3;
        if (id <= naviMetaOffset)
            return $(naviMainSelector +  ' ul.categories li:eq(' + (id - 1) + ')');
        else
            return $(naviMetaSelector +  ' ul.categories li:eq(' + (id - 1 - naviMetaOffset) + ')');
        //return $(naviMainSelector +  ' ul.categories li:eq(' + (id - 1) + ')' + ',' + naviMetaSelector +  ' ul.categories li:eq(' + (id - 1 - naviMetaOffset) + ')');
        //return $(naviMainSelector +  ' ul.categories li:eq(' + (id - 1) + ')').add(naviMetaSelector +  ' ul.categories li:eq(' + (id - 1 - naviMetaOffset) + ')');
        //return $(naviMainSelector +  ' ul.categories li:eq(' + (id - 1) + ')');
    }

    /**
     * Hides all titles.
     */
    var hideAllTitles = function()
    {
        var titles = getAllTitles();
        titles.hide();
    }

    /**
     * Shows section of given category.
     * @param cat
     */
    var showSectionsOfCategory = function(cat)
    {
        var sections = getSectionsOfCategory(cat);
        sections.show();
    }

    var showTitlesOfSection = function(cat, sect)
    {
        var titles = getTitlesOfSection(cat, sect);
        titles.show();
    }

    var hideAllSections = function()
    {
        var sections = getAllSections();
        sections.hide();
    }

    var getAllTitles = function()
    {
        return $(naviMainSelector + ' ' + 'ul.titles');
    }

    var getAllSections = function()
    {
        return $(naviMainSelector + ' ' + 'ul.sections');
    }

    var getSectionsOfCategory = function(cat)
    {
        return $(naviMainSelector + ' .category' + cat + ' ul.sections');
    }

    var getSectionOfCategory = function(cat, sect)
    {
        return $(naviMainSelector + ' .category' + cat + ' ul.sections li:eq(' + (sect - 1) + ')');
    }

    var getTitlesOfSection = function(cat, sect)
    {
        return $(naviMainSelector + ' .category' + cat + ' div.section' + sect + ' .titles');
    }

    var getTitleOfSection = function(cat, sect, tit)
    {
        return $(naviMainSelector + ' .category' + cat + ' div.section' + sect + ' .titles li:eq(' + (tit - 1) + ')');
    }


    /**
     * Shows the animation of the intro, i.e. the sliding in of the words.
     */
    this.showIntroAnimation = function()
    {
        // items for animation
        var a1 = $(naviMainSelector + ' ' + animItems[0]);
        var a2 = $(naviMainSelector + ' ' + animItems[1]);

        var naviItems = $(naviMainSelector + ' ' + animItems[2]);

        var a3 = naviItems.eq(0);
        var a4 = naviItems.eq(1);
        var a5 = naviItems.eq(2);

        var posOrg1 = a1.position().left;
        var posOrg2 = a2.position().left;
        var posOrg3 = a3.position().left;
        var posOrg4 = a4.position().left;
        var posOrg5 = a5.position().left;
        var START_POS = '-110px';
        var START_OPACITY = '0.0';

        a1.css({ left: START_POS, position: 'absolute', opacity: START_OPACITY });
        a2.css({ left: START_POS, position: 'absolute', opacity: START_OPACITY });
        a3.css({ left: START_POS, position: 'absolute', opacity: START_OPACITY });
        a4.css({ left: START_POS, position: 'absolute', opacity: START_OPACITY });
        a5.css({ left: START_POS, position: 'absolute', opacity: START_OPACITY });

        var DURATION = 750;
        this.doAnimation(a1, posOrg1, DURATION);
        this.doAnimation(a2, posOrg2, DURATION);
        this.doAnimation(a3, posOrg3, DURATION);
        this.doAnimation(a4, posOrg4, DURATION);
        this.doAnimation(a5, posOrg5, DURATION);
    }


    /**
     * Does the actual animation procedere.
     *
     * @param element The element to be animated.
     * @param targetPosition The position to move the element to.
     * @param duration The duration of the animation.
     */
    this.doAnimation = function(element, targetPosition, duration)
    {
        var TARGET_OPACITY1 = 0.6;
        var TARGET_OPACITY2 = 1;

        if ($.browser.msie)
        {
            // simpler animation for ie, because of clearType anti-alias bug
            element.animate({ opacity: TARGET_OPACITY2, left: targetPosition }, duration, 'swing', function()
            {
                this.style.removeAttribute('filter');
            });
        } else
        {
            element.animate({ opacity: TARGET_OPACITY1, left: targetPosition }, duration, 'swing');
            element.fadeTo(duration / 2, TARGET_OPACITY2, 'swing');
        }

    }


}

