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

/**
 * Model of the navigation.
 *
 * The model stores the ids of the current active category, section and title of the application.
 * Depending on changes of these ids, the model sets the state of the application.
 *
 * Structure:
 *
 * category - photography, film, news
 * section - corporate, editorial, portrait ...
 * title - harlem, germans, artist ...
 *
 * states: slideshow, photoindex ...
 *
 */

function Model()
{
    var _this = this;

    /*
    The current active ids
     */
    var category = 0;
    var section = 0;
    var title = 0;

    /*
    The current state
     */
    var state;

    // Previous active elements
    var categoryPrev = -1;
    var sectionPrev = -1;
    var titlePrev = -1;

    var temporaryActiveTitle = 0; // for mouseover/out effects
    var infoText = 0; // the current infoText


    // The categories
    this.CAT_PHOTO = 1;
    this.CAT_FILM = 2;
    this.CAT_NEWS = 3;

    this.CAT_VITA = 4;
    this.CAT_CONTACT = 5;
    this.CAT_IMPRINT = 6;

    // The different states
    this.SLIDESHOW = 'slideshow';
    this.PHOTOINDEX = 'photoindex';
    this.PHOTOSERIES = 'photoseries';
    this.FILMINDEX = 'filmindex';
    this.FILMDETAIL = 'filmdetail';
    this.NEWS = 'news';
    this.VITA = 'vita';
    this.CONTACT = 'contact';
    this.IMPRINT = 'imprint';

    /**
     * Id of page, where Ajax calls are handled
     */
    var AJAX_PAGE_ID = 1;
    var AJAX_PAGE_TYPENUM = 100;

    var PI_NAME = 'tx_igfpi_main';

    /**
     * Map the page ids of typo3 to the ids of the model.
     * This is necessary, since the ids of the model are simply numbered consecutively
     * an are not resembling the ids of typo3.
     */

    // Map the page ids of typo3 to the text pages vita, contact...
    var PAGE_IDS = new Object();
    PAGE_IDS[this.VITA] = 10;
    PAGE_IDS[this.CONTACT] = 11;
    PAGE_IDS[this.IMPRINT] = 12;

    // Map the page ids of typo3 to the categorys and sections
    var CAT_SECT_PAGE_IDS = new Array();
    CAT_SECT_PAGE_IDS[1] = new Array();
    CAT_SECT_PAGE_IDS[2] = new Array();
    CAT_SECT_PAGE_IDS[1][1] = 3; // category 1 / section 1 -> page id of typo3 = 3
    CAT_SECT_PAGE_IDS[1][2] = 4;
    CAT_SECT_PAGE_IDS[1][3] = 5;
    CAT_SECT_PAGE_IDS[2][1] = 7;
    CAT_SECT_PAGE_IDS[2][2] = 8;


    // used for partially disabling while deeplinking
    this.disableSlideshow = false;
    this.disableIndexes = false;

    /**
     * Inits the model.
     *
     * @param {Array} naviIds Contains the ids of the category, section, title
     */
    this.init = function(naviIds)
    {

        if (naviIds[0] || naviIds[1] || naviIds[2])
        {
            // If deeplink contains changed section, disable slideshow
            if (naviIds[1])
            {
                this.disableSlideshow = true;
            }

            // If deeplink contains changed title, disable slideshow and index pages
            if (naviIds[2])
            {
                this.disableSlideshow = true;
                this.disableIndexes = true;
            }

            // simulate clicks
            _this.changeNavi(naviIds[0], 0, 0);
            _this.changeNavi(naviIds[0],naviIds[1], 0);
            //_this.changeNavi(naviIds[0],naviIds[1],naviIds[2]);
            if (naviIds[2]) _this.changeNavi(naviIds[0],naviIds[1],naviIds[2]);

            this.disableSlideshow = false;
            this.disableIndexes = false;
        } else
        {
            resetNavi();
        }
    }

    /**
     * Resets the navigation.
     */
    var resetNavi = function()
    {
        _this.changeNavi(0, 0, 0);
    }

    /**
     * Changes the navigation.
     *
     * @param categoryNew The new category
     * @param sectionNew The new section
     * @param titleNew The new title
     */
    this.changeNavi = function(categoryNew, sectionNew, titleNew)
    {

        categoryPrev = category;
        sectionPrev = section;
        titlePrev = title;

        // keep the current values, if param contains no new value
        category = categoryNew || category;
        section = sectionNew || section;
        //title = titleNew || title;
        title = titleNew;

        trace("changeNavi c=" + category + " s=" + section + " t=" + title);
        // if category has changed, reset sections and titles
        if (category != categoryPrev)
        {
            section = 0;
            title = 0;
        }

        // if section has changed, reset title
        if (section != sectionPrev)
        {
            title = 0;
        }

        updateState();

        $(_this).trigger({type: 'naviChanged', category: category, section: section, title: title});
    }

    /**
     * Sets the temporary active title.
     * Useful for mouseover/out events, e.g. called from ThumbIndex.
     *
     * @param id
     */
    this.setTemporaryActiveTitle = function (id)
    {
        temporaryActiveTitle = id;
        $(_this).trigger({type: 'temporaryActiveTitleChanged', category: category, section: section, title: temporaryActiveTitle});
    }

    /**
     * Sets the infoText.
     * Useful for mouseover/out events of title buttons and thumbs
     *
     * @param id
     */
    this.setInfoText = function (id)
    {
        infoText = id;
        $(_this).trigger({type: 'infoTextChanged', id: id});
    }


    /**
     * Updates the state.
     *
     * The state is adjusted depending on changes in category, section and title.
     * If needed, an event to change the content is triggered.
     */
    var updateState = function()
    {
        var stateOrg = state;
        var changeContent = false;

        // Slideshow
        if (!_this.disableSlideshow && (category == 0 || (category != categoryPrev && (category == _this.CAT_PHOTO || category == _this.CAT_FILM)) ))
        {
            state = _this.SLIDESHOW;
        }
        // States for "photography"
        else if (category == _this.CAT_PHOTO)
        {
            if (!_this.disableIndexes && section != 0 && (section != sectionPrev || (section == sectionPrev && !title) ))
            {
                state = _this.PHOTOINDEX;
                changeContent = true; //always change content here, regardless of state change
            } else if (title != titlePrev)
            {
                state = _this.PHOTOSERIES;
                changeContent = true; // always change content here, regardless of state change
            }
        }
        // States for "film"
        else if (category == _this.CAT_FILM)
        {
            if (!_this.disableIndexes && section != 0 && (section != sectionPrev || (section == sectionPrev && !title) ))
            {
                state = _this.FILMINDEX;
                changeContent = true; // always change content here, regardless of state change
            } else if (title != titlePrev)
            {
                state = _this.FILMDETAIL;
                changeContent = true; // always change content here, regardless of state change
            }
        }
        // State for "news"
        else if (category == _this.CAT_NEWS)
        {
            state = _this.NEWS;
        }
        // State for "vita"
        else if (category == _this.CAT_VITA)
        {
            state = _this.VITA;
        }
        // State for "contact"
        else if (category == _this.CAT_CONTACT)
        {
            state = _this.CONTACT;
        }

        // State for "imprint"
        else if (category == _this.CAT_IMPRINT)
        {
            state = _this.IMPRINT;
        }

        trace("-> " + state);

        categoryPrev = category;
        sectionPrev = section;
        titlePrev = title;


        // The content will be changed if the state has changed
        // or if changeContent has been set to true in the above state evaluation.
        if (state != stateOrg) changeContent = true;

        if (changeContent)
        {
            $(_this).trigger({type: 'changeContent', state: state, category: category, section: section, title: title});
            loadContent(categoryPrev, sectionPrev, titlePrev);
        }

        // Check if application has been reset (i.e. started from the beginning with no navi preselection)
        if (category == 0 && section == 0 && title == 0)
        {
            $(_this).trigger({type: 'reset'});
        }
    }

    /**
     * Load the content from the server.
     * Depending on state and active ids, different content is loaded.
     *
     * @param category
     * @param section
     * @param title
     */
    var loadContent = function (category, section, title)
    {
        trace("loadContent section=" + section);

        if (state == _this.SLIDESHOW)
        {
            $.ajax({
                url: getAjaxUrl('Photo', 'slideshow', ''),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.PHOTOINDEX)
        {
            var pageId = CAT_SECT_PAGE_IDS[category][section];
            $.ajax({
                url: getAjaxUrl('Photoseries', 'list', new Array(['pageId', pageId])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.FILMINDEX)
        {
            var pageId = CAT_SECT_PAGE_IDS[category][section];
            $.ajax({
                url: getAjaxUrl('Film', 'list', new Array(['pageId', pageId])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.PHOTOSERIES)
        {
            var pageId = CAT_SECT_PAGE_IDS[category][section];
            $.ajax({
                url: getAjaxUrl('Photoseries', 'show', new Array(['pageId', pageId], ['photoseriesNr', title])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.FILMDETAIL)
        {
            var pageId = CAT_SECT_PAGE_IDS[category][section];
            $.ajax({
                url: getAjaxUrl('Film', 'show', new Array(['pageId', pageId], ['filmNr', title])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.NEWS)
        {
            $.ajax({
                url: getAjaxUrl('News', 'list', ''),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.VITA)
        {
            $.ajax({
                url: getAjaxUrl('Text', 'show', new Array(['pageId', PAGE_IDS[_this.VITA]])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.CONTACT)
        {
            $.ajax({
                url: getAjaxUrl('Text', 'show', new Array(['pageId', PAGE_IDS[_this.CONTACT]])),
                cache: false,
                success: contentLoaded
            });
        }

        if (state == _this.IMPRINT)
        {
            $.ajax({
                url: getAjaxUrl('Text', 'show', new Array(['pageId', PAGE_IDS[_this.IMPRINT]])),
                cache: false,
                success: contentLoaded
            });
        }

    }

    /**
     * Gets the url for the Ajax call.
     *
     * @param controller The controller of the Plugin.
     * @param action The action of the Plugin.
     * @param params Further Parameters.
     * @return string The url.
     */
    var getAjaxUrl = function (controller, action, params)
    {
        var url = '/?id=' + AJAX_PAGE_ID + '&type=' + AJAX_PAGE_TYPENUM + '&' + PI_NAME + '[controller]=' + controller + '&' + PI_NAME + '[action]=' + action;

        for (var i = 0; i < params.length; i++)
        {
            var param = params[i];
            url += '&' + PI_NAME + '[' + param[0] + ']=' + param[1];
        }
        return url;
    }

    /**
     * Is called, when the content has been successfully loaded.
     * Handles the "success" from loadContent.
     *
     * @param data The data returned from the server.
     */
    var contentLoaded = function (data)
    {
        $(_this).trigger({type: 'contentLoaded', state: state, content: data});
    }

    /*
        Getters
     */

    this.getCategory = function ()
    {
        return category;
    }

    this.getSection = function ()
    {
        return section;
    }

    this.getTitle = function ()
    {
        return title;
    }

    this.getCategoryPrev = function ()
    {
        return categoryPrev;
    }

    this.getSectionPrev = function ()
    {
        return sectionPrev;
    }

    this.getTitlePrev = function ()
    {
        return titlePrev;
    }


}

