YUI.add('video-frames', function(Y) {
var Lang = Y.Lang,
Widget = Y.Widget,
Node = Y.Node;
var NS = Y.namespace('mazzle');
NS.VideoFrames = VideoFrames;
/* VideoFrames class constructor */
function VideoFrames(config) {
VideoFrames.superclass.constructor.apply(this, arguments);
}
/*
* Required NAME static field, to identify the Widget class and
* used as an event prefix, to generate class names etc. (set to the
* class name in camel case).
*/
VideoFrames.NAME = "video-frames";
/*
* The attribute configuration for the VideoFrames widget. Attributes can be
* defined with default values, get/set functions and validator functions
* as with any other class extending Base.
*/
VideoFrames.ATTRS = {
frameServer: {
value: null
},
maxFrames: {
value: 50
},
frames: {
value: []
},
related: {
value: []
},
duration: {
value: null
},
confirm: {
value: false
},
video: {
value: null
},
interval : {
value: 10
},
showRelated : {
value: true
},
showTime : {
value: false
},
selected : {
value: null
}
};
/* Static constants used to define the markup templates used to create VideoFrames DOM elements */
VideoFrames.LIST_CLASS = 'frames-list';
VideoFrames.LIST_TEMPLATE = '
';
/* VideoFrames extends the base Widget class */
Y.extend(VideoFrames, Widget, {
initializer: function() {
this.listNode = null;
},
destructor : function() {
},
renderUI : function() {
var content = this.get("contentBox");
this._renderFrameList(content);
},
bindUI : function() {
this.after("framesChange", this._renderFrames);
this.after("relatedChange", this._renderRelated);
// frame click
Y.delegate("click", this._onFrameSelect, this.listNode, "li .image", this);
Y.delegate("mouseover", this._onFrameHover, this.get("contentBox"), "li", this);
Y.delegate("click", this._onRoleSelect, this.get("contentBox"), "li div.frame-confirm", this);
},
syncUI : function() {
this._renderFrames();
},
_renderFrameList : function(node) {
var list = node.appendChild(Node.create(VideoFrames.LIST_TEMPLATE));
// create list elements
var maxFrames = this.get("maxFrames");
for(var i=0; i < maxFrames; i++) {
list.append('');
}
this.listNode = list;
if(this.get("showRelated")) {
// create list for related frames
node.appendChild('');
related = node.appendChild(Node.create(VideoFrames.LIST_TEMPLATE));
related.addClass("related");
for(var i=0; i < maxFrames; i++) {
related.append('');
}
this.relatedNode = related;
}
},
_renderFrames : function() {
var frames = this.get("frames");
this.listNode.all("li").removeClass("selected");
this.set("selected", null);
this._updateFrames(this.listNode, frames);
},
_renderRelated : function() {
var frames = this.get("related");
if(this.relatedNode) {
this._updateFrames(this.relatedNode, frames);
}
},
_updateFrames : function(node, frames) {
var time = 0;
var interval = this.get("interval")*1000;
node.all("li").each(function(node, i) {
if(frames[i]) {
var startTime = frames[i].startTime;
node.setContent(this.formatFrame(frames[i]));
if(time==0 || interval==0 || startTime>time+interval) {
node.removeClass("hidden");
}
time = startTime;
} else {
node.setContent("");
node.addClass("hidden");
}
}, this);
},
formatFrame : function(frame) {
var frameServer = this.get("frameServer"),
video = frame.video || this.get("video"),
time = frame.startTime/1000,
label = frame.tag ? (frame.tag.label ? frame.tag.label : frame.tag.value) : '',
role = frame.role ? frame.role : '',
endTime = frame.duration ? time+(frame.duration/1000) : null;
var html = ''
+'
'
+'
';
if(this.get("confirm")) {
//html += 'click to confirm
';
html += ''
+this._roleLabel(role)
+label+' '+this.formatTime(time)+'
';
} else {
html += ''+label+' '+this.formatTime(time);
if(endTime) { html += ' -- '+this.formatTime(endTime); }
html += '
';
}
return html;
},
formatTime : function(totalSeconds) {
if(this.get("showTime")) {
var minutes = Math.floor(totalSeconds / 60);
var seconds = Math.floor(totalSeconds % 60);
var spacer = (seconds<10) ? 0 : '';
return ''+minutes+':'+spacer+seconds+'';
} else {
return '';
}
},
_roleLabel : function(role) {
if(role=="depicted") {
return "depicts ";
} else if(role=="associated") {
return "associated with ";
} else if(role=="rejected") {
return "not ";
} else {
return "";
}
},
_onFrameSelect : function(e) {
var node = e.currentTarget.get("parentNode"),
list = node.get("parentNode");
index = list.all("li").indexOf(node),
frame = this._getFrame(list, index),
arg = {li:node, index:index, frame:frame};
this.set("selected", frame);
list.all("li").removeClass("selected");
node.addClass("selected");
Y.log('clicked frame '+frame+' at index '+index);
this.fire("frameSelect", arg);
},
_onFrameHover : function(e) {
var node = e.currentTarget,
list = node.get("parentNode"),
index = list.all("li").indexOf(node),
frame = this._getFrame(list, index);
arg = {li:node, index:index, frame:frame};
this.fire('frameHover', arg);
},
_onRoleSelect : function(e) {
var target = e.currentTarget,
node = e.currentTarget.get("parentNode"),
list = node.get("parentNode");
index = list.all("li").indexOf(node),
frame = this._getFrame(list, index),
tag = frame.tag.label;
Y.log('frame role selected at index '+index);
var type = "depicted";
if(frame.confirm) {
if(frame.confirm=="depicted") {
type="associated";
} else if(frame.confirm=="associated") {
type = "rejected";
}
target.replaceClass(frame.confirm, type);
} else {
target.addClass(type);
};
frame.confirm = type;
e.target.setContent(this._roleLabel(type)+tag);
this.fire("roleSelect", {type:type, index:index, frame:frame});
},
_getFrame : function(list, index) {
if(list.hasClass("related")) {
return this.get("related")[index];
} else {
return this.get("frames")[index]
}
}
});
}, 'gallery-2010.03.02-18' ,{requires:['node','widget','io-base','json-parse']});