(function() {
'use strict';
var SEEK_INTERVAL = 5;
var event = window.mheContpract.libs['event'].user;
var Video = function(section) {
this.section = section;
this.$section = this.section.jq;
this.section.points_possible = 1;
this.section.points_earned = 0;
this.section.section_completed = false;
this.$container = this.$section.find('.video');
this.video = this.$container.find('video')[0];
this.video.mute = false;
this.showCaptions = false;
this.hasCaptions = true;
this.timeDrag = false;
this.transcriptUrl = this.$container.data('transcript');
this.hasTranscripts = !!this.transcriptUrl;
var captionsUrl = this.$container.data('captions');
var self = this;
$.getJSON(captionsUrl, function(data) {
self.captions = data.captions;
createHtml.call(self);
});
this.feedbacks = [];
this.section.jq.find('.feedback').each(function(elem) {
self.feedbacks.push({
'text': $(this).text(),
'correct': $(this).data('correct') == 'yes',
'startTime': $(this).data('startTime'),
'endTime': $(this).data('endTime')
});
});
addCheckBtn.call(this);
};
var createHtml = function() {
var captions = '
';
var transcript;
if ( this.transcriptUrl ) {
transcript = '-->
CC
' +
'';
this.$liveRegion = $( '' );
this.$container.append(controlBar, captions, this.$liveRegion);
initProgressBar.call(this);
initButtons.call(this);
initButton.call(this, '.btnCaption', onCaptionBtnClick);
initButton.call(this, '.btnVolume', onPlayBtnVolume);
if ( this.hasTranscripts ) {
initButton.call(this, '.btnTranscript', onPlayBtnTranscript);
}
if ( this.hasCaptions ) {
var $captions = this.$container.find('.captions');
// Create all captions and hide them.
for (var i = 0; i < this.captions.length; i++) {
var captionData = this.captions[i];
var $caption = $('' + captionData.text + '
');
$captions.append($caption);
// save link to the jQuery element
captionData.$caption = $caption;
// hide all captions
$caption.css({ 'display': 'none' });
}
}
onCaptionBtnClick.call(this, this.$container.find('.btnCaption'));
};
var onPlayBtnTranscript = function() {
if ( this.transcriptUrl ) {
window.open(this.transcriptUrl, '_blank');
}
};
var onPlayBtnVolume = function($btn) {
$btn.toggleClass( "mute" );
this.video.mute = !this.video.mute;
this.video.mute ? this.$liveRegion.text('Sound off') : this.$liveRegion.text('Sound on');
};
var initButton = function(selector, callback) {
var $btn = this.$container.find(selector);
callback = callback.bind(this, $btn);
$btn.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
callback();
}
}.bind(this));
$btn.bind(event.mousedown, callback);
};
var initProgressBar = function() {
var self = this;
var $btnSlider = this.$container.find('.btnSlider');
var $progressBar = this.$container.find('.progressBar');
var $progress = this.$container.find('.progressTime');
this.timeDrag = false;
$progressBar.bind(event.mousedown, function(e) {
self.timeDrag = true;
updateBar(e.pageX);
$btnSlider.addClass("active");
document.addEventListener(event.mouseup, onSliderDragStop);
document.addEventListener(event.mousemove, onSliderMove);
});
function updateBar(x) {
var scaleFactor = window.player._scaleFactor;
var maxDuration = self.video.duration; //Video duraiton
var position = x - $progressBar.offset().left; //Click pos
var btnSliderWidth = $btnSlider.width() * scaleFactor;
var progressBarWidth = $progressBar.width() * scaleFactor;
var minPosition = 0;
var maxPosition = progressBarWidth - btnSliderWidth;
var sliderPosition = Math.min(Math.max((position - btnSliderWidth / 2 ), minPosition), maxPosition);
var percentage = Math.round(100 * 100 * sliderPosition / (maxPosition - minPosition)) / 100;
percentage = Math.min(100, Math.max(percentage, 0));
$btnSlider.css('left', sliderPosition / scaleFactor);
// Update progress bar and video currenttime
$progress.css('width', $progressBar.width() * percentage / 100);
self.video.currentTime = maxDuration * percentage / 100;
}
function onSliderDragStop(e) {
document.removeEventListener(event.mouseup, onSliderDragStop);
document.removeEventListener(event.mousemove, onSliderMove);
if ( self.timeDrag ) {
self.timeDrag = false;
$btnSlider.removeClass("active");
}
}
function onSliderMove(e) {
if ( self.timeDrag ) {
updateBar(e.pageX);
}
}
this.video.addEventListener('timeupdate', function(e) {
var currentTime = this.video.currentTime;
updateCaptions.call(this, currentTime);
if ( this.timeDrag ) {
return;
}
// Get video duration
var maxDuration = this.video.duration;
var percentage = 100 * currentTime / maxDuration; //in %
var progressWidth = $progressBar.width() - $btnSlider.width();
var position = progressWidth * percentage / 100;
var minPosition = 0;
var maxPosition = $progressBar.width() - $btnSlider.width();
var sliderPosition = Math.min(Math.max((position), minPosition), maxPosition);
$btnSlider.css('left', sliderPosition);
$progress.css('width', $progressBar.width() * percentage / 100);
}.bind(this));
};
var initButtons = function() {
var $btnPlay = this.$container.find('.btnPlay');
var $btnRewind = this.$container.find('.btnRewind');
var $btnForward = this.$container.find('.btnForward');
$btnPlay.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
this.onPlayBtnClick.call(this);
}
}.bind(this));
$btnPlay.bind('click', this.onPlayBtnClick.bind(this));
$btnRewind.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
this.onRewindBtnClick.call(this);
}
}.bind(this));
$btnRewind.bind(event.mousedown, this.onRewindBtnClick.bind(this));
$btnForward.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
this.onForwardBtnClick.call(this);
}
}.bind(this));
$btnForward.bind(event.mousedown, this.onForwardBtnClick.bind(this));
this.video.addEventListener('play', function() {
$btnPlay.addClass('playing');
});
this.video.addEventListener('pause', function() {
$btnPlay.removeClass('playing');
});
};
var onCaptionBtnClick = function($btn) {
if ( this.showCaptions ) {
$btn.removeClass('selected');
}
else {
$btn.addClass('selected');
}
this.showCaptions = !this.showCaptions;
updateCaptions.call(this, this.video.currentTime);
};
var updateCaptions = function(currentTime) {
if ( this.hasCaptions ) {
for (var i = 0; i < this.captions.length; i++) {
var captionData = this.captions[i];
if ( this.showCaptions ) {
if ( currentTime >= captionData.startTime && currentTime < captionData.endTime ) {
captionData.$caption.css({ 'display': 'table-cell' });
}
else {
captionData.$caption.css({ 'display': 'none' });
}
}
else {
// hide all captions
captionData.$caption.css({ 'display': 'none' });
}
}
}
};
Video.prototype.onPlayBtnClick = function(e) {
var currentTime, totalTime;
var self = this;
if ( this.video.paused ) {
this.video.play();
}
else {
this.video.pause();
}
};
Video.prototype.onRewindBtnClick = function(e) {
var currentTime = this.video.currentTime - SEEK_INTERVAL;
if ( currentTime > 0 ) {
this.video.currentTime = currentTime;
}
else {
this.video.currentTime = 0;
}
};
Video.prototype.onForwardBtnClick = function(e) {
var currentTime = this.video.currentTime + SEEK_INTERVAL;
var totalTime = this.video.duration;
var self = this;
if ( currentTime < totalTime ) {
this.video.currentTime = currentTime;
}
else {
this.video.currentTime = totalTime;
}
};
Video.prototype.update = function() {
var $controlBar = this.$container.find('.controlBar');
var $playBtn = this.$container.find('.btnPlay');
var $captionBtn = this.$container.find('.btnCaption');
var $volumeBtn = this.$container.find('.btnVolume');
var $transcriptBtn = this.$container.find('.btnTranscript');
var $progressBar = this.$container.find('.progressBar');
// calculate progressBar width
var trans;
var progressBarWidth = $controlBar.width() -
$playBtn.outerWidth()*3 - 10 -
(this.hasCaptions ? $captionBtn.outerWidth() + 4 : 0) -
(this.hasTranscripts ? $transcriptBtn.outerWidth() + 4 : 0) -
$volumeBtn.outerWidth() - 2 -
parseFloat($progressBar.css('margin-left')) -
parseFloat($progressBar.css('margin-right'));
$progressBar.width(progressBarWidth);
};
var addCheckBtn = function() {
this.btnCheck = $('');
this.btnCheck.bind('click', checkAnswer.bind(this));
this.$section.find('.btn_container').append(this.btnCheck);
};
var selectFeedback = function(time) {
for (var i = 0; i < this.feedbacks.length; i++) {
if ( (this.feedbacks[i].startTime <= time) && (this.feedbacks[i].endTime >= time) ) {
return this.feedbacks[i];
}
}
}
var checkAnswer = function() {
var self = this;
this.video.pause();
var feedback = selectFeedback.call(this, this.video.currentTime);
if ( feedback.correct ) {
this.finishSlide.call(this);
Standard_Dialog.open(feedback.text, {
title: 'Correct!'
}, 'correct');
}
else {
Standard_Dialog.open(feedback.text, {
title: 'Incorrect',
buttons: [
{
text: "OK",
click: function() {
Standard_Dialog.close();
}
}
]
}, 'incorrect');
}
};
Video.prototype.finishSlide = function() {
this.section.points_earned = this.section.points_possible;
this.section.section_completed = true;
player.activity.grade_activity();
player.update_section_status();
document.querySelector('.navigation_button.next_button').focus();
};
var slide;
window.mheContpract = window.mheContpract || {};
window.mheContpract['video_quiz_1'] = {
initialize: function(section) {
section.slide = new Video(section);
},
show: function(section) {
section.slide.update();
},
hide: function(section) {
section.slide.video.pause();
}
};
})();