/*
* NarrationManager.js
* Keynote HTML Player
*
* Created by Tungwei Cheng
* Copyright (c) 2013 Apple Inc. All rights reserved.
*/
var NarrationManager = Class.create({
initialize: function(recording) {
// recording movies in an array
this.movieSegments = recording.movieSegments;
// total time of this recording
this.duration = recording.duration;
// navigation, movie and pause in eventTracks array
this.eventTracks = recording.eventTracks;
// current navigation event index
this.currentNavigationEventIndex = 0;
// last scene index
this.lastSceneIndex = 0;
for (var i = 0, length = this.eventTracks.length; i < length; i++) {
var eventTrack = this.eventTracks[i];
if (eventTrack.type === "navigation") {
this.navigationEvents = eventTrack.events;
} else if (eventTrack.type === "movie") {
this.movieEvents = eventTrack.events;
} else if (eventTrack.type === "pause") {
this.pauseEvents = eventTrack.events;
}
}
},
start: function() {
// set up media resources
var audio = new Audio();
audio.src = "../" + this.movieSegments[0].url;
// observe play event
Event.observe(audio, "playing", this.handleAudioDidStart.bind(this));
Event.observe(audio, "ended", this.handleAudioDidEnd.bind(this, 0));
audio.play();
},
handleAudioDidStart: function() {
// audio has started, now navigate to the first navigation event
setTimeout(this.navigate(this.navigationEvents[0], true), 100);
},
handleAudioDidEnd: function(audioIndex) {
var nextAudioIndex = audioIndex + 1;
if (this.movieSegments[nextAudioIndex]) {
var audio = new Audio();
audio.src = "../" + this.movieSegments[nextAudioIndex].url;
audio.play();
Event.stopObserving(audio, "ended");
Event.observe(audio, "ended", this.handleAudioDidEnd.bind(this, nextAudioIndex));
}
},
navigate: function(event, startup) {
var sceneIndex = this.sceneIndexFromNavigationEvent(event);
if (event.animationPhase === "start") {
// if event's slideIndex has been changed from lastScene's slide
// check to see if this is our next scene to play
var isNextScene = false;
if (gShowController.script.loopSlideshow) {
if (this.lastSceneIndex === gShowController.script.numScenes - 1) {
if (sceneIndex === 0) {
isNextScene = true;
}
}
} else {
if (this.lastSceneIndex + 1 === sceneIndex) {
isNextScene = true;
}
}
if (isNextScene) {
if (gShowController.state === kShowControllerState_IdleAtInitialState) {
gShowController.playCurrentScene();
} else if (gShowController.state === kShowControllerState_IdleAtFinalState) {
gShowController.jumpToScene(this.lastSceneIndex, true);
}
} else {
// this is the slide we are jumping to
var slideIndexToJump = gShowController.scriptManager.slideIndexFromSceneIndex(sceneIndex);
var sceneIndexOfHyperlink = this.lastSceneIndex;
// get hyperlink from slide, find the first occurrence of slideId in hyperlinks
var hyperlinks = gShowController.script.events[sceneIndexOfHyperlink].hyperlinks;
var hyperlink;
var hyperlinkEvent;
for (var i = 0, length = hyperlinks.length; i < length; i++) {
hyperlink = hyperlinks[i];
hyperlinkEvent = hyperlink.events[event.slide];
if (hyperlinkEvent) {
break;
}
}
if (hyperlink) {
// call jumpToHyperlinkSlide to play hyperlink transition
gShowController.jumpToHyperlinkSlide(slideIndexToJump, hyperlink);
} else {
// if no hyperlink event is found for any reason, we still want to jump
gShowController.jumpToScene(sceneIndex, false);
}
}
} else if (event.animationPhase === "none" && startup == null) {
gShowController.jumpToScene(sceneIndex, false);
}
// if there is any more event then set it to run next
var nextEvent = this.navigationEvents[this.currentNavigationEventIndex + 1];
if (nextEvent == null) {
return;
}
// set timeout to navigate to next event
var duration = nextEvent.startTime - event.startTime;
setTimeout(this.navigate.bind(this, nextEvent), duration * 1000);
this.lastSceneIndex = sceneIndex;
this.currentNavigationEventIndex = this.currentNavigationEventIndex + 1;
},
handleCurrentSceneDidComplete: function(sceneIndexToJump) {
// scene did complete, jump to next scene so we have more time to set it up
gShowController.jumpToScene(sceneIndexToJump, false);
},
sceneIndexFromNavigationEvent: function(event) {
// return sceneIndex from navigation event
var slideId = event.slide;
var slideList = gShowController.script.slideList;
var newSlideIndex = -1;
for (var i = 0, length = slideList.length; i < length; i++) {
if (slideList[i] === slideId) {
newSlideIndex = i;
break;
}
}
var sceneIndex = gShowController.scriptManager.sceneIndexFromSlideIndex(newSlideIndex);
var newSceneIndex = event.eventIndex + sceneIndex;
return newSceneIndex;
},
slideIndexFromSlideId: function(slideId) {
var slideList = gShowController.slideList;
var slideIndex = -1;
for (var i = 0, length = slideList.length; i < length; i++) {
if (slideList[i] === slideId) {
slideIndex = i;
break;
}
}
return slideIndex;
}
});