Home Reference Source

app/generator.js

/** Modular Zeeguu Exercise Generator @authors Martin Avagyan, Vlad Turbureanu
 *  @initialize it using: new Generator(args);
 *  @param args is matrix of exercise name and number of bookmarks,
 *         example: [[1,3],[2,4]] 3 bookmarks for ex1 and 4 bookmarks for ex2
 *  @customize it by using prototypal inheritance
 **/

import $ from 'jquery';
import Ex1 from './exercises/ex1';
import Ex2 from './exercises/ex2';
import Ex3 from './exercises/ex3';
import Ex4 from './exercises/ex4';
import ProgressBar from './progress_bar';
import events from './pubsub';
import swal from 'sweetalert';
import Session from './session';
import {Loader} from './loader';
import Util from './util';
import Validator from './validator';
import TDS from './the_distraction_shield_extension';


 
var Generator = function(set,parentInvocation = "NA"){
    this.init(set,parentInvocation);
};

Generator.prototype = {
    /************************** SETTINGS ********************************/
    data: 0,		//bookmakrs from zeeguu api
    set: 0,			//matrix for initialaizer
    index: 0,		//current index from set
    startTime: new Date(),
    session: Session.getSession()  , //Example of session id 34563456 or 11010001
    templateURL: 'static/template/exercise/exercise.html',
    parentInvocation: '',

    /**
     *	Saves the common dom in chache
     **/
    cacheDom: function(){
    },

    /**
     * The function caches imports in local scope for later to be referenced as a string
     * */
    cacheExerciseImports: function(){
        this.Ex1 = Ex1;
        this.Ex2 = Ex2;
        this.Ex3 = Ex3;
        this.Ex4 = Ex4;
    },

    /**
     *	Generator initialaizer
     **/
    init: function(set,parentInvocation){
        this.set = set;
        var _this = this;

        this.validator = new Validator(set);

        this.parentInvocation = parentInvocation;
        // "bind" event
        this.$eventFunc = function(){_this.nextEx()};
        events.on('exerciseCompleted',this.$eventFunc);

        this.start();
    },

    restart: function(){
        this.start();
    },

    /**
     *	Call to load the data from API
     **/
    start: function ()
    {
        let _this= this;
        //Callback wait until the bookmarks are loaded
        this.validator.getValidBookMarks(function(ldata) {
            _this.data = (ldata);
            _this.set = _this.validator.validSet;
            //Terminate generator if not enough bookmarks
            if(_this.set ==null || _this.set <=0) {
                _this.terminateGenerator();
                return;
            }
            //Loads the HTML general exercise template from static
            $.when(Loader.loadTemplateIntoElem(_this.templateURL,$("#main-content"))).done(function(){
                // Create the DOM and start the generator
                ProgressBar.init(0, _this.validator.validSize);
                _this.cacheDom();
                _this.cacheExerciseImports();
                _this._constructor();
            });
        });
    },

    filterArray: function(bookmarksData)
    {
        for(var i = 0; i< bookmarksData.length;i++){
            var tempIdx = indexOf(bookmarksData[i]);
            if(tempIdx == -1 || tempIdx == i){
                continue;
            }
            bookmarksData.splice(i, 1);
        }
        return bookmarksData;
    },
    /**
     *	The main constructor
     **/
    _constructor: function (){
        this.index = 0;
        this.startTime = new Date();
        this.nextEx();
    },

    /**
     *	Add Ex here
     **/
    nextEx: function(){
        if(this.index >= this.set.length){
            this.onExSetComplete();
            return;
        }
        var ex = this.set[this.index][0];
        var size = this.set[this.index][1];
        var startingIndex = Util.calcSize(this.set,this.index);

        this.$currentEx = null;
        delete this.$currentEx;
        //Local scope reference
        this.$currentEx = new (this['Ex'+ex])(this.data,startingIndex,size);
        this.index++;
    },
    /**
     *	Request the submit API
     **/
    submitResults: function(){
        //TODO submit user feedback if any
    },

    /**
     *	When the ex are done perform an action
     **/
    onExSetComplete: function (){
        var _this = this;
        var redirect = TDS.distractionShieldOriginalDestination();
        var finalAction = this.finalActions(redirect,this.parentInvocation);
		_this.submitResults();
        swal({
                title: "You rock!",
                text: "That took less than "+ Util.calcTimeInMinutes(_this.startTime) + ". practice more?",
                type: "success",
                showCancelButton: true,
                confirmButtonColor: "#7eb530",
                confirmButtonText: "Let's do it!",
                cancelButtonText: finalAction.btnText,
                closeOnConfirm: true
            },
            function(isConfirm){
                if(isConfirm){
                    ProgressBar.terminate();
                    _this.restart();
                    return;
                }
                _this.terminateGenerator();
                finalAction.actionFunc();
            });
    },

    /**
     * Text and the action that the secondary button should perform
     * @param {String} redirect url
     * @param {String} parentInvocation, who to emit when the action is done
     * @return {Object}, text of the action and the action function
     * */
    finalActions: function (redirect,parentInvocation) {
        let secondaryBtn = 'Go home!';
        let actionFunction = ()=> {_this.invokeParent();};

        //If the redirect url is present
        if(redirect!=null){
            secondaryBtn = "Take me away!";
            actionFunction = ()=> { window.location = redirect;};
        }
        //If there is no home available create home
        else if(parentInvocation === "NA"){
            actionFunction = ()=> {
                let redirect = window.location.protocol + "//" + window.location.hostname;
                //Local debuging, wont be part of final code
                window.location.href = (redirect === "http://127.0.0.1") ? redirect + ":5000" : redirect;
            };
        }
        return {btnText:secondaryBtn, actionFunc:actionFunction};
    },

    terminateGenerator: function(){
        events.off('exerciseCompleted',this.$eventFunc);
        ProgressBar.terminate();
        events.emit('generatorCompleted');
    },
    invokeParent: function(){
        events.emit(this.parentInvocation);
    },
};

export default Generator;