/*
 * app.shell.js
 * Shell module for SPA
 */

/*jslint         browser : true, continue : true,
  devel  : true, indent  : 2,    maxerr   : 50,
  newcap : true, nomen   : true, plusplus : true,
  regexp : true, sloppy  : true, vars     : false,
  white  : true
*/
/*global $, app */

app.shell = (function () {
    'use strict';
    //---------------- BEGIN MODULE SCOPE VARIABLES --------------

    var

        stateMap = {
            $container: undefined,
            anchor_map: {},
            user: {
                authenticated: false,
                token: '',
                name: '',
                id:0
            },
            apiUrl: '',
            search_cache: {
                has_cache: false
            }
        },
        tokenExpired,
        //onUPdate,
        onLogin, onLogout, onShowError, onClearError,
        initModule;
    //----------------- END MODULE SCOPE VARIABLES ---------------

    //------------------- BEGIN UTILITY METHODS ------------------

    tokenExpired = function () {
        //fetch stored creds if available
        var creds = store.get('pecklist.usercreds');
        if (creds) {
            //check if token has expired
            //is the date greater than the expires date
            var rightNowUtc = new Date();
            var expDate = new Date(creds.expires * 1000);
            if (rightNowUtc > expDate) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }
    //-------------------- END UTILITY METHODS -------------------


    //------------------- BEGIN EVENT HANDLERS -------------------

    onLogin = function (event, login_user) {
        //store creds
        store.set('pecklist.usercreds', stateMap.user);
        //New token needs to reset lastNav
        stateMap.lastNav = new Date();
        //Go to the home page
        page('#!/main/');
        return false;
    };

    onLogout = function (event) {
        store.clear();
        stateMap.user.authenticated = false;
        stateMap.user.name = '';
        stateMap.user.token = '';
        stateMap.user.id=0;
        page('#!/authenticate/');
        return false;
    };

    // onUpdate = function (event) {

    //     window.location.reload(true);
    //     return false;
    // };


    onShowError = function (event, msg) {
        $("#app-error-div").removeClass("d-none");
        $('#app-error-message').text(msg);
        return false;
    };

    onClearError = function (event) {
        $("#app-error-div").addClass("d-none");       
        return false;
    };

   
    //-------------------- END EVENT HANDLERS --------------------



    //------------------- BEGIN PUBLIC METHODS -------------------   
    initModule = function ($container) {

        document.title = 'Pecklist ' + app.api.GZAppVersion;


        //PRE FLIGHT CHECK
        //================
      
        //local storage required
        if (!store.enabled) {
            alert('Local storage is not supported by your browser. Please disable "Private Mode", or upgrade to a modern browser.');
            return;
        }

        //wait indicator for ajax functions
        $(document).ajaxStart(function () {

            //disable all buttons
            $('.app-frm-buttons button').prop('disabled', true).addClass('disabled');
            //$('.app-frm-buttons button').attr('disabled', 'disabled');
            $("body").css("cursor", "progress");
            //add app-ajax-busy style to buttons div where user clicked          
            $('.app-frm-buttons').addClass('app-ajax-busy');

        }).ajaxStop(function () {

            //with delay in case it's too fast to see
            setTimeout(function () {
                $('.app-frm-buttons button').prop('disabled', false).removeClass('disabled');
                //$('.app-frm-buttons button').removeAttr('disabled');              
                $("body").css("cursor", "default");
                $('.app-frm-buttons').removeClass('app-ajax-busy');
            }, 250);

        });


        // load HTML and map jQuery collections
        stateMap.$container = $container;
        $container.html(Handlebars.templates['app.shell']({}));

        //auto hide navbar on click of nav link item       
        $('.nav-link').on('click',function() {
            $('.navbar-collapse').collapse('hide');
          });

        //determine API url and save it
        stateMap.apiUrl = app.utilB.getApiUrl();


        //fetch stored creds if available
        var creds = store.get('pecklist.usercreds');
        

        //check if token has expired       

        if (tokenExpired()) {
            stateMap.user.authenticated = false;
            stateMap.user.name = '';
            stateMap.user.token = '';
            stateMap.user.id=0;

        } else {
            //Show the logout item in the menu
            $(".app-mnu-logout").removeClass("app-hidden");
            stateMap.user.authenticated = true;
            stateMap.user.name = creds.name;
            stateMap.user.token = creds.token;
            stateMap.user.dlkey=creds.dlkey;
            stateMap.user.id=creds.id;
        }
        //}


        //EVENT SUBSCRIPTIONS
        $.gevent.subscribe($container, 'app-login', onLogin);
        $.gevent.subscribe($container, 'app-logout', onLogout);
        //$.gevent.subscribe($container, 'gz-update', onUpdate);
        $.gevent.subscribe($container, 'app-show-error', onShowError);
        $.gevent.subscribe($container, 'app-clear-error', onClearError);


        //ROUTES
        //
        page.base('/index.html');
        
        page('*', beforeUrlChange);
        page('/authenticate', authenticate);
        page('/', main);
        page('/logout', function () {
            $.gevent.publish('app-logout');
        });     
        page('/main', main);
        page('/settings', settings);
        page('*', notFound);
        page({
            hashbang: true
        });
        // /ROUTES
    };
    // End PUBLIC method /initModule/

    var beforeUrlChange = function (ctx, next) {
        $.gevent.publish('app-clear-error');
        app.shell.stateMap.mediaSize = app.utilB.getMediaSize();

        //bypass stuff below if about to logout
        if (ctx.path == '/logout') {
            return next();
        }


        //================================================================
        //Check authentication token to see if expired, but only if it's been a few minutes since last navigation
        if (stateMap.user.authenticated) {
            //This first bit sets the last nav in cases where it's never been set before
            //default to one hour ago in case it hasn't ever been set yet or isn't in statemap
            if (!stateMap.lastNav) {
                //Isn't this sketchy?  Is this a date or a moment being set here
                stateMap.lastNav = moment().subtract(3600, 's').toDate();//60 minutes ago          
            }


            var mNow = moment(new Date()); //todays date
            var mLastNav = moment(stateMap.lastNav); // another date
            var duration = moment.duration(mNow.diff(mLastNav));
            var secondsSinceLastNav = duration.asSeconds();

            if (secondsSinceLastNav > 300)//have we checked in the last 5 minutes?
            {
                if (tokenExpired()) {
                    stateMap.user.authenticated = false;
                }

            }
            stateMap.lastNav = new Date();
        }
        //===============================================================

        //Not logged in and trying to go somewhere but authenticate?
        if (!stateMap.user.authenticated) {
            //hide nav
            $("#gz-nav").hide({
                duration: 200
            });


            //page nav to authenticate
            if (ctx.path != '/authenticate/')
                return page('#!/authenticate/');

        } else {
            //logged in so make sure to show toolbar here
            $("#gz-nav").show({
                duration: 200
            });
        }

        next();
    }


    var authenticate = function (ctx) {

        app.authenticate.configModule({
            context: ctx
        });
        app.authenticate.initModule();
    }
  
    var main = function (ctx) {
        app.nav.setSelectedMenuItem('main');
        app.main.configModule({
            context: ctx
        });
        app.main.initModule();
    }

    var settings = function (ctx) {
        app.nav.setSelectedMenuItem('settings');
        app.settings.configModule({
            context: ctx
        });
        app.settings.initModule();
    }

    var notFound = function (ctx) {
        app.fourohfour.configModule({
            context: ctx
        });
        app.fourohfour.initModule();
    }





    return {
        initModule: initModule,
        stateMap: stateMap
    };
    //------------------- END PUBLIC METHODS ---------------------
}());