var MediaManager = (function () {

    var _self = this;
    var _mPlayer = null;
    var _seekInterval = null;

    var _isLinear = false;

    var _shell_wrapper = $("#shell_wrapper");
    var _pageProgress = $("#pageProgress");
    var _ccText_description = null

    var _data = null;

    var isFirstTimeCall = true;
    var isAudioReplayHit = true;
    var _isMutedByLearners = false;

    var timeline = {
        cTime: 0,
        tTime: 1,
        rTime: 1,
        nodes: null
    }


    this.destroy = function () {
        try {
            if (_mPlayer) {
                _mPlayer.dispose();
                _mPlayer = null;
                _seekInterval = null
            }
        } catch (err) {
            Utils.error("1. MediaManager:  destroy:  ")
        }


        try {
            window.pPlayer.dispose();
            window.vPlayer.dispose();
            window.aPlayer.dispose();
            window.iPlayer.dispose();
        } catch (err) {
            Utils.error("2. MediaManager:  destroy:  ")
        }

        $(".vjs-big-play-button").hide();
        $("#bigPlay_button_holder").hide();
    }



    this.updatePlayer = function (mPlayer) {
        _mPlayer = mPlayer
    }

    this.updateData = function (data) {
        _data = data;
    }

    this.updateMedia = function (data) {

        _shell_wrapper = $("#shell_wrapper");
        try {
            _self.stop();
        } catch (err) {
            console.error(". MediaManager:  updateMedia:  ", err)
        }

        try {
            _ccText_description = $(".ccText_description").empty();
            $(".simple_video_holder").removeClass("disabled")
        } catch (err) {

        }

        _self.updateData(data);
        let _url = data['url'];
        updateCCTxt("");

        try {
            if (data['player']) {
                _mPlayer = data['player'];
            }
        } catch (err) {
            console.error("1. MediaManager: updateMedia:  ", _url)
        }

        try {
            if (!isFirstTimeCall) {
                _mPlayer.src(_url);
                let _vtt = data['vtt'];
                addTrackVTT(_vtt);
                //  addRemoteTextTrack(_vtt);
            }

        } catch (err) {
            console.error("2. MediaManager:  updateMedia:  ", _url)
        }

        _callback = data['callback'] || null;
        timeUpdateCallback = data['timeUpdateCallback'] || null;
        _isLinear = data['isLinear'] || false;

        if (!isFirstTimeCall) {
            mediaReadyToPlay(data);
        }

        isFirstTimeCall = false;
    };

    this.playInitially = function (data) {
        try {
            _self.stop();
        } catch (err) {
            console.error(" MediaManager: playInitially:  ", err)
        }
        _self.updateData(data);

        if (data['player']) {
            _mPlayer = data['player'];
        }

        _callback = data['callback'] || null;
        timeUpdateCallback = data['timeUpdateCallback'] || null;
        _isLinear = data['isLinear'] || false;
        mediaReadyToPlay(data);
    }

    var mediaReadyToPlay = function (data) {

        updateTranscript()

        if (data['autoplay'] == false) {
            try {
                _self.stop();
            } catch (err) {
                console.error("1. MediaManager: mediaReadyToPlay ", err)
            }
            isAudioReplayHit = false;
        }

        // console.log('MediaManager: : url:    ', data['url'])

        try {
            timeline = {
                cTime: 0,
                tTime: 1,
                rTime: 1,
                nodes: data['timeline'] || null
            }
            _self.ElementSync(timeline);
        } catch (err) {
            console.error("4. MediaManager:   mediaReadyToPlay:  ", err)
        }
    }


    var addEventsForCC = function () {
        $(".vjs-menu-item").off("click").on("click", function () {
            let _btn = $(this)
            if (_btn.hasClass("vjs-captions-menu-item")) {

            }
        })
    }


    var addTabIndexing = function () {

        setTimeout(function () {

            let _transcript = $("#btn_transcript")
            let list_1 = $("#simple_video_holder button")

            if (_transcript.hasClass('active') && list_1.length > 0) {

                let __tIndex = parseInt(_transcript.attr('tabindex')) || 500

                let list_2 = $("#simple_video_holder").find('*[tabindex]')

                list_1.each(function (i, item) {
                    let _self = $(this);
                    // if(_self.attr("tabindex")==0){
                    _self.attr("tabindex", __tIndex);
                    // }
                })
                list_2.each(function (i, item) {
                    let _self = $(this);
                    _self.attr("tabindex", __tIndex);
                })
                $("video").attr("tabindex", -1)
                $("#simple_video_1").attr("tabindex", -1);
                _transcript.focus();
            }
        }, 400)

    }

    var addEventOnChangeCue = function (vtt_url, tracks) {
        // console.log("addEventOnChangeCue");
        let _isDebugging = _user_details['isDebugging'];
        if (_isDebugging) {
            let _vttText = "\nVTT File: " + vtt_url + "\n\n"
            try {
                $.each(tracks['cues_'], function (i, item) {
                    _vttText += item.text + "\n\n"
                })
            } catch (err) {

            }
            console.log(_vttText);
        }


        try {
            tracks.addEventListener('cuechange', function (e) {
                let _activeCues = this.activeCues[0];
                let _aCue = {};
                if (_activeCues !== undefined) {
                    _aCue['id'] = _activeCues.id
                    _aCue['text'] = _activeCues.text
                    _aCue['startTime'] = _activeCues.startTime
                    _aCue['endTime'] = _activeCues.endTime;
                    updateCCTxt(_activeCues.text);
                }
                // console.log('oncuechange:   ', _aCue)
            });
        } catch (err) {

        }
        $("#btn_cc").off("click").on("click", function () {
            $("#ccText_popup_video").toggleClass("d-hide");
            $(this).toggleClass("cc_active")
        });
        $(".vjs-menu-content").remove();
    }

    var addTrackVTTForAudio = function (vtt_url) {

        if (vtt_url && vtt_url != '') {

            try {

                // $("#btn_ccText").addClass('active').removeClass('disabled');

                const trackEl = _mPlayer.addRemoteTextTrack({ src: vtt_url }, false);

                trackEl.addEventListener('load', function () {
                    var aTracks;
                    var tracks = _mPlayer.textTracks();
                    for (var i = 0; i < tracks.length; i++) {
                        var track = tracks[i];
                        if (track.kind === 'subtitles' || track.kind === 'captions') {
                            track.mode = 'hidden';
                            aTracks = track;
                        }
                    }
                    addEventOnChangeCue(vtt_url, aTracks)

                });
            } catch (err) {

            }
        } else {
            $("#btn_ccText").addClass('disabled').removeClass('active');
        }

    }

    var addTrackVTT = function (vtt_url) {
        let _vtt_url = vtt_url || '';
        // console.log("addTrackVTT ", _vtt_url);
        if (_vtt_url && _vtt_url != '') {
            addTrackVTTForAudio(_vtt_url);
        }
    }



    var addTrackVTTForVideo = function (_vtt_url) {

        let _videoTag = $("video");

        if (_videoTag.length > 0) {

            _videoTag.empty();

            if (_vtt_url && _vtt_url != '') {
                // document.querySelector("#video-subtitles").src = _vtt_url;
                let _track = document.createElement("track");
                _track.id = "subtitles";
                _track.src = _vtt_url;
                _track.kind = "captions";
                _track.srclang = "en";
                _track.language = "en";
                _track.label = "English";
                _track.default = "English";
                _videoTag.empty().append(_track);
                // addEventsForCC();
                // document.querySelector(".subtitles").src = _vtt_url;

            } else {
                $(".vjs-subs-caps-button").addClass("vjs-hidden")
            }
        }
    }

    let _addEventOnCaptionTrack_ = function () {
        // Get all text tracks for the current player.
        let player = _mPlayer;
        var tt = player.textTracks()[0];

        if (tt) {
            //  console.log(tt.activeCues)
            tt.oncuechange = function () {
                if (tt.activeCues[0] !== undefined) {
                    var dynamicHTML = "id: " + tt.activeCues[0].id + ", ";
                    dynamicHTML += "text: " + tt.activeCues[0].text + ", ";
                    dynamicHTML += "startTime: " + tt.activeCues[0].startTime + ",  ";
                    dynamicHTML += "endTime: " + tt.activeCues[0].endTime;
                    console.log("dynamicHTML: " + dynamicHTML);
                }
            }
        }

    }

    let addEventOnCaptionTrack_ = function () {
        // Get all text tracks for the current player.
        let player = _mPlayer;

        let tracks = player.textTracks()
        tracks.addEventListener('addtrack', function (event) {
            videojs.log('example', 'a track was added');
        });

        let metadataTrack;

        for (let i = 0; i < tracks.length; i++) {
            let track = tracks[i];
            // Find the metadata track that's labeled "ads".
            if (track.kind === 'captions' && track.label === 'English') {
                track.mode = 'showing';
                // Store it for usage outside of the loop.
                metadataTrack = track;
            }
        }

        track.addEventListener('cuechange', cueChangeHandler);

        // Add a listener for the "cuechange" event and start ad playback.
        metadataTrack.addEventListener('cuechange', function () {
            //  console.log('cuechange')
            // player.ads.startLinearAdMode();
        });
    }


    this.addRevind = function (player) {
        // +++ Create divs for buttons +++
        var _player = player,
            _nextTime = 5,
            _controlBar,
            _insertBeforeNode,
            _newEleBB = document.createElement("div"),
            _newEleFB = document.createElement("div"),
            _newImgBB = document.createElement("img"),
            _newImgFB = document.createElement("img");

        // +++ Assign IDs for later element manipulation +++
        _newEleBB.id = "backButton";
        _newEleFB.id = "forwardButton";

        // +++ Assign properties to elements and assign to parents +++
        _newImgBB.setAttribute("src", "templates/simple_video/back-button.png");
        _newEleBB.appendChild(_newImgBB);
        _newImgFB.setAttribute("src", "templates/simple_video/back-button.png");
        _newEleFB.appendChild(_newImgFB);

        // +++ Get controlbar and insert elements +++
        _controlBar = _player.$(".vjs-control-bar");
        // Get the element to insert buttons in front of in conrolbar
        _insertBeforeNode = _player.$(".vjs-volume-panel");

        // Insert the button div in proper location
        _controlBar.insertBefore(_newEleBB, _insertBeforeNode);
        _controlBar.insertBefore(_newEleFB, _insertBeforeNode);

        // +++ Add event handlers to jump back or forward +++
        // Back button logic, don't jump to negative times
        _newEleBB.addEventListener("click", function () {
            rewind(_nextTime)
        });

        // Forward button logic, don't jump past the duration
        _newEleFB.addEventListener("click", function () {
            forward(_nextTime)
        });
    }

    /*Function to Reload video from Beginning*/
    this.reloadVideo = function () {
        _self.setTime(0)
    }

    this.rewind = function (time) {
        let _cTime = _mPlayer.currentTime()
        let _nTime = 0;
        if (_cTime >= time) {
            _nTime = (_cTime - time)
        }
        _self.setTime(_nTime)
    }

    /*Function to Forward & Rewind*/
    this.forward = function (time) {
        let _cTime = _mPlayer.currentTime(),
            _duration = _mPlayer.duration();

        let _nTime = (_cTime + time);
        if (_nTime >= _duration) {
            _nTime = _duration;
        }
        _self.setTime(_nTime)
    }

    this.init = function (data) {

        //   console.log('MediaManager:    init: ')

        let _player = null

        _self.updateMedia(data);

        _mPlayer.ready(function () {

            _player = this;
            _player.tech_.off('dblclick')

            $(".vjs-descriptions-button.vjs-menu-button").remove();

            $(".vjs-chapters-button.vjs-menu-button").remove();

            $(".vjs-playback-rate.vjs-menu-button").remove();
            $(".vjs-audio-button.vjs-menu-button").remove();
            $(".vjs-playback-button.vjs-menu-button").remove();


            var currentTime = 0;
            _callback = data['callback'] || null;
            timeUpdateCallback = data['timeUpdateCallback'] || null;

            timeline = {
                cTime: 0,
                tTime: 1,
                rTime: 1,
                nodes: data['timeline'] || null
            }


            _player.on('timeupdate', function () {

                // get
                // var whereYouAt = _player.currentTime();
                // set
                // _player.currentTime(120); // 2 minutes into the video

                var _duration = this.duration();
                var _whereYouAt = this.currentTime();
                var _timeLeft = this.remainingTime();

                //  console.log("MediaManager:   timeupdate:  cTime:   ", _whereYouAt, "_duration:   ",_duration);

                try {

                    if (_duration) {

                        var minutes = Utils.addZero(Math.floor(_whereYouAt / 60));
                        var seconds = Utils.addZero(Math.floor(_whereYouAt - minutes * 60));

                        timeline['cTime'] = _whereYouAt
                        timeline['tTime'] = _duration
                        timeline['rTime'] = _timeLeft

                        //    console.log(":   timeupdate:   " , timeline);

                        if (timeline['nodes'] != null) {
                            _self.ElementSync(timeline);
                        }

                        _self['time'] = timeline;
                        try {
                            if (_data['timeUpdateCallback']) {
                                _data['timeUpdateCallback'](_whereYouAt, _duration)
                            }
                        } catch (e) { }

                        self.PageProgress(timeline);

                        //  console.log(timeline)
                        //  _self['player'] = _player;
                        //  _mPlayer.trigger("updateTime", time)
                    }
                } catch (err) {
                    console.error("MediaManager: timeupdate ", err)
                }
            });


            //This example allows users to seek backwards but not forwards.
            //To disable all seeking replace the if statements from the next
            //two functions with myPlayer.currentTime(currentTime);

            _player.on("seeking", function (event) {
                try {
                    if ((currentTime < _player.currentTime()) && _isLinear) {
                        _player.currentTime(currentTime);
                    }
                } catch (err) {
                    console.error("MediaManager: seeking ", err)
                }
            });

            _player.on("seeked", function (event) {
                try {
                    if ((currentTime < _player.currentTime()) && _isLinear) {
                        _player.currentTime(currentTime);
                    }
                } catch (err) {
                    console.error("MediaManager: seeked ", err)
                }
            });


            _player.on("canplaythrough", function () {
                _shell_wrapper.trigger('mediaCanplaythrough');
            });

            _player.on("loadedmetadata", function () {

                addTrackVTT(data['vtt']);

                _shell_wrapper.trigger('mediaLoadedmetadata');

                let _preloader = $("#preloader")
                if (!_preloader.hasClass('isShow')) {
                    if (data['autoplay'] == true) {
                        _self.start()
                    }
                }

            });

            _player.on("mute", function (event) {
                console.log("MediaManager : mediaIsMute")
                _shell_wrapper.trigger('mediaIsMute');
            })

            _player.on("unmute", function (event) {
                console.log("MediaManager : mediaIsUnmute")
                _shell_wrapper.trigger('mediaIsUnmute')
            })

            _player.on("play", function (event) {
                console.log("MediaManager : mediaIsPlaying")
                _shell_wrapper.trigger('mediaIsPlaying');
                if (!_player.paused()) {
                    if ($("#timerPopupoverlay").is(':visible') || $(".g_popup_holder").is(':visible')) {
                        _self.stop();
                    }
                }

                if (_isMutedByLearners) {
                    _self.mute();
                }
            })

            _player.on("pause", function (event) {
                console.log("MediaManager : mediaIsPaused")
                _shell_wrapper.trigger('mediaIsPaused')
            })

            _player.on('ended', function () {
                _shell_wrapper.trigger('mediaIsEnded');
                console.log("MediaManager:   ended:   ");
                //  this.controls(false);

                try {
                    var _callback = _data['callback'] || null
                    if (_callback) {
                        _callback()
                    }
                } catch (err) {
                    console.error("MediaManager: ended ", err)
                }



            });

            try {
                if (_isLinear) {
                    _seekInterval = 1;
                    setInterval(function () {
                        if (!_seekInterval) {
                            return;
                        }
                        if (!_player.paused()) {
                            currentTime = _player.currentTime();
                        }
                    }, 600);
                }
            } catch (err) {
                console.error("MediaManager: _isLinear ", err)
            }

            _player.on("fullscreenchange", function () {
                if (_player.isFullscreen()) {
                    _player.exitFullscreen();
                }
            });


        })

    }



    this.getTime = function () {
        try {
            if (_mPlayer['player_']) {
                var _currentTime = _mPlayer['player_'].currentTime();
                return _currentTime
            }
        } catch (err) {
            console.error("MediaManager: getTime ", err)
        }
    }

    this.setTime = function (cTime) {
        try {
            if (_mPlayer['player_']) {
                let _cTime = cTime || 0;
                if (_cTime <= _mPlayer.duration()) {
                    _mPlayer['player_'].currentTime(_cTime);
                    // _mPlayer.currentTime(cTime)
                }
            }
        } catch (err) {
            console.error("MediaManager: setTime ", err)
        }
    }

    this.gotoAndStopEnd = function () {
        console.log("MediaManager: gotoAndStopEnd ")
        try {
            if (_mPlayer) {
                let _end = (_mPlayer.duration() - 1);
                _self.setTime(_end);
                _self.pause();
                isAudioReplayHit = true;
            }
        } catch (err) {
            console.error("MediaManager: gotoAndStopEnd ", err)
        }

        try {
            var _callback = _data['callback'] || null
            if (_callback) {
                _callback()
            }
        } catch (err) {
            console.error("MediaManager: gotoAndStopEnd ", err)
        }

    }

    this.stop = function () {
        console.log("MediaManager: stop ")
        try {
            if (_mPlayer) {
                _self.setTime(0)
            }
        } catch (err) {
            console.error("1. MediaManager: stop ", err)
        }
        _self.pause();
    }

    this.start = function () {

        if (_mPlayer) {

            _self.setTime(0);

            if ($("#timerPopupoverlay").is(':visible') || $(".g_popup_holder").is(':visible') || !isAudioReplayHit) {
                try {
                    _self.stop();
                } catch (err) {
                    Utils.error("1. MediaManager: start ", err)
                }
            } else {
                try {
                    _self.play();
                } catch (err) {
                    Utils.error("2. MediaManager: start ", err)
                }
            }
            _pageProgress = $("#pageProgress");
        }


    }

    var updateTranscript = function () {

        try {
            if (_data['isNotification']) {
                return
            }
            var _tData = _data['transcript'] || "";
            $("#transcript_discription").html("");
            $("#transcript_discription").html(_tData).scrollTop(0);

        } catch (err) {
            Utils.error("3. MediaManager: setTime ", err)
        };
    }

    var updateCCTxt = function (ccTxt) {
        // console.log("updateCCTxt", ccTxt);
        try {
            _ccText_description.text(ccTxt);
        } catch (err) {
            console.error(" MediaManager: updateCCTxt:  ", err)
        };
    }

    this.gotoAndPlay = function (cTime) {
        try {
            if (_mPlayer) {
                _self.setTime(cTime)
                _mPlayer.play();
            }
        } catch (err) {
            Utils.error("MediaManager: gotoAndPlay ", err)
        }
    }

    this.gotoAndStop = function (cTime) {
        console.log("MediaManager: gotoAndStop ")
        try {
            if (_mPlayer) {
                _self.setTime(cTime)
            }
        } catch (err) {
            console.error("1. MediaManager: gotoAndStop ", err)
        }

        _self.pause();
    }

    this.replay = function () {
        try {
            var _pAudio = _data['pageAudio'] || null
            if (_pAudio != null) {
                _pAudio();
                _data['pageAudio'] = null;
            } else {
                isAudioReplayHit = true;
                _self.start();
            }
        } catch (err) {
            console.error("MediaManager: replay ", err)
        }
    }

    this.pause = function () {

        if (_mPlayer && !_mPlayer.paused()) {
            console.log("MediaManager: pause ")
            try {
                if (_mPlayer) {
                    _mPlayer.pause();
                }
            } catch (err) {
                console.error("MediaManager: pause ", err)
            }
        }
    }

    this.play = function () {
        // console.log("MediaManager: play ")
        // console.log("MediaManager: play ", _mPlayer.currentTime(), _mPlayer.duration(), isAudioReplayHit)
        try {
            if (_mPlayer) {
                if (_mPlayer.currentTime() <= (_mPlayer.duration() - 0.01)) {
                    _mPlayer.play();
                }
            }
        } catch (err) {
            console.error("MediaManager: play ", err)
        }
    }

    this.mute = function () {
        try {
            // get
            // var _isVolumeMuted = _mPlayer.muted();
            // set
            if (_mPlayer) {
                _mPlayer.muted(true);
                _shell_wrapper.trigger('mediaIsMute');
                _isMutedByLearners = true
                // mute the volume
            }
        } catch (err) {
            console.error("MediaManager: mute ", err)
        }

    }

    this.unMute = function () {
        try {
            if (_mPlayer) {
                _mPlayer.muted(false);
                _shell_wrapper.trigger('mediaIsUnMute');
                _isMutedByLearners = false
            }
        } catch (err) {
            console.error("MediaManager: unMute ", err)
        }
    }

    this.setVolume = function (val) {
        try {
            // get
            // var howLoudIsIt = _mPlayer.volume();
            // set
            if (_mPlayer) {
                _mPlayer.volume(val); // Set volume to half
            }
        } catch (err) {
            console.error("MediaManager: setVolue ", err)
        }

    }


    this.videoSync = function (data) {
        try {
            // var video = data['vObj'];
            // video['cTime'] = data.cTime;
            this.ElementSync(video);
        } catch (err) {
            console.error("MediaManager: videoSync ", err)
        }
    }

    this.audioSync = function (data) {
        this.ElementSync(data);
    }

    this.ElementSync = function (data) {

        let nodes = data.nodes || data || [],
            lastTime = data.lastTime || -1,
            i = 0,
            time = parseFloat(data.cTime.toFixed(1));

        if (nodes.length < 1) return;

        if (Math.abs(time - lastTime) < 0.1) {
            return;
        }


        //  console.log('ElementSync:  lastTime: ', lastTime, " time:    ", time, "  nodes:", nodes);

        data['lastTime'] = time;

        for (i = 0; i < nodes.length; i += 1) {

            let _node = nodes[i];
            let _sTime = _node['sTime'];
            let _eTime = _node['eTime'];
            let _ele = $(_node['element']);
            let classIn = _node['classIn'];
            let classOut = _node['classOut'];

            try {
                let _isActivity = _node['isActivity'] || false;
                if (_isActivity || _isActivity == "true") {

                    if ((time >= _sTime) && (_eTime ? (time <= _eTime) : true)) {
                        // console.log(_node)
                        try {
                            _self.pause();
                        } catch (err) {
                            console.error("1. MediaManager: ElementSync ", err)
                        }

                        try {
                            let _callback = _node['callback']
                            if (_callback)
                                _callback();
                        } catch (err) {
                            console.error("2. MediaManager: ElementSync ", err)
                        }
                    }
                }
            } catch (err) {
                console.error("1. MediaManager: ElementSync ", err)
            }

            try {
                //  console.log(i, time, lastTime, _sTime, _eTime)

                if (!_ele.hasClass(classIn)) {
                    if ((time >= _sTime) && (_eTime ? time < _eTime : true)) {
                        _ele.addClass(classIn);
                        //_ele.fadeIn();
                        _ele.removeClass(classOut);
                    }
                } else if (_ele.hasClass(classIn)) {
                    if ((time < _sTime) || (_eTime ? time >= _eTime : false)) {
                        _ele.removeClass(classIn);
                        // _ele.fadeOut();
                        _ele.addClass(classOut);
                    }
                }
            } catch (err) {
                console.error("3. MediaManager: ElementSync ", err)
            }

        }
    }

    this.PageProgress = function (data) {
        try {
            let _progress = (data.cTime * 100 / data.tTime).toFixed(2);
            _pageProgress.attr('value', _progress);
        } catch (err) {
            console.error(" MediaManager: PageProgress:  ", err)
        }
    }

    return _self;

})();



$.fn.videosync = function () {
    // P01692
    // console.clear();

    return this.each(function () {

        this.classIn = 'fadeIn';
        this.classOut = 'fadeOut';
        this.nodes = [];
        this.lastTime = -1;
        this.time = 0;
        var _that = this;

        $('.timeLine').each(function () {
            var _self = $(this)[0];
            _that.nodes.push({
                sTime: parseFloat(_self.dataset['stime']),
                eTime: parseFloat(_self.dataset['etime']),
                classIn: _self.dataset['inclass'],
                classOut: _self.dataset['outclass'],
                element: $(this)
            });
        });
    });

};