﻿var VoiceSearch = {
    init: function () {
        var ua = navigator.userAgent.toLowerCase();
        var isAndroid = ua.indexOf("android") > -1 || ua.indexOf("mobile") > -1;

        if (isAndroid) {
            return;
        }

        var self = this;
        this.voiceSearchLocation = {
            HEADER_FLYOUT: "header_flyout",
            HEADER_SIMPLE: "header_simple",
            FOOTER: "footer",
            HOME: "home"
        }
        this.$body = $("body");
        this.isCoveoSearchEnabled = this.$body.hasClass("coveo-search-enabled");
        this.isCapturing = false;
        this.$searchForm = $("#connector-search");
        this.$microphoneBtn = (this.isCoveoSearchEnabled) ? $('#voice_search_trigger') : $('#voice_search');
        this.$microphoneBtnFooter = $('#voice_search_trigger_footer');
        this.$microphoneBtnHome = $("#voice_search_trigger_home");
        this.$topNavSearch = $('#connector-search [type="search"]');
        this.$footerSearch = $('.search-bar-footer [type="search"]');
        this.$homeSearch = $('.home-search [type="search"]');
        this.$footerReset = $(".search-bar-footer").find("[type='reset']");
        this.$resetButton = $('#connector-search [type="reset"]').eq(0);
        this.$voiceSearchOverlay = $("#voice-search-overlay");
        this.$voiceSearchOverlayQuery = this.$voiceSearchOverlay.find("p");
        this.$voiceSearchOverlayClose = this.$voiceSearchOverlay.find("#voiceSearchCloseBtn");   

        this.language = (document.documentElement.lang !== "fr" && typeof document.documentElement.lang !== "undefined") ? "en-CA" : "fr-CA";
        this.speechRecognitionCheck = window.SpeechRecognition || window.webkitSpeechRecognition || null;

        this.isMicrophoneAvailable = false;
        this.isVoiceSearchEnabled = false;

        if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
            navigator.mediaDevices.enumerateDevices()
                .then(function (devices) {
                    for (var i = 0; i < devices.length; i++) {
                        var device = devices[i];

                        if (device.kind === "audioinput" && !self.isMicrophoneAvailable) {
                            self.isMicrophoneAvailable = true;
                            if (self.speechRecognitionCheck
                                && navigator.mediaDevices.getUserMedia
                                && self.isMicrophoneAvailable
                                /*&& location.protocol.toLowerCase().indexOf("https") > -1*/) {
                                self.setupRecognition();
                            }

                            $(document).keyup(function (e) {
                                if (e.which == 27) {
                                    self.stopCapture();
                                }
                            });
                        }
                    }
                });
        }
    },

    setupRecognition: function () {
        var self = this;
        this.searchLocation = "";

        self.recognition = new this.speechRecognitionCheck();

        navigator.permissions.query({ name: 'microphone' }).then(function (permissionStatus) {
            console.log('Microphone permission state:', permissionStatus.state);

            if (permissionStatus.state !== "denied") {
                self.$body.addClass("voice-search-enabled");
            }
        });

        $(this.$microphoneBtn).click(function () {
            if (self.isCoveoSearchEnabled)
                self.searchLocation = self.voiceSearchLocation.HEADER_FLYOUT;
            else
                self.searchLocation = self.voiceSearchLocation.HEADER_SIMPLE;

            self.microphoneClickHandler();
        });

        $(this.$microphoneBtnFooter).click(function () {
            self.searchLocation = self.voiceSearchLocation.FOOTER;
            self.microphoneClickHandler();
        });

        $(this.$microphoneBtnHome).click(function () {
            self.searchLocation = self.voiceSearchLocation.HOME;
            self.microphoneClickHandler();
        });

        $(this.$voiceSearchOverlayClose).focusout(function () {
            self.voiceSearchReturnFocus();
        });

        this.recognition.onresult = (function (event) {

            if (typeof self.$voiceSearchOverlay !== "undefined"
                && !self.$voiceSearchOverlay.hasClass("interim-recognition-on")) {
                self.$voiceSearchOverlay.addClass("interim-recognition-on");
            }

            switch (self.searchLocation) {
                case self.voiceSearchLocation.HEADER_FLYOUT: {
                    self.populateSpeechQueryCoveo(event);
                    break;
                }
                case self.voiceSearchLocation.FOOTER: {
                    self.populateFooterSpeechQuery(event);
                    break;
                }
                case self.voiceSearchLocation.HOME: {
                    self.populateHomeSpeechQuery(event);
                    break;
                }
                case self.voiceSearchLocation.HEADER_SIMPLE:
                    {
                        self.populateSpeechQuerySimpleHeader(event);
                        break;
                    }
            }
        });

        this.recognition.onspeechend = (function (event) {
            self.stopCapture();
        });

        self.$voiceSearchOverlayClose.on("click", function () {
            self.stopCapture();
        });

        this.recognition.onerror = (function (event) {
            console.log("web speech error: " + event.error);
            self.stopCapture();
        });
    },

    startCapture: function () {

        this.$body.addClass("voice-recording-on voice-active");
        this.recognition.lang = this.language;
        this.recognition.interimResults = true;

        this.recognition.start();
        this.isCapturing = true;
    },

    stopCapture: function () {

        this.$body.removeClass("voice-recording-on voice-active");

        if (typeof this.recognition !== "undefined") {
            this.recognition.stop();
        }
        this.isCapturing = false;
    },

    toggleCapture: function () {
        if (!this.isCapturing) {
            this.startCapture();
        } else {
            this.stopCapture();
        }
    },

    microphoneClickHandler: function () {

        var self = this;

        if (self.isVoiceSearchEnabled === false) {
            navigator.mediaDevices.getUserMedia({ audio: true }).then(function (stream) {

                self.isVoiceSearchEnabled === true;
                self.toggleCapture();
                self.voiceSearchFocusModal();

            }).catch(function (err) {
                self.$body.removeClass("voice-search-enabled");
            });

        } else {
            self.toggleCapture();
        }

        typeof s_oTrackPage == "function" && s_oTrackPage({
            s_oAPT: "095-0-0"
        })

        self.voiceSearchFocusModal();

    },

    voiceSearchFocusModal: function () {
        setTimeout(function () {
            var self = this;
            voiceSearchModal = document.getElementById("voice-search-overlay");
            voiceSearchClose = document.getElementById("voiceSearchCloseBtn");
            if (window.getComputedStyle(voiceSearchModal).visibility !== "hidden") {
                self.voiceSearchClose.focus();
            }
        }, 100);
    },

    voiceSearchReturnFocus: function () {
        voiceSearchBtn = document.getElementById("voice_search");

        if (window.getComputedStyle(voiceSearchBtn).visibility !== "hidden") {
            voiceSearchBtn.focus();
        }
    },

    coveoFlyoutMicClickHandler: function (event) {
        this.searchLocation = this.voiceSearchLocation.HEADER_FLYOUT;
        this.microphoneClickHandler();
    },

    populateHomeSpeechQuery: function (event) {

        var speechQuery = this.updateOverlay(event);
        this.$homeSearch.val(speechQuery.toLowerCase()).focus();
        this.$homeSearch.keydown();
    },

    populateFooterSpeechQuery: function (event) {

        var speechQuery = this.updateOverlay(event);

        this.$footerSearch.val(speechQuery.toLowerCase()).focus();

        this.$resetButton.addClass("active");
        this.$searchForm.addClass("active");
        $(".search-bar-footer").submit();
    },

    populateSpeechQuerySimpleHeader: function (event) {
        var speechQuery = this.updateOverlay(event);
        this.$topNavSearch.val(speechQuery.toLowerCase());
        $("#topNavSearch").val(speechQuery.toLowerCase());
        this.$searchForm.submit();
    },

    populateSpeechQueryCoveo: function (event) {

        var speechQuery = this.updateOverlay(event);

        this.$body.addClass("search-bar-active");
        Coveo.get(Coveo.$$(document).find('.CoveoFlyoutController'), 'FlyoutController').setKeywords(speechQuery.toLowerCase());
        bell.coveoFlyout.$coveoSearchInput.focus();
    },

    updateOverlay: function (event) {

        var query = '';

        for (var i = 0; i < event.results.length; i++) {
            if (event.results[i].isFinal) {
                query = event.results[i][0].transcript;
                this.$voiceSearchOverlayQuery.text("");

                if (typeof this.$voiceSearchOverlay !== "undefined") {
                    this.$voiceSearchOverlay.removeClass("interim-recognition-on");
                }
            } else {
                query += event.results[i][0].transcript;
                this.$voiceSearchOverlayQuery.text(query);
            }
        }

        return query;
    },
    /**
     * Prevents form from submitting if query is empty.
     * @param {object} event - Event handler
     */
}

$(document).ready(function () {
    VoiceSearch.init();
})