Source: common/model.js

/**
 * @module common/model
 * @description This is the application model. 
 * @requires spearfishHelpers
 * @requires managers/timer-manager
 * @requires common/services
 * @requires ldash
 * @requires moment
 */

define([
    "spearfishHelpers",
    "managers/timer-manager",
    "common/services",
    "ldash",
    "moment"
], 

function (helpers, timer, services, ldash, moment) 
{

    // ---------------------------------------------------------------
    //
    // Model
    //
    // ---------------------------------------------------------------
   
    var Model = function ()
    {   
        console.log(" * <model>");

        // events
        window.tEvent.eventStr.EVENT_JSON_LOADED              = "EVENT_JSON_LOADED";
        window.tEvent.eventStr.EVENT_MODEL_READY              = "EVENT_MODEL_READY";
        
        // page events
        window.tEvent.eventStr.EVENT_NEW_PAGE                 = "EVENT_NEW_PAGE";
        window.tEvent.eventStr.EVENT_PAGE_LOADED              = "EVENT_PAGE_LOADED";
        window.tEvent.eventStr.EVENT_TEMPLATE_LOADED          = "EVENT_TEMPLATE_LOADED";
        window.tEvent.eventStr.EVENT_TEMPLATE_LOADED_DETAILS  = "EVENT_TEMPLATE_LOADED_DETAILS";
        
        window.tEvent.eventStr.EVENT_VIDEO_START              = "EVENT_VIDEO_START",
        window.tEvent.eventStr.EVENT_VIDEO_END                = "EVENT_VIDEO_END",
        window.tEvent.eventStr.EVENT_VIDEO_PAUSE              = "EVENT_VIDEO_PAUSE",
        
        window.tEvent.eventStr.EVENT_TOGGLE_MIC               = "EVENT_TOGGLE_MIC",
        
        window.tEvent.eventStr.EVENT_TEST_MODE_STATE_CHANGE   = "EVENT_TEST_MODE_STATE_CHANGE",
        
        window.tEvent.eventStr.EVENT_TIMER_EXPIRED            = "EVENT_TIMER_EXPIRED";
        window.tEvent.eventStr.EVENT_PRSONAS_MESSAGE_RECEIVED = "EVENT_PRSONAS_MESSAGE_RECEIVED";

        this.def = {
            PATH_ASSETS       : "Content/",
            
            CLASS_INCOMPLETE  : "is-incomplete",
            CLASS_IS_DISABLED : "is-disabled",
            CLASS_IS_ACTIVE   : "is-active",
            CLASS_TEST_MODE   : "is-test-mode",
            CLASS_IN_SEARCH   : "in-search",
            
            LANGUAGE_ENGLISH  : "_English",
            MODE_IHA          : "iha"
        };

        this.ui = {
            configScript: ".js-config-script"
        };

        // init lodash 
        window._ = ldash;

        // moment js
        window.moment = moment;

        this.oServices = services;
        
        // maintains page data for router
        this.pageModel = { page:{} };

        // query string object
        this.queryString = window.helpers.parseQuerystring();     

        // debug mode   
        this.debugMode = -1;

        // test mode
        this.testMode = {
            isActive: false,
            emailTo: "",
            smsTo: ""
        };     

        this.jConfig = -1;

        this.oTimer = timer;

        this.interactionBlockState = false;

        this.modelReady = false;

        this.init();
    };
       
    Model.prototype =
    {
        
        // ______________________________________________________________
        //                                                           init
        /**
            * init
            * @description Initializes class
            * @fires assignListeners()
            * @fires loadJson()
            * @memberOf module:common/model
            * @instance
        */
        init: function()
        {   
            // debug mode   
            this.debugMode = this.getDebugMode();

            this.assignListeners();
            this.loadJson();
        },


        // ______________________________________________________________
        //                                                assignListeners
        /**
            * assignListeners
            * @description Assigns listeners to events used in this class.
            * @listens EVENT_INTERACTION_BLOCK_STATE
            * @listens EVENT_MODEL_READY
            * @memberOf module:common/model
            * @instance
        */
        assignListeners: function()
        {
            var self = this;
            
            // manage interaction delay
            window.tEvent.addListener("EVENT_INTERACTION_BLOCK_STATE", function(evt, data) {   
                self.interactionBlockState = data;
            });

        }, 
        
        // ______________________________________________________________
        //                                       getInteractionBlockState
        /**
            * getInteractionBlockState
            * @description Getter for block state
            * @returns {Boolean} interactionBlockState
            * @memberOf module:common/model
            * @instance
        */
        getInteractionBlockState: function()
        {
            return(this.interactionBlockState);
        },

        // ______________________________________________________________
        //                                                   getDebugMode
        /**
            * getDebugMode
            * @description Getter for debug state
            * @returns {Boolean} debug
            * @memberOf module:common/model
            * @instance
        */
        getDebugMode: function()
        {
            var debug = false;
            if (this.queryString.devdebug && this.queryString.devdebug === "1") 
                debug = true;

            return debug;

        },


        // ______________________________________________________________
        //                                                    setTestMode
        /**
            * setTestMode
            * @description Sets the application state to test mode
            * @param {Object} testData - Data required for any method to make use of the test mode
            * @fires EVENT_TEST_MODE_STATE_CHANGE
            * @memberOf module:common/model
            * @instance
        */
        setTestMode: function(testData)
        {
            this.testMode = testData;
            

            if (testData.isActive){
                $("body").addClass(this.def.CLASS_TEST_MODE);
                $("body").append("<div class='test-mode__copy'>TEST MODE</div>");

            } else {
                $("body").removeClass(this.def.CLASS_TEST_MODE);
                $(".test-mode__copy").remove();
            }

            window.tEvent.fire(window.tEvent.eventStr.EVENT_TEST_MODE_STATE_CHANGE, testData);

            console.log(" * <model.setTestMode> ", testData);
        },


        // ______________________________________________________________
        //                                                       loadJson
        /**
            * loadJson
            * @description loads the configuration JSON files. This includes 'core-config.json' and 'project.json'. 'project.json' will override the 'core-config.json' content.
            * @fires EVENT_JSON_LOADED
            * @fires EVENT_LANGUAGE_SET
            * @memberOf module:common/model
            * @instance
        */        
        loadJson: function()
        {
            var self = this;
            var bust = "?bust=" + Math.random();
            var mode = $("#configuration").attr("data-mode");
            var qs = window.helpers.parseQuerystring();

            // get project config file
            var configJson = "project.json";
            if ($(this.ui.configScript).length !== 0 && $(this.ui.configScript).attr("config-json") !== "undefined"){
                configJson = $(this.ui.configScript).attr("config-json");
            }


            if (typeof qs.json !== "undefined"){
                configJson = qs.json;
            }
            
            // load custom json from Prsonas viewer commandline
            if (typeof window.oPrsonas !== "undefined" &&
                typeof window.oPrsonas.app !== "undefined" &&
                window.oPrsonas.app.getCommandLineParameters() !== null){
                
                if (typeof window.oPrsonas.app.getCommandLineParameters().json !== "undefined"){
                    configJson = window.oPrsonas.app.getCommandLineParameters().json;
                }  
            }

            // load core json config
            $.getJSON("__static_ext/dxp/json/core-config.json" + bust, function(staticJson)
            {   
                console.log(" * <model.loadJson> dxp core-config.json", staticJson); 


                if (mode === self.def.MODE_IHA){

                    $.getJSON("__static_ext/iha/json/core-config.json" + bust, function(ihaStaticJson)
                    { 

                        console.log(" * <model.loadJson> iha core-config.json", ihaStaticJson); 

                        staticJson = _.merge(staticJson, ihaStaticJson);

                        // load custom project json
                        self.oServices.loadProjectJson(configJson, function(returnObj){

                            console.log(" * <model.projJson>", returnObj); 
                            projJson = returnObj.data;
                            self.jConfig = _.merge(staticJson, projJson);

                            // set environment
                            self.manageEnv();

                            // set timer vars
                            self.oTimer.init(self.jConfig);

                            // call out json loaded
                            window.tEvent.fire(window.tEvent.eventStr.EVENT_JSON_LOADED, self.jConfig);

                            // set language
                            console.warn (" * <model.loadJson> Firing event EVENT_LANGUAGE_SET - This should not be done here.");
                            window.tEvent.fire("EVENT_LANGUAGE_SET", self.jConfig.document.language);
                         
                            console.log(" * <model.projJson> Merged", self.jConfig);                   
                        });
                    });



                } else {
                    // load custom project json
                    self.oServices.loadProjectJson(configJson, function(returnObj){

                        console.log(" * <model.projJson>  dxp core-config.json", returnObj); 
                        projJson = returnObj.data;
                        self.jConfig = _.merge(staticJson, projJson);

                        // set environment
                        self.manageEnv();

                        // set timer vars
                        self.oTimer.init(self.jConfig);

                        // call out json loaded
                        window.tEvent.fire(window.tEvent.eventStr.EVENT_JSON_LOADED, self.jConfig);

                        // set language
                        console.warn (" * <model.loadJson> Firing event EVENT_LANGUAGE_SET - This should not be done here.");
                        window.tEvent.fire("EVENT_LANGUAGE_SET", self.jConfig.document.language);
                     
                        console.log(" * <model.projJson> Merged", self.jConfig);                   
                    });

                }



            });    

        },
        

        // ______________________________________________________________
        //                                                      manageEnv
        /**
            * manageEnv
            * @description Environment dependent data is applied from the 'project.json' 'environment' node            
            * @fires onModelReady()
            * @memberOf module:common/model
            * @instance
        */  
        manageEnv: function()
        {            
            // get environment
            var env = this.jConfig.environment;
            
            var targetEnv = "";

            for (var i = 0; i < env.local.url.length; i++){
                if ( document.URL.indexOf(env.local.url[i]) != -1){
                    targetEnv = "local";
                    break;
                }
            }

            if (targetEnv === ""){
                for (var i = 0; i < env.development.url.length; i++){
                    if ( document.URL.indexOf(env.development.url[i]) != -1){
                        targetEnv = "development";
                        break;
                    }
                }
            }


            if (targetEnv === ""){
                for (var i = 0; i < env.stage.url.length; i++){
                    if ( document.URL.indexOf(env.stage.url[i]) != -1){
                        targetEnv = "stage";
                        break;
                    }
                }
            }


            if (targetEnv === ""){
                for (var i = 0; i < env.production.url.length; i++){
                    if ( document.URL.indexOf(env.production.url[i]) != -1){
                        targetEnv = "production";
                        break;
                    }
                }
            }


            if (targetEnv === ""){                
                targetEnv = "local";                    
            }

            console.log(" * <model.manageEnv> using " + targetEnv + " environment");



            // block console log for production                   
            if (targetEnv === "production") {          
                if (!this.debugMode && this.jConfig.environment.production.disableConsole) {            
                    console =  {           
                        log   :function(){},
                        warn  :function(){},
                        error :function(){},
                        info  :function(){},
                        trace :function(){}
                    };
                }
                                 
            }

            this.onModelReady();
        },


        // --------------------------------------------------------------
        // HELPERS
        // --------------------------------------------------------------
        // ______________________________________________________________
        //                                                    getManifest
        /**
            * getManifest
            * @description Getter for Prsonas manifest json
            * @returns {Object} Prsonas manifest
            * @memberOf module:common/model
            * @instance
        */  
        getManifest: function() {    
            return (this.oServices.manifest);
        },

        // ______________________________________________________________
        //                                                   getReturnObj
        /**
            * getReturnObj
            * @description Returns generic return object
            * @returns {Object}
            * @example
            * {
            *    "status": "ok",
            *    "data": {}
            * }
            * @memberOf module:common/model
            * @instance
        */ 
        getReturnObj: function() {    
            return ({
                "status": "ok",
                "data": {}
            });
        },
       

        // --------------------------------------------------------------
        // EVENTS
        // --------------------------------------------------------------  
        

        // ______________________________________________________________
        //                                                   onModelReady
        /**
            * onModelReady
            * @description Called when model is ready
            * @fires EVENT_MODEL_READY
            * @memberOf module:common/model
            * @instance
        */  
        onModelReady: function()
        {              
            this.modelReady = true;         
        }


    };

    /** 
    * @global 
    */
    window.oModel = new Model(); 

    return(window.oModel);
});