/**
 * /sQuiz/sQuiz.js
 * @version 1.4
 * @desc sQuiz main class file
 * @author Fándly Gergő Zoltán (gergo@systemtest.tk, systemtest.tk)
 * @copy 2017 Fándly Gergő Zoltán
 * License:
    sQuiz for creating small jQuery based quizs in an implementable way
    Copyright (C) 2017  Fándly Gergő Zoltán

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 **/

(function($){
    /**
     * sQuiz(element, quiz)
     * @desc Creating a new quiz based on a json file
     * @param $ element Container in which the quiz will be running
     * @param string quiz A JSON string/JSON object containing an sQuiz parameter list
     */
    $.sQuiz=function(element, quiz){
        this.element=(element instanceof $)?element:$(element);
        this.quiz=(typeof quiz=="object")?quiz:JSON.parse(quiz);
        this.current=-1;
        this.currentQustion;
        this.reg;
        this.countdown;
        this.elapsedPerTest=(this.quiz.timeLimitPerTest>0)?0:-2;
        this.elapsed=(this.quiz.timeLimit>0)?0:-2;
        this.answers=[];
        this.quizDoneCallback;
        this.quizDoneOptions;
    };
    
    
    $.sQuiz.prototype={
        /**
         * sQuiz.setRegionalization(lang)
         * @desc Assing an Object which has all the needed vars for language (startQuiz, timeRemaining, etc. Full list in /sQuiz/lang.json), or leave it on default for English
         * @param object lang Object storing language settings
         */
        setRegionalization: function(lang){
            this.reg=lang;
        },
        
        /**
         * sQuiz.setQuizDoneCallback(callback)
         * @desc Assign a function to run when the quiz is finished
         * @param function callback Function to call
         */
        setQuizDoneCallback: function(callback){
            this.quizDoneCallback=callback;
        },
         
        /**
        * sQuiz.setQuizDoneOptions(options)
        * @desc Set options to offer when quiz is finished. Set download to true, to offer downloading. Set upload to true, to offer online submit to upload_url. Set custom to a JS function call to do self made stuff. Custom action's label regionalization is customAction.
        * @param object options Object containing the settings
        */
        setQuizDoneOptions: function(options){
            this.quizDoneOptions=options;
        },
        
        /**
         * sQuiz.secToTime(sec)
         * @desc Function for converting seconds to traditional MM:SS format
         * @param int sec Seconds to convert
         * @return string
         */
         secToTime: function(sec){
             var mins=Math.floor(sec/60);
             var secs=sec%60;
             var minstr=(mins.toString().length==1)?"0"+mins.toString():mins.toString();
             var secstr=(secs.toString().length==1)?"0"+secs.toString():secs.toString();
             var time=minstr+":"+secstr;
             return time;
         },
        
        /**
         * sQuiz.quizDone()
         * @desc Function to call when a test is finished
         */
        quizDone: function(){
            var points=0;
            $.each(this.answers, function(key, val){
                if(val.correct){
                    points++;
                }
            });
            
            var self=this;
            this.element.slideUp(function(){
                var buttons="<div class=\"sq sq-menu\">";
                if(self.quizDoneOptions.download==true){
                    buttons+="<button class=\"sq sq-big\" type=\"button\" id=\"sqDownloadResults\"><i class=\"fa fa-save\"></i>"+self.reg.downloadResults+"</button>";
                }
                if(self.quizDoneOptions.upload==true){
                    buttons+="<button class=\"sq sq-big\" type=\"button=\" id=\"sqUploadResults\"><i class=\"fa fa-upload\"></i>"+self.reg.uploadResults+"</button>";
                }
                if(self.quizDoneOptions.custom!=undefined){
                    buttons+="<button class=\"sq sq-big\" type=\"button=\" id=\"sqCustomAction\" onclick=\""+self.quizDoneOptions.custom+"\">"+self.reg.customAction+"</button>";
                }
                buttons+="</div>";
                
                self.element.html("<h2>"+self.reg.quizFinished+"</h2><hr class=\"sq sq-placeholder\" style=\"height: 10vh\"><div class=\"sq sq-center\"><h3>"+self.reg.resultsGot+": <b>"+points.toString()+"/"+self.quiz.questions.length+"</b></h3><br><br>"+buttons);
                
                $("#sqDownloadResults").on("click", function(){
                    //store quiz name, description and done date in result file
                    var result={
                        "quizName": self.quiz.name,
                        "quizDesc": self.quiz.description,
                        "doneDate": Date.now(),
                        "answers": self.answers
                    };
                    var json=JSON.stringify(result);
                    var send="text/json;charset=utf-8,"+encodeURIComponent(json);
                    $("<a href=\"data:"+send+"\" download=\""+self.quiz.name+"_answers_sQuiz.json\"></a>")[0].click();
                });
                $("#sqUploadResults").on("click", function(){
                    var result={
                        "quizName": self.quiz.name,
                        "quizDesc": self.quiz.description,
                        "doneDate": Date.now(),
                        "answers": self.answers
                    };
                    var json=JSON.stringify(result);
                    var submitter=prompt(self.reg.yourname+":");
                    $.ajax({
                        url: (self.quizDoneOptions.upload_url!=undefined)?self.quizDoneOptions.upload_url:"",
                        type: "POST",
                        data: {
                            "submitResult": json,
                            "submitResult_submitter": submitter
                        },
                        success: function(res){
                            alert(self.reg.idForResult+": "+res);
                        }
                    });
                });
                        
                self.element.slideDown();
            });
            
            var result={
                "quizName": self.quiz.name,
                "quizDesc": self.quiz.description,
                "doneDate": Date.now(),
                "answers": self.answers
            };
            if(this.quizDoneCallback!=undefined){
                this.quizDoneCallback(result, this.quiz);
            }
        },
        
        /**
         * sQuiz.nextQuestion()
         * @desc Start the next question. Should be called only internally!
         */
        nextQuestion: function(){
            var self=this;
            this.current++;
            
            if(this.current>=this.quiz.questions.length){
                this.quizDone();
            }
            else{
                var type=this.quiz.questions[this.current].type;
                this.element.slideUp(function(){
                    var timer="<p id=\"sqTimer\">"+(self.quiz.timeLimit>0?"<b>"+self.reg.timeLeft+":</b> <span id=\"sqTimeLeft\"></span><br>":"")+(self.quiz.timeLimitPerTest>0?"<b>"+self.reg.timeLeftPerTest+":</b> <span id=\"sqTimeLeftPerTest\"></span>":"")+"</p>";
                    var submitbutton="<br><br><div class=\"sq sq-center\"><button class=\"sq green sq-big\" id=\"sqSubmitButton\"><i class=\"fa fa-check\"></i>"+self.reg.submit+"</button></div>";
                    self.element.html(timer+"<hr class=\"sq-placeholder\"><div id=\"sqTestArea\" style=\"overflow: auto\"></div>"+submitbutton);
                    self.element.children("#sqTimeLeft").html(self.secToTime(self.timeLimit));
                    self.element.children("#sqTimeLeftPerTest").html(self.secToTime(self.timeLimitPerTest));
                    self.currentQuestion=new $["sQuiz_module_"+type](self, self.quiz.questions[self.current]);
                    
                    $("#sqSubmitButton").on("click", function(){
                        self.currentQuestion.submit();
                        $("#sqSubmitButton").unbind();
                        $("#sqSubmitButton").fadeOut(function(){
                            $(this).html("<i class=\"fa fa-arrow-right\"></i>"+self.reg.nextQuestion);
                            $(this).fadeIn();
                        });
                        $("#sqSubmitButton").on("click", function(){
                            self.nextQuestion();
                        });
                    });
                    
                    self.currentQuestion.load();
                    self.element.slideDown(function(){
                        self.startTimer();
                    });
                });
            }
        },
        
        /**
         * sQuiz.init()
         * @desc set up styles and so for the container
         */
        init: function(){
            var self=this;
            
            if(this.reg==undefined){
                this.reg={
                    "downloadResults":"Download results",
                    "uploadResults":"Upload results",
                    "customAction":"Custom action name goes here",
                    "quizFinished":"Quiz finished!",
                    "resultsGot":"You've got the following results",
                    "yourname":"Your name",
                    "idForResult":"Share this ID with anybody you want to know your results",
                    "timeLeft":"Time left for entire quiz",
                    "timeLeftPerTest":"Time left for this question",
                    "submit":"Submit",
                    "nextQuestion":"Next question",
                    "startQuiz":"Start quiz",
                    "answer":"Answer"
                };
            }
            
            this.element.hide();
            this.element.addClass("sq sq-container");
            this.element.html("<hr class=\"sq sq-placeholder\" style=\"height: 20vh\"><h2>"+this.quiz.name+"</h2><p>"+this.quiz.description+"</p><hr><div class=\"sq sq-center\"><button class=\"sq sq-big\" id=\"sqStart\">"+this.reg.startQuiz+"</button></div>");
            $("#sqStart").on("click", function(){
                self.nextQuestion();
            });
            this.element.slideDown();
        },
        
        /**
         * sQuiz.startTimer
         * @desc Starts the countdown
         */
        startTimer: function(){
            var self=this;
            this.elapsedPerTest=0;
            if(this.quiz.timeLimitPerTest>0 || this.quiz.timeLimit>0){
                if(self.quiz.timeLimitPerTest>0){
                    self.elapsedPerTest++;
                    self.element.children("#sqTimer").children("#sqTimeLeftPerTest").html(self.secToTime(self.quiz.timeLimitPerTest-self.elapsedPerTest));
                    if(self.elapsedPerTest>=self.quiz.timeLimitPerTest){
                        $("#sqSubmitButton")[0].click();
                    }
                }
                if(self.quiz.timeLimit>0){
                    self.elapsed++;
                    self.element.children("#sqTimer").children("#sqTimeLeft").html(self.secToTime(self.quiz.timeLimit-self.elapsed));
                    if(self.elapsed>=self.quiz.timeLimit){
                        $("#sqSubmitButton")[0].click();
                    }
                }
            }
            this.countdown=window.setInterval(function(self){
                self.elapsedPerTest++;
                if(self.quiz.timeLimitPerTest>0){
                    self.element.children("#sqTimer").children("#sqTimeLeftPerTest").html(self.secToTime(self.quiz.timeLimitPerTest-self.elapsedPerTest));
                    if(self.elapsedPerTest>=self.quiz.timeLimitPerTest){
                        $("#sqSubmitButton")[0].click();
                    }
                }
                if(self.quiz.timeLimit>0){
                    self.elapsed++;
                    self.element.children("#sqTimer").children("#sqTimeLeft").html(self.secToTime(self.quiz.timeLimit-self.elapsed));
                    if(self.elapsed>=self.quiz.timeLimit){
                        $("#sqSubmitButton")[0].click();
                    }
                }
            }, 1000, self);
        },
        
        /**
         * sQuiz.stopTimer
         * @desc Stops the countdown
         */
        stopTimer: function(){
            clearInterval(this.countdown);
        }
    }
}(jQuery));
