/* CodeQ: an online programming tutor. Copyright (C) 2015 UL FRI This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ /** * Created by robert on 9/15/15. * */ (function() { "use strict"; codeq.makeStateMachine = function (def) { var currState = null; return { 'transition': function (name) { var newState = def[name]; if (!newState) { codeq.log.error('Cannot transition to state ' + name + ': it is not defined'); return; } if (newState === currState) { codeq.log.info('Will not transition between identical states: ' + name); return; } if (currState !== null) currState.exit(); currState = newState; currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); }, 'destroy': function () { if (currState !== null) currState.exit(); currState = null; }, 'register': function (name, state) { if (name in def) codeq.log.error('The state ' + name + ' is already registered, overriding'); def[name] = state; } } }; //the global state machine is a bit different - so it'll be implemented here var makeGlobalStateMachine = function (def) { var currState = null, waitingState = null; // state hidden with a modal form var stateChangeFun = function historyStateChangeHandler() { var historyState = History.getState(); codeq.globalStateMachine.actualTransition.apply(codeq.globalStateMachine, $.merge([historyState.data.state] ,historyState.data.params)); }; History.Adapter.bind(window, 'statechange', stateChangeFun); //prepare the history state change listener return { 'transition': function (name) { var newState = def[name]; if (!newState) { codeq.log.error('Cannot transition to state ' + name + ': it is not defined'); return; } if (newState === currState) { codeq.log.info('Will not transition between identical states: ' + name); return; } if(History.getState().data.state === name) codeq.globalStateMachine.actualTransition.apply(codeq.globalStateMachine,Array.prototype.slice.apply(arguments, [0]));//special case which happens if the user refreshes while in the login screen (history state doesn't change because it goes from login to login and the above listener doesn't trigger) try { History.pushState({'state': name, 'params': Array.prototype.slice.apply(arguments, [1])}, 'CodeQ', '?s=' + name); } catch (e) { codeq.log.error('init: History.pushState() failed for new state ' + name+'. Error:'+e, e); } }, 'destroy': function () { var i; if (currState) currState.exit(); currState = null; if (waitingState) waitingState.exit(); waitingState = null; History.Adapter.unbind(window, 'statechange', stateChangeFun); }, 'register': function (name, state, props) { if (name in def) codeq.log.error('The state ' + name + ' is already registered, overriding'); def[name] = state; }, 'actualTransition': function (name) { //check if we are logged in - if we aren't we will always transition to the login state if(!codeq.comms.getSid() && name !== "signup" && name !== "aailogin"){//we can of course enter the signup/aailogin state even if not logged in name = 'login';//this will cause the following code to transition to the login state instead of the original one given } var newState = def[name];//if the newState is not the same as the old or if it doesn't exist at all is already checked at this point if (currState) { if (newState.isModal) { if (currState.isModal) currState.exit(); else { waitingState = currState; waitingState.jqScreen.css('display', 'none'); } currState = newState; currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); } else { currState.exit(); currState = newState; if (waitingState === newState) { waitingState.jqScreen.css('display', ''); waitingState = null; } else { if (waitingState) { waitingState.exit(); waitingState = null; } currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); } } } else { currState = newState; currState.enter.apply(currState, Array.prototype.slice.apply(arguments, [1])); } } } }; codeq.globalStateMachine = makeGlobalStateMachine({}); //setup all the buttons in the banner $('#navigation-home').on('click', function(e){ codeq.globalStateMachine.transition('language'); e.preventDefault(); }); $('#navigation-problem_list').on('click', function(e){ codeq.globalStateMachine.transition('problem_list'); e.preventDefault(); }); $('#navigation-python').on('click', function(e){ codeq.globalStateMachine.transition('python'); e.preventDefault(); }); $('#navigation-prolog').on('click', function(e){ codeq.globalStateMachine.transition('prolog'); e.preventDefault(); }); $('#navigation-robot').on('click', function(e){ codeq.globalStateMachine.transition('robot'); e.preventDefault(); }); $('#navigation-logout').on('click', function(e){ codeq.comms.logout() .then(function (data) { codeq.comms.disconnect(); }) .fail(function (reason) { codeq.log.error('Logout failed: ' + reason); }) .done(); /*leaving this here if we later decide to enable saml_logout if(codeq.samlLogin){ codeq.comms.samlLogout() .then(function (data) { console.log(data); codeq.comms.disconnect(); }) .fail(function (reason) { console.log(reason); }) .done(); }else{ codeq.comms.logout() .then(function (data) { console.log(data); codeq.comms.disconnect(); }) .fail(function (reason) { console.log(reason); }) .done(); }*/ codeq.globalStateMachine.transition('login'); //codeq.globalStateMachine.transition('login'); e.preventDefault();//prevent this since we'll trigger a page reload otherwise }); $('#navigation-profile').on('click', function(e){ codeq.globalStateMachine.transition('profile'); e.preventDefault();//prevent this since we'll trigger a page reload otherwise }); $('#navigation-about').on('click', function(e){ codeq.globalStateMachine.transition('about'); e.preventDefault();//prevent this since we'll trigger a page reload otherwise }); $('#navigation-change-password').on('click', function(e){ codeq.globalStateMachine.transition('changePassword'); e.preventDefault();//prevent this since we'll trigger a page reload otherwise }); $('#navigation-settings').on('click',function(e){ codeq.globalStateMachine.transition('settings'); e.preventDefault(); }); })();