Source: managers/template-manager.js

/**
 * @module managers/template-manager
 * @description This module process the project JSON modules into functional templates.
 * @requires common/view
 * @requires managers/styles-manager
 */

define([
    "common/view",
    "managers/styles-manager",
    "managers/prsonas-manager"
], 

function (view, styles, prsonas)
{

    // ---------------------------------------------------------------
    //
    // TEMPLATE MANAGER
    //
    // ---------------------------------------------------------------

    var Template = function ()
    {
        console.log(" * <template>");

        window.tEvent.eventStr.EVENT_DROPINPUT_ACTIVE = "EVENT_DROPINPUT_ACTIVE";   

        this.oView = view;
        this.oStyles = styles;
        this.oPrsonas = prsonas;

        this.ui = {
            constrainContainer : ".js-constrain",
            video              : ".js-video",
            interactivePanels  : ".js-interactive-panels"
        };

        this.def = {
            MODULE_PAGE                   : "m-page",
            MODULE_IHA_TEMPLATE_PAGE      : "iha-template-page",
            MODULE_COMPLEX_TEMPLATE_PAGE  : "complex-template-page",
            MODULE_LANGUAGE_TEMPLATE_PAGE : "complex-template-page-languages",
            MODE_IHA                      : "iha"
        };

        // modules from json
        this.jModules = -1;

        this.init();
    };

    Template.prototype =
    {    
       
        // ______________________________________________________________
        //                                                           init
        /**
            * init
            * @description Initializes class
            * @fires assignListeners()
            * @memberOf module:managers/template-manager
            * @instance
        */
        init: function()
        { 
            this.assignListeners();            
        },


        // ______________________________________________________________
        //                                                assignListeners
        /**
            * assignListeners
            * @description Assigns listeners to events used in this class.
            * @listens EVENT_JSON_LOADED
            * @fires onJsonLoaded()
            * @memberOf module:managers/template-manager
            * @instance
        */
        assignListeners: function()
        {           
            var self = this;

            if (typeof window.oModel === "undefined" || window.oModel.jConfig === -1){
                window.tEvent.addListener("EVENT_JSON_LOADED", function(evt, data)
                {
                    // clean up for new page
                    self.onJsonLoaded(window.oModel.jConfig); 
                });                
            } else {
                self.onJsonLoaded(window.oModel.jConfig); 
            }


        },

        // --------------------------------------------------------------
        // HELPERS
        // --------------------------------------------------------------
        // ______________________________________________________________
        //                                              initSendKeyEvents
        /**
            * initSendKeyEvents
            * @description Registers all of the project JSON events with the application event system
            * @memberOf module:managers/template-manager
            * @instance
        */
        initSendKeyEvents: function(evts) {
            var self = this;

            for (var key in evts){
                window.tEvent.eventStr[key] = key;
            }
        },

        // ______________________________________________________________
        //                                                      initModes
        /**
            * initModes
            * @description Initializes application modes (ie IHA)
            * @memberOf module:managers/template-manager
            * @instance
        */
        initModes: function() {
            var modules = this.jModules;
            var mode = $("#configuration").attr("data-mode");
            var tempObj;
            
            switch(mode){
                case this.def.MODE_IHA:                    
                    break;                    
            }

            // interactive panel
            if (typeof modules["complex-interactive-panel"] !== "undefined"){
                tempObj = window.oDxpTemplates["complex-template-interactive"](modules["complex-interactive-panel"]);
            } else {
                // fix for missing module in project.json
                tempObj = window.oDxpTemplates["complex-template-interactive"]({
                    "id": "complex-interactive-panel",
                    "micToggle": {
                        "copy": "Turn microphone on or off.",
                        "data": {
                        }
                    }
                });
                
            }

            $(this.ui.interactivePanels).html(tempObj);
        },

        // ______________________________________________________________
        //                                                  registerPages
        /**
            * registerPages
            * @description Registers page modules. Where module ids are "m-page" or "iha-template-page" (if using IHA mode). 
            * @param {Object} modules - Collection of modules from the project json "module" node
            * @listens Page Events
            * @fires EVENT_NEW_PAGE - When page event is fired
            * @fires onLoadPage(pageData) - When page event is fired
            * @memberOf module:managers/template-manager
            * @instance
        */
        registerPages: function(modules) {

            var self = this;

            var targetMod;

            for (var m in modules){
                targetMod = modules[m];
                if (targetMod.id === this.def.MODULE_PAGE || 
                    targetMod.id.indexOf(this.def.MODULE_IHA_TEMPLATE_PAGE) !== -1 || 
                    targetMod.id.indexOf(this.def.MODULE_COMPLEX_TEMPLATE_PAGE) !== -1){

                    console.log(" * <template.registerPages> " + targetMod.class);

                    // register page with router
                    this.oView.registerPage({
                        events: [targetMod.event],
                        routes: {
                            index: {
                                hashString : targetMod.class,
                                loadEvent  : targetMod.event
                            }
                        }
                    });

                    // create listener for page event
                    window.tEvent.addListener(targetMod.event, function(evt, data)
                    {  
                        // triggered event on page load (before loaded)
                        window.tEvent.fire(window.tEvent.eventStr.EVENT_NEW_PAGE, evt.type);

                        if (evt.type.indexOf("EVENT_PAGE") !== -1){
                            window.tEvent.fire("EVENT_HISTORY", {
                                eventId: evt.type,
                                data: data
                            });
                        }

                        // get page data
                        var pageData = self.getPageFromEvent(evt.type);

                        // added ref to modules
                        pageData._modules = self.jModules;

                        //load page
                        self.onLoadPage(pageData);


                    }); 
                }
            }

        },


        // ______________________________________________________________
        //                                               getPageFromEvent
        /**
            * getPageFromEvent
            * @description Returns module page data based on event string
            * @param {String} evt - Event string
            * @returns {Object} - Module data object
            * @memberOf module:managers/template-manager
            * @instance
        */
        getPageFromEvent: function(evt) {

           var targetMod;
           var isPage;
           var data = {};

           for (var key in this.jModules) {
               targetMod = this.jModules[key];
               isPage = false;

               // EVENT_PAGE_LANGUAGES
                if (targetMod.id.indexOf(this.def.MODULE_LANGUAGE_TEMPLATE_PAGE) !== -1){
                    isPage = true;
               }

               if (targetMod.id.indexOf(this.def.MODULE_IHA_TEMPLATE_PAGE) !== -1 || 
                targetMod.id.indexOf(this.def.MODULE_COMPLEX_TEMPLATE_PAGE) !== -1){
                    isPage = true;
               }

               if ( (targetMod.id === this.def.MODULE_PAGE && targetMod.event === evt) || (isPage && targetMod.event === evt) ){
                   data = window.helpers.clone(targetMod);
                   data.moduleId = key;
                   break;
               }


           }

           return data;

        },
        

        // ______________________________________________________________
        //                                                 initPageEvents
        /**
            * initPageEvents
            * @description Initializes specialized module page events including video event handling.
            * @param {Object} pageData - Module page data
            * @memberOf module:managers/template-manager
            * @instance
        */
        initPageEvents: function(pageData) { 

            if (typeof pageData.modules === "undefined"){
                return;
            }
            // check for module events
            var m;            
            for (var i = 0; i < pageData.modules.length; i++){
                m = pageData.modules[i];
                switch(m.id){
                    case "m-video":
                        var vid = $(".m-video " + this.ui.video, "." + pageData.class)[0];

                        // set required events, append customized actions for these events
                        (function(v, events){
                            v.onended = function(){
                                window.tEvent.fire(window.tEvent.eventStr.EVENT_VIDEO_END);
                                if (typeof events.onended !== "undefined"){
                                    window.tEvent.fire(events.onended);
                                }
                            }; 

                            v.onplay = function(){
                                window.tEvent.fire(window.tEvent.eventStr.EVENT_VIDEO_START);
                                if (typeof events.onplay !== "undefined"){
                                    window.tEvent.fire(events.onplay);
                                }
                            }; 

                            v.onpause = function(){
                                window.tEvent.fire(window.tEvent.eventStr.EVENT_VIDEO_PAUSE);
                                if (typeof events.onpause !== "undefined"){
                                    window.tEvent.fire(events.onpause);
                                }
                            }; 
                        })(vid, m.events);   


                        // iterate through user defined events
                        for (var key in m.events){        
                            switch (key){
                                case "onended":
                                case "onplay":
                                case "onpause":
                                    // skip, already done
                                    break;

                                default:
                                (function(v, onEvent, toEvent){
                                    v[onEvent] = function(){
                                        window.tEvent.fire(toEvent);
                                    };     
                                })(vid, key, m.events[key]);   
                            }                   
                          
                        }

                        
                        break;
                }
            }

        },


        // ______________________________________________________________
        //                                                initProxyEvents
        /**
            * initProxyEvents
            * @description Initializes event proxies
            * @param {Object} proxyData - Proxy event data from the project JSON
            * @listens Proxy events
            * @fires onCustomEventBehavior() - When proxy event is fired
            * @memberOf module:managers/template-manager
            * @instance
        */
        initProxyEvents: function(proxyData) {
            var self = this;

            for (var evt in proxyData) {
                (function(proxyEvt, evtToCall){
                    window.tEvent.addListener(proxyEvt, function(evt){  
                        self.onCustomEventBehavior(evtToCall, evt.type);
                    });
                })(evt, proxyData[evt]);                
            }

        },

        // --------------------------------------------------------------
        // EVENTS
        // --------------------------------------------------------------
        
        // ______________________________________________________________
        //                                          onCustomEventBehavior
        /*
            Called from ext custom project class for non send key events
        */
        /**
            * onCustomEventBehavior
            * @description Handles proxy event behavior
            * @param {String} evt - Event string that is being proxied
            * @param {String} proxyEvtStr - Proxy event string
            * @fires EVENT_NEW_PAGE
            * @fires onLoadPage()
            * @memberOf module:managers/template-manager
            * @instance
        */
        onCustomEventBehavior: function(evt, proxyEvtStr) { 
            
            var self = this;

            // triggered event on page load (before loaded)
            window.tEvent.fire(window.tEvent.eventStr.EVENT_NEW_PAGE, evt);
          

            // get page data
            var pageData = self.getPageFromEvent(evt);
            
            if (typeof pageData.moduleId === "undefined"){
                return;
            }

            if (proxyEvtStr.indexOf("EVENT_PAGE") !== -1){
                window.tEvent.fire("EVENT_HISTORY", {
                    eventId: proxyEvtStr,
                    data: pageData
                });
            }

            // added ref to modules
            pageData._modules = self.jModules;
            pageData._proxyEvtStr = proxyEvtStr;

            //load page
            self.onLoadPage(pageData);
            
        },
        

        // ______________________________________________________________
        //                                                   onJsonLoaded
        /**
            * onJsonLoaded
            * @description Got JSON data from core and project. Begins the template processing.
            * @param {JSON} jData - JSON data
            * @fires EVENT_NEW_PAGE
            * @fires onLoadPage()
            * @memberOf module:managers/template-manager
            * @instance
        */
        onJsonLoaded: function(jData) { 

            // store module data
            this.jModules = jData.modules;

            // set document class
            $("body").addClass(jData.document.bodyClass);

            // set mode
            if (typeof jData.document.mode !== "undefined"){
                $("#configuration").attr("data-mode", jData.document.mode);
            }   

            $(this.ui.constrainContainer).addClass(jData.document.constrainClass);
           
            // init proxy events with alternative send keys
            this.initProxyEvents(jData.proxySendkeyEvents);

            // init sendkey events
            this.initSendKeyEvents(jData.sendKeyEvents);

            // register pages
            this.registerPages(jData.modules);    

            // init modes
            this.initModes();

            // call event that all is ready
            window.tEvent.fire(window.tEvent.eventStr.EVENT_MODEL_READY);

            // call starting page
            var mode = $("#configuration").attr("data-mode");
            switch(mode){
                case this.def.MODE_IHA:
                    // IHA has own process to start page
                    break;
                default:
                    window.tEvent.fire(jData.document.startEvent);
                    break;
            }

        },


        // ______________________________________________________________
        //                                                     onLoadPage
        /**
            * onLoadPage
            * @description Loads page from pageData
            * @param {Object} pageData - Module page data
            * @fires EVENT_TEMPLATE_LOADED
            * @memberOf module:managers/template-manager
            * @instance
        */
        onLoadPage: function(pageData) { 

            console.log(" * <template.onLoadPage>", pageData);

            var templ = window.oDxpTemplates;

            if (typeof templ[pageData.id] === "undefined"){
                if (typeof window.oIhaTemplates[pageData.id] !== "undefined"){
                    templ = window.oIhaTemplates;
                } else {
                    console.error(" ! <template.onLoadPage> Template not found: " + pageData.id);
                    return;
                }
            }


            this.oView.loadPageTemplate( templ[pageData.id](pageData), pageData );

            // init additional page events
            this.initPageEvents(pageData);

            window.tEvent.fire(window.tEvent.eventStr.EVENT_TEMPLATE_LOADED_DETAILS, pageData); 
            window.tEvent.fire(window.tEvent.eventStr.EVENT_TEMPLATE_LOADED, pageData.event); 
          
        }



    };

    /** 
    * @global 
    */
    var oTemplate = new Template();
        
    return (oTemplate);        
   
});