define(['jquery',
  'core/log',
  'core/ajax',
  'mod_minilesson/definitions',
  'mod_minilesson/pollyhelper',
  'mod_minilesson/ttrecorder',
  'mod_minilesson/animatecss',
  'core/str',
  'core/notification'
], function ($, log, Ajax, def, polly, ttrecorder, anim, str, notification) {
    "use strict"; // jshint ;_;

  /*
  This file is to manage the quiz stage
   */

    log.debug('MiniLesson Speechcards: initialising');

    return {

      //for making multiple instances
        clone: function () {
            return $.extend(true, {}, this);
        },

        init: function (index, itemdata, quizhelper) {

            this.init_app(index, itemdata, quizhelper);
        },

        init_app: function (index, itemdata, quizhelper) {

            console.log(itemdata);

            var app = {
                passmark: 90,
                pointer: 1,
                jsondata: null,
                props: null,
                dryRun: false,
                language: 'en-US',
                terms: [],
                phonetics: [],
                displayterms: [],
                results: [],
                controls: {},
                ttrec: null, //a handle on the tt recorder
                strings: {},

                init: function () {

                  //init terms
                    for (var i = 0; i < itemdata.sentences.length; i++) {
                        app.terms[i] = itemdata.sentences[i].sentence;
                        app.phonetics[i] = itemdata.sentences[i].phonetic;
                        app.displayterms[i] = itemdata.sentences[i].prompt;
                    }
                    app.language = itemdata.language;

                  //anim
                    var animopts = {};
                    animopts.useanimatecss = quizhelper.useanimatecss;
                    anim.init(animopts);

                    this.init_controls();
                    this.init_strings();
                    this.initComponents();
                    this.register_events();
                },

                init_controls: function () {
                    app.controls = {};
                    app.controls.star_rating = $("#" + itemdata.uniqueid + "_container .minilesson_star_rating");
                    app.controls.next_button = $("#" + itemdata.uniqueid + "_container .minilesson-speechcards_nextbutton");
                    app.controls.slider = $("#" + itemdata.uniqueid + "_container .minilesson_speechcards_target_phrase");
                },
                init_strings: function () {
                    var app = this;
                    str.get_strings([
                    { "key": "nextlessonitem", "component": 'mod_minilesson' },
                    { "key": "confirm_desc", "component": 'mod_minilesson' },
                    { "key": "yes", "component": 'moodle' },
                    { "key": "no", "component": 'moodle' },
                    ]).done(function (s) {
                        var i = 0;
                        app.strings.nextlessonitem = s[i++];
                        app.strings.confirm_desc = s[i++];
                        app.strings.yes = s[i++];
                        app.strings.no = s[i++];
                    });
                },
                next_question: function () {
                    var stepdata = {};
                    stepdata.index = index;
                    stepdata.hasgrade = true;
                    stepdata.totalitems = app.terms.length;
                    stepdata.correctitems = app.results.filter(function (e) {
                        return e.points > 0; }).length;
                    stepdata.grade = Math.round((stepdata.correctitems / stepdata.totalitems) * 100);
                    quizhelper.do_next(stepdata);
                },
                register_events: function () {

                    $("#" + itemdata.uniqueid + "_container .minilesson_nextbutton").on('click', function (e) {
                        if (app.results.length <= app.terms.length) {
                            notification.confirm(
                                app.strings.nextlessonitem,
                                app.strings.confirm_desc,
                                app.strings.yes,
                                app.strings.no,
                                function () {
                                    app.next_question();
                                }
                            );
                        } else {
                            app.next_question();
                        }
                    });

                    app.controls.next_button.click(function () {
                      //user has given up ,update word as failed
                        app.check(false);

                      //transition if required
                        if (app.is_end()) {
                            setTimeout(function () {
                                app.do_end();
                            }, 200);
                        } else {
                            app.controls.next_button.prop("disabled", true);
                            app.controls.next_button.children('.fa').removeClass('fa-times');
                            app.controls.next_button.children('.fa').addClass('fa-spinner fa-spin');
                            setTimeout(function () {
                                app.controls.next_button.children('.fa').removeClass('fa-spinner fa-spin');
                                app.controls.next_button.children('.fa').addClass('fa-times');
                                app.controls.next_button.prop("disabled", false);
                                app.do_next();
                            }, 200);
                        }

                    });
                },

                initComponents: function () {

                    var theCallback = function (message) {

                        switch (message.type) {
                            case 'recording':

                            break;

                            case 'speech':
                                log.debug("speech at speechcards");
                                var speechtext = message.capturedspeech;
                                var spoken_clean = quizhelper.cleanText(speechtext);
                                var correct_clean = quizhelper.cleanText(app.terms[app.pointer - 1]);
                                var correctphonetic = app.phonetics[app.pointer - 1];
                                log.debug('speechtext:', speechtext);
                                log.debug('spoken:', spoken_clean);
                                log.debug('correct:', correct_clean);
                              //Similarity check by character matching
                                var similarity_js = quizhelper.similarity(spoken_clean, correct_clean);
                                log.debug('JS similarity: ' + spoken_clean + ':' + correct_clean + ':' + similarity_js);

                              //Similarity check by direct-match/acceptable-mistranscription
                                if (similarity_js >= app.passmark ||
                                app.wordsDoMatch(spoken_clean, correct_clean)) {
                                      log.debug('local match:' + ':' + spoken_clean + ':' + correct_clean);
                                      app.showStarRating(100);
                                      app.flagCorrectAndTransition();
                                      return;
                                }

                              //Similarity check by phonetics(ajax)
                                quizhelper.checkByPhonetic(correct_clean, spoken_clean, correctphonetic, app.language).then(function (similarity_php) {
                                    if (similarity_php === false) {
                                        return $.Deferred().reject();
                                    } else {
                                        log.debug('PHP similarity: ' + spoken_clean + ':' + correct_clean + ':' + similarity_php);

                                        if (similarity_php >= app.passmark) {
                                            app.showStarRating(similarity_php);
                                            app.flagCorrectAndTransition();
                                        } else {
                                          //show the greater of the ratings
                                            app.showStarRating(Math.max(similarity_js, similarity_php));
                                        }
                                    } //end of if check_by_phonetic result
                                }); //end of check by phonetic
                        } //end of switch message type
                    };

                  //init tt recorder
                    var opts = {};
                    opts.uniqueid = itemdata.uniqueid;
                    opts.callback = theCallback;
                    opts.stt_guided = quizhelper.is_stt_guided();
                    app.ttrec = ttrecorder.clone();
                    app.ttrec.init(opts);
                  //init prompt for first card
                  //in some cases ttrecorder wants to know the target
                    app.ttrec.currentPrompt = app.displayterms[app.pointer - 1];

                  //init progress dots
                    app.progress_dots(app.results, app.terms);

                    app.initSlider();


                },

                initSlider: function () {
                    app.controls.slider.text(app.displayterms[app.pointer - 1]);
                    app.controls.slider.show();
                },

                writeCurrentTerm: function () {
                  /*
                  app.controls.slider.toggle("slide",{direction:"left"});
                  app.controls.slider.text(app.displayterms[app.pointer - 1]);
                  app.controls.slider.toggle("slide",{direction:"right"})
                   */
                    anim.do_animate(app.controls.slider, 'zoomOut animate__faster', 'out').then(
                        function () {
                            app.controls.slider.text(app.displayterms[app.pointer - 1]);
                            anim.do_animate(app.controls.slider, 'zoomIn animate__faster', 'in');
                        }
                    );
                },

                flagCorrectAndTransition: function () {

                  //update students word log if matched
                    app.check(true);

                  //transition if required
                    if (app.is_end()) {
                        setTimeout(function () {
                            app.do_end();
                        }, 700);
                    } else {
                        setTimeout(function () {
                            app.do_next();
                        }, 700);
                    }

                },

                wordsDoMatch: function (phraseheard, currentphrase) {
                  //lets lower case everything
                    phraseheard = quizhelper.cleanText(phraseheard);
                    currentphrase = quizhelper.cleanText(currentphrase);
                    if (phraseheard == currentphrase) {
                        return true;
                    }
                    return false;
                },


                showStarRating: function (similarity) {
                  //how many stars code
                    var stars = [true, true, true];
                    if (similarity < app.passmark) {
                        stars = [true, true, false];
                    }
                    if (similarity < .75) {
                        stars = [true, false, false];
                    }
                    if (similarity < 0.5) {
                        stars = [false, false, false];
                    }

                  //prepare stars html
                    var code = "";
                    stars.forEach(function (star) {
                        if (star === true) {
                            code += '<i class="fa fa-star"></i>';
                        } else {
                            code += '<i class="fa fa-star-o"></i>';
                        }
                    });

                    app.controls.star_rating.html(code);
                },

                check: function (correct) {
                    var points = 1;
                    if (correct == true) {
                        points = 1;
                    } else {
                        points = 0;
                    }
                    var result = {
                        points: points
                    };
                    app.results.push(result);
                },

                do_next: function () {
                    app.pointer++;
                    app.progress_dots(app.results, app.terms);
                    app.clearStarRating();
                    if (!app.is_end()) {
                        app.writeCurrentTerm();
                      //in some cases ttrecorder wants to know the target
                        if (quizhelper.use_ttrecorder()) {
                            app.ttrec.currentPrompt = app.displayterms[app.pointer - 1];
                        }
                    } else {
                        app.do_end();
                    }
                },

                clearStarRating: function () {
                    app.controls.star_rating.html('· · ·');
                },

                do_end: function () {
                    app.next_question();
                },

                is_end: function () {
                  //pointer is 1 based but array is, of course, 0 based
                    if (app.pointer <= app.terms.length) {
                        return false;
                    } else {
                        return true;
                    }
                },

                progress_dots: function (results, terms) {

                    var code = "";
                    var color = "";
                    terms.forEach(function (o, i) {
                        color = "#E6E9FD";
                        var icon = "fa fa-square";
                        if (results[i] !== undefined) {
                            if (results[i].points) {
                                color = "#74DC72";
                                icon = "fa fa-check-square";
                            } else {
                                color = "#FB6363";
                                icon = "fa fa-window-close";
                            }
                        }
                        code += '<i style="color:' + color + ';" class="' + icon + ' pl-1"></i>';
                    });

                    $("#" + itemdata.uniqueid + "_container .minilesson_progress_dots").html(code);

                },
            }; //end of app definition
            app.init();

        } //end of init_App


    }; //end of return value
});