/*
 * xMDB Viewer - XML Movie Database Viewer; DHTML viewer for XML movie databases
 * Copyright (C) 2006 Attila Szabo
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 * See the GNU General Public License for more info at http://www.gnu.org/licenses/gpl.txt
 */

// global object 'MDBAPP' will be created
// dependencies: bookmarkable.js


var MDB = { // namespacing object

    "locales" : {

            // text showed when content is being loaded in the status bar of the browser
            'loadingMsg'                : 'please wait...',

            // min. required screen resoluton is 1024
            'notEnoughScreenResolution' : 'Your screen resolution is too low. The minimal required screen resolution is at least 1024x768.',

            // too old version of MSXML
            'msxmlMustBeUpgraded'       : 'You browser needs to be updated. If you have Internet Explorer download and install the following update from '+
                                          'Microsoft\'s web page: <br /> '+
                                          '<a href="https://www.microsoft.com/downloads/details.aspx?familyid=993C0BCF-3BCF-4009-BE21-27E85E1857B1&displaylang=en">'+
                                          'Microsoft Core XML Services (MSXML) 6.0</a>'
    },

    "config" : {

        // these are the most important
        'target'     : 'tabContent',                      // ID of a HTML container (mostly a DIV) in which the movie listing will appear
        'dataSource' : 'db/films.xml', //DSO_films        // ID of the XML data island holding the XML database (file)
        'views'      : { 'list'   : 'views/list.xsl',     // one or more XSLT files to provide different views on the data
                         'details': 'views/details.xsl'   // they transform the XML, these files are responsible for the representation of data
                       },


        "viewModeLstElementID" : 'lstViewMode',           // ID of a list box displaying available view modes (XSLT styles)
        "navListElementID"     : 'tabbedNav',             // ID of the tabbed navigation container. It's a UL tag for listing the filter names of the 'Genre' filter group
        'filterGroups'         : [],                      // array holding filter group objects (FilterType instances)
        'browserProblemsListID': 'browserProblems',       // ID of a DOM List element in which error messages appear when the used client browser is not supported
        'browserProblemsBoxID' : 'requirementsMsg',       // ID of an HTML container to inform user about unsupported browser
        'initialLoadingMsgParagraphID' : 'initialLoadingMsg' // ID of an HTML paragraph informing the user to wait till the data loads on page load
    },


    "Init" : function (){
        var genreInitial, viewInitial; // initial viewMode and genre

        // get stored state from document location
        genreInitial = bookmarkable.getState('genre');
        genreInitial = (!isNaN(parseInt(bookmarkable.getState('genre'),10)))? parseInt(genreInitial,10) : 0;
        viewInitial = bookmarkable.getState('view');


        // verify client browser if it is capable to host this web application (if it meets the minimal browser requirements)
        var oLstBrowserRequirements = document.getElementById(MDB.config.browserProblemsListID);
        var aBrowserSupportProblems = [];
        var bBrowserSupported = true;
        if (oLstBrowserRequirements){

            // screen resolution
            if (screen && screen.width){
                if (parseInt(screen.width,10) < 1024){
                    aBrowserSupportProblems.push(MDB.locales.notEnoughScreenResolution);
                    bBrowserSupported = false;
                }
            }

            // is AJAX supported?
            var ajaxSupported = false;
            try {
                if (XML.getDomDocument());
                    ajaxSupported = true;
            } catch (e) {
            }

            if (!ajaxSupported){
                aBrowserSupportProblems.push(MDB.locales.msxmlMustBeUpgraded);
                bBrowserSupported = false;
            }

            // unhide message box and add error messages to the List element
            if (!bBrowserSupported){
                for (var i=0; i < aBrowserSupportProblems.length; i++){
                    var oLstElement = document.createElement('li');
                    oLstElement.innerHTML = aBrowserSupportProblems[i];
                    oLstBrowserRequirements.appendChild(oLstElement);
                    oLstElement = null;
                }
                document.getElementById(MDB.config.browserProblemsBoxID).style.visibility = 'visible';
            }

            // hide loading msg text
            document.getElementById(MDB.config.initialLoadingMsgParagraphID).style.display = 'none';

        }

        // get object reference to DOM list box for displaying view modes
        var oLstViewModes = document.getElementById(MDB.config.viewModeLstElementID);
        if (oLstViewModes.nodeName.toUpperCase() != 'SELECT'){
            alert("Configuration error: HTML element '"+ MDB.config.viewModeLstElementID +"' must be a list box.");
            return;
        }

        // populate list box with available view modes
        if (!MDB.config.views || typeof MDB.config.views != 'object')
            alert("Configuration error: value of 'views' must be an object.");

        for(var viewName in MDB.config.views){
            var oLiOption = document.createElement("option");
            oLiOption.value = viewName;
            oLiOption.appendChild(document.createTextNode(viewName));
            if (viewName == viewInitial)
                oLiOption.selected = true;
            oLstViewModes.appendChild(oLiOption);
            oLiOption = null;
        }

        // bind event listener to list box
        oLstViewModes.onchange = function(){
            MDBAPP.db.ChangeView(this.options[this.selectedIndex].value);
            if (MDBAPP.OnLoading && MDBAPP.OnFinishedLoading)
               MDBAPP.OnLoading();

            bookmarkable.storeState("view",this.options[this.selectedIndex].value)
            MDBAPP.db.Render();

            if (MDBAPP.OnLoading && MDBAPP.OnFinishedLoading)
                MDBAPP.OnFinishedLoading();
        }


        // Create menu items for the tabbed navigation
        var oNav = new TabbedNav(MDB.config.navListElementID);
        var oUL = document.getElementById(MDB.config.navListElementID);
        if (!MDB.config.navListElementID){
            alert("Configuration error: value of \'navListElementID\' must be specified!");
            return;
        }


        if (!oUL){
            alert("Configuration error: invalid \'navListElementID\'. There is no HTML element with this ID ("+ MDB.config.navListElementID +")!");
            return;
        }
        if (oUL.nodeName.toUpperCase() != 'UL'){
            alert("Configuration error: HTML element '"+ MDB.config.navListElementID +"' must be an UL list element.");
            return;
        }
        oUL = null;


        // Create navigation

        // verify if there is 'Genre' filter group
        var oGenre = MDB.config.filterGroups.Find(function (oFGroup){return oFGroup.name.toLowerCase() == 'genre';});
        if (!oGenre)
            alert("Configuration error: filter type 'Genre' is missing. You must specify 'Genre' filters.");

        for(var i=0; i < oGenre.CountFilters(); i++){
            var oTmp = {};
            oTmp.label = oGenre.getFilter(i).name;
            oTmp.title = oTmp.label;
            oTmp.onSelect = MDB.menuItem_clicked;

            oNav.items.Add(oTmp);
        }


        // make navbar item selected (first is selected by default)
        oNav.items.MakeItemSelected(genreInitial);


        MDBAPP = new MDB._constructor(genreInitial,viewInitial); // create global variable 'MDBAPP'
    },


    "_constructor" : function (genreSelected,viewMode){
        this.db = new MovieDB(MDB.config);
        this.db.setFilters(MDB.config.filterGroups);
        this.db.ApplyFilter('Genre', genreSelected);
        if (viewMode)
            this.db.ChangeView(viewMode);
        this.db.Render();

        this.OnLoading = function(){window.status = MDB.locales.loadingMsg;};
        this.OnFinishedLoading = function(){window.status = '';};

        this.OrderByColumn = function (index){
            this.db.ApplyFilter('Ordering',index);
            this.db.Render();
        };

    },


    "menuItem_clicked" : function (filterIndex){ // event handler

        if (MDBAPP.OnLoading && MDBAPP.OnFinishedLoading)
            MDBAPP.OnLoading();


        if (typeof filterIndex == 'number')
            MDBAPP.db.ApplyFilter('Genre', filterIndex);
        else
            MDBAPP.db.ClearFilters();

        bookmarkable.storeState('genre', filterIndex);
        MDBAPP.db.Render();


        if (MDBAPP.OnLoading && MDBAPP.OnFinishedLoading)
            MDBAPP.OnFinishedLoading();
    }

}

addEvent(window, 'load', MDB.Init, false);
