/**
* Created by robert on 9/15/15.
*/
codeq.makeStateMachine = function(def){
var currState = null;
return {
'transition': function(name){
if(currState !== null) currState.exit();
currState = def[name];
currState.enter();
},
'destroy': function(){
if(currState !== null) currState.exit();
currState = null;
}
}
}
var loginFun = function(){
var identifier = $('#problem_group').val().split('/'),
problem = $('#problems').val();
if (identifier.length < 2) alert('Choose a problem group');
else if (!problem) alert('Choose a problem');
else {
$('#disabled').css('display', '');
codeq.comms.login($('#username').val(), $('#password').val())
.then(function (data) {
$('#disabled').css('display', 'none');
if (data.code !== 0) throw new Error('Login failed, code: ' + data.code + ', message: ' + data.message);
})
.then(function () {
return codeq.comms.getProblem(identifier[0], identifier[1], problem);
})
.then(function (data) {
if (data.code !== 0) throw new Error('Failed to obtain problem data, code: ' + data.code + ', message: ' + data.message);
$('#disabled').css('display', 'none');
switch (identifier[0]) {
case 'prolog':
// TODO: assignment to window for debug only
//$('#screen_login').css('display', 'none');
//$('#screen_prolog').css('display', '');
codeq.globalStateMachine.transition('prolog');
window.phandler = codeq.createPrologHandler(data.data);
break;
case 'python':
// TODO: assignment to window for debug only
//$('#screen_login').css('display', 'none');
//$('#screen_prolog').css('display', '');
codeq.globalStateMachine.transition('prolog');
window.phandler = codeq.createPythonHandler(data.data);
break;
default:
alert('Unknown language: ' + identifier[0]);
break;
}
})
.fail(function (reason) {
$('#disabled').css('display', 'none');
alert('Login request failed: ' + reason);
})
.done();
}
};
codeq.globalStateMachine = codeq.makeStateMachine({
'login':{
'enter': function(){
codeq.comms.connect().then(function () {
return codeq.comms.send({'action': 'list_problems'});//currently problem list and the actual login are still in the same state
}).then(
function success(data) {
var i, groups, group, problems, problem, first_group,
jqGroup = $('#problem_group'),
jqProblems = $('#problems'),
html = [],
mapping = {},
onGroupChange = function () {
var problems = mapping[jqGroup.val()],
html = [],
i, p;
if (problems) {
for (i = 0; i < problems.length; i++) {
p = problems[i];
html.push('\n')
}
}
jqProblems.html(html.join(''));
};
if (data && (data.code === 0)) {
$('#disabled').css('display', 'none');
groups = data.problems;
for (i = 0; i < groups.length; i++) {
group = groups[i];
var identifier = group.identifier.language + '/' + group.identifier.group;
var name = group.name.language + ': ' + group.name.group;
html.push('\n');
mapping[identifier] = group.problems;
}
jqGroup.html(html.join(''));
first_group = html[1];
html = null;
jqGroup.on('click', onGroupChange);
jqGroup.val(first_group);
onGroupChange();
$("#submit").on('click', loginFun);
}
else {
$('#disabled').css('cursor', '');
alert('Obtaining list of problems failed: code=' + data.code + ', reason=' + data.message);
}
},
function failure(reason) {
$('#disabled').css('cursor', '');
alert('Request to obtain list of problems failed: ' + reason);
}
).done();
},
'exit' : function(){
$("#submit").off('click', loginFun);
$("#screen_login").css('display', 'none');
}
},
'prolog':{
'enter': function(){
$('#screen_prolog').css('display', '');
removeFocusFromElements();
problems = codeq.makeStateMachine(substates);
//problems.transition('instructions');
problems.transition('instructions');
},
'exit': function(){
$('#screen_prolog').css('display', 'none');
problems.destroy();
}
}
});
/*
the following variables are used in the sub-state machine representing the 4 different panels in the codeq app
*/
var problems,//this will the actual state machine
description = $('div.col-lg-3.col-md-6.col-sm-12:has(#description)'),//lets actually find the needed divs for later use
code = $('div.col-lg-3.col-md-6.col-sm-12:has(#code_editor)'),
consoleDiv = $('div.col-lg-3.col-md-6.col-sm-12:has(#console)'),//named 'consoleDiv', because 'console' is already in use
info = $('div.col-lg-3.col-md-6.col-sm-12:has(#info)'),
//some functions used inside the enter and exit functions of the state machine
eventName = 'mousedown',//event name of the event which will trigger the transition between these substates
mouseDownEventFunctionDescription = function(){
problems.transition('instructions');
},
mouseDownEventFunctionCode = function(){
problems.transition('code');
},
mouseDownEventFunctionConsole = function(){
problems.transition('console');
},
mouseDownEventFunctionInfo = function(){
problems.transition('info');
},
removeListenersFromDivs = function(){
description.off(eventName,mouseDownEventFunctionDescription);
code.off(eventName,mouseDownEventFunctionCode);
consoleDiv.off(eventName,mouseDownEventFunctionConsole);
info.off(eventName,mouseDownEventFunctionInfo);
},
removeBlockClassesFromDivs = function(){
description.removeClass('block');
code.removeClass('block');
consoleDiv.removeClass('block');
info.removeClass('block');
},
removeChangedClassesFromDivs = function(){
description.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');//these class names were chosen for the view where the screen is partitioned in 4 quarters (2 by 2)
code.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
consoleDiv.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
info.removeClass('block-focus block-less-width block-less-height block-less-everything').addClass('block');
},
setTransitionsBetweenDivs = function(current){
if(current !== description)description.on(eventName,mouseDownEventFunctionDescription);
if(current !== code)code.on( eventName,mouseDownEventFunctionCode);
if(current !== info)info.on( eventName,mouseDownEventFunctionInfo);
if(current !== consoleDiv)consoleDiv.on( eventName,mouseDownEventFunctionConsole);
},
removeFocusFromElements = function(){
},
//the states of the sub-state machine
substates = {
'instructions':{
'enter': function(){
removeBlockClassesFromDivs();
description.addClass('block-focus');
code.addClass('block-less-width');
consoleDiv.addClass('block-less-height');
info.addClass('block-less-everything');
setTransitionsBetweenDivs(description);
},
'exit': function(){
removeFocusFromElements();
removeChangedClassesFromDivs();
removeListenersFromDivs();
}
},
'code':{
'enter': function(){
removeBlockClassesFromDivs();
description.addClass('block-less-width');
code.addClass('block-focus');
consoleDiv.addClass('block-less-everything');
info.addClass('block-less-height');
setTransitionsBetweenDivs(code);
},
'exit': function(){
removeFocusFromElements();
removeChangedClassesFromDivs();
removeListenersFromDivs();
}
},
'info':{
'enter': function(){
removeBlockClassesFromDivs();
description.addClass('block-less-everything');
code.addClass('block-less-height');
consoleDiv.addClass('block-less-width');
info.addClass('block-focus');
setTransitionsBetweenDivs(info);
},
'exit': function(){
removeFocusFromElements();
removeChangedClassesFromDivs();
removeListenersFromDivs();
}
},
'console':{
'enter': function(){
removeBlockClassesFromDivs();
description.addClass('block-less-height');
code.addClass('block-less-everything');
consoleDiv.addClass('block-focus');
info.addClass('block-less-width');
setTransitionsBetweenDivs(consoleDiv);
},
'exit': function(){
removeFocusFromElements();
removeChangedClassesFromDivs();
removeListenersFromDivs();
}
}
};