dojo.provide("motionbox.MBXHaClient");
if (!MBX) {
var MBX;
if (window.MBX) {
MBX = window.MBX;
} else {
MBX = window.MBX = {};
}
}
var CentralDispatch = {
requestData: function (url, callbacks, options) {
var request = CentralDispatch.request({url: url, callbacks: callbacks, options: options});
request.addToDom();
return request;
},
receiveData: function (version, url, data) {
CentralDispatch.RequestMap.runAllFor(url, data);
},
timeout: 60000 // 60 seconds
};
CentralDispatch.request = function (spec, my) {
var that;
that = {};
that.url = spec.url;
that.requestedUrl = null;
my = my || {};
my.timeout = null;
my.options = spec.options || {};
// Private methods
my.setCallbacks = function () {
if (typeof(spec.callbacks) === 'function') {
my.callbacks = { onSuccess: spec.callbacks };
} else {
my.callbacks = spec.callbacks || {};
}
};
my.setTimeout = function () {
if (CentralDispatch.timeout) {
if (window) {
my.timeout = window.setTimeout(function () {
that.timeout();
}, CentralDispatch.timeout);
}
}
};
my.setElement = function () {
var element;
element = document.createElement('script');
element.src = that.requestedUrl;
element.onerror = that.error;
that.element = element;
};
my.setRequestedUrl = function () {
var url, date;
// TODO: Make the url using a library
url = that.url;
if (my.options.jsonp === "CentralDispatch" || my.options.skipCache) {
url = url + "?";
}
if (my.options.jsonp === "CentralDispatch") {
url = url + "callback=CentralDispatch.receiveData";
if (my.options.skipCache) {
url = url + "&";
}
}
if (my.options.skipCache) {
date = new Date();
url = url + "nocache=" + date.valueOf();
}
that.requestedUrl = url;
};
my.process = function (func) {
if (!my.executed) {
my.executed = true;
my.cleanupElement();
func();
}
};
my.cleanupElement = function () {
if (that.element) {
document.body.removeChild(that.element); 
that.element = null; 
}
};
my.cleanupTimeout = function () {
if (my.timeout) {
window.clearTimeout(my.timeout);
my.timeout = null;
}
};
// Public methods
that.success = function (data) { 
my.process(function () {
my.cleanupTimeout();
if (my.callbacks.onSuccess) {
my.callbacks.onSuccess(data, my.options.userData);
}
});
};
that.error = function (msg, url, line) {
my.process(function () {
CentralDispatch.RequestMap.remove(that);
if (my.callbacks.onError) {
my.cleanupTimeout();
my.callbacks.onError(msg, url, line, my.options.userData);
}
});
};
that.timeout = function () {
my.process(function () {
CentralDispatch.RequestMap.remove(that);
if (my.callbacks.onTimeout) {
my.callbacks.onTimeout(that, my.options.userData);
}
});
};
that.addToDom = function () {
document.body.appendChild(that.element);
};
that.isExecuted = function () {
return my.executed;
};
// Init
my.executed = false;
my.setRequestedUrl();
my.setCallbacks();
my.setTimeout();
my.setElement();
CentralDispatch.RequestMap.add(that);
return that;
};
CentralDispatch.RequestMap = function () {
var klass = {}, requests = {}, findAllFor;
findAllFor = function (url) {
var regex, fullUrl;
// Exit with an exact match if possible for speed
if (requests[url]) {
return requests[url];
}
// TODO: The following is innefficient in the case of many requests
regex = new RegExp(url + '$');
for (fullUrl in requests) {
if (requests.hasOwnProperty(fullUrl)) {
if (regex.test(fullUrl)) {
return requests[fullUrl];
}
}
}
// Incase we don't find anything
return [];
};
klass.add = function (request) {
requests[request.url] = requests[request.url] || [];
requests[request.url].push(request);
};
klass.runAllFor = function (url, data) {
var matches, current;
matches = findAllFor(url);
current = matches.pop();
while (current) {
// TODO: Should clone data so that functions don't spoil the fun for
// others.
try {
current.success(data); 
current = matches.pop();
} catch (e) {
// Silently ignore errors so that other callbacks will run
}
}
};
klass.remove = function (request) {
var matches, i, match;
matches = findAllFor(request.url);
for (i = 0; i < matches.length; i += 1) {
if (matches[i] === request) {
match = i;
break;
}
}
if (match !== undefined) {
matches.splice(match, 1);
}
};
return klass;
}();
MBX.Client = function () {
var klass = {};
klass.nonHaBaseUrlFor = function (version) {
if (version === 'dev1') {
return 'http://localhost:3000';
} else if (version.match("prod[1-3]")) {
return 'http://www.motionbox.com';
} else if (version.match("stg[0-9]+-[0-9]")) {
return 'http://web.' + version.split('-')[0] + '.mbox';
} else {
throw ('Client.nonHaBaseUrlFor: Unknown version - ' + version);
}
};
klass.baseUrlFor = function (version) {
if (version === 'dev1') {
return 'http://localhost:3000';
} else if (version.match("prod[1-3]")) {
return 'http://ha.motionbox.com';
} else if (version.match("stg[0-9]+-[0-9]")) {
return 'http://web.' + version.split('-')[0] + '.mbox';
} else {
throw ('Client.baseUrlFor: Unknown version - ' + version);
}
};
klass.pathFor = function (version) {
if (version === 'dev1') {
return '/v2/ha';
} else if (version === 'prod1') {
return '/v2/ha';
} else if (version.match("prod[2-3]")) {
return '/s/ha';
} else if (version.match("stg[0-9]+-[0-9]")) {
return '/s/ha';
} else {
throw ('Client.pathFor: Unknown version - ' + version);
}
};
klass.baseHaUrlFor = function (version) {
return klass.baseUrlFor(version) + klass.pathFor(version);
};
klass.version = function (token) {
return token.split('.')[0];
};
klass.secret = function (token) {
return token.split('.')[1];
};
klass.HALocation = function (resource, token) {
var version = klass.version(token);
return [klass.baseHaUrlFor(version), '/', resource].join('');
};
klass.metadataUrlFor = function (resource, uid, token, collection) {
var version, secret, folder, file;
version = token.split('.')[0];
secret = token.split('.')[1];
folder = [secret.charAt(0), secret.charAt(1), secret.charAt(2), secret.charAt(3)].join('/');
if (version.match("prod[2-3]") || version.match("stg[0-9]+-2")) {
file = [uid, secret].join('-') + '.js';
if (collection) {
return [klass.HALocation(resource, token), collection, folder, file].join('/');
} else {
return [klass.HALocation(resource, token), folder, file].join('/');
}
} else {
if (collection) {
file = [collection, uid, secret].join('-') + '.js';
} else {
file = [uid, secret].join('-') + '.js';
}
return [klass.HALocation(resource, token), folder, file].join('/');
}
};
klass.requestData = function (url, callback, options) {
options = options || {};
if (options.skipCache !== false) {
options.skipCache = true;
}
CentralDispatch.requestData(url, callback, options);
};
klass.setTimeout = function (timeout) {
CentralDispatch.timeout = timeout;
};
return klass;
}();
MBX.domHelper = function () {
var self = {};
self.generateScriptTag = function (src) {
var element = document.createElement('script');
element.type = 'text/javascript';
element.src = src;
return element;
};
return self;
}();
MBX.Editor = function (){
var klass = {};
var editorSWF = null;
var statusCallback = null;
klass.setVideo = function(video) {
this.video = video;
};
klass.playMovie = function() {
MBX.Editor.callSWFFunction('playMovie');
};
klass.pauseMovie = function() {
MBX.Editor.callSWFFunction('pauseMovie');
};
klass.toggleMute = function() {
MBX.Editor.callSWFFunction('toggleMute');
};
klass.setStatusCallback = function(callback) {
statusCallback = callback;
};
klass.statusHandler = function(type, data) {
try {		
statusCallback(type, data);
} catch (e) {}
};
klass.callSWFFunction = function(functionName, params) {
if (editorSWF) {
if (params) {
return editorSWF[functionName](params);
} else {
return editorSWF[functionName]();
}
} else {
throw ("Editor SWF not defined");
}
};
klass.setEditorSWF = function(swf)  {
if (typeof swf == "string") {
if (navigator.appName.indexOf("Microsoft") != -1) {
editorSWF = document.getElementById(swf + '_object');
} else {
editorSWF = document.getElementById(swf + '_embed');
}
} else {
editorSWF = swf;
}
};
return klass;
}();
if (!MBX.Editor) {
MBX.Editor = {};
} else {
MBX.Editor = window.MBX.Editor;
}
MBX.Editor.Rotate = {
rotation: function() {
return MBX.Editor.callSWFFunction('rotation');
},
rotate: function(degrees) {
MBX.Editor.callSWFFunction('rotate', degrees);
}
};
if (!MBX.Editor) {
MBX.Editor = {};
} else {
MBX.Editor = window.MBX.Editor;
}
MBX.Editor.Trim = {
setStartTime: function(percent) {
MBX.Editor.callSWFFunction('setStartTime', percent);
MBX.Editor.statusHandler('trim', MBX.Editor.Trim.getTimes());
},
setEndTime: function(percent) {
MBX.Editor.callSWFFunction('setEndTime', percent);
MBX.Editor.statusHandler('trim', MBX.Editor.Trim.getTimes());
},
getTimes: function() {
return MBX.Editor.callSWFFunction('getTimes');
}
};
MBX.Folder = function () {
var klass, allForUserCallbacks, foldersMetadataUrlFor;
klass = {};
allForUserCallbacks = {};
foldersMetadataUrlFor = function (uid, token) {
return MBX.Client.metadataUrlFor('folders', uid, token, 'user');
};
klass.findAll = function (parent, uid, token, callback, options) {
if (parent === 'user') {
MBX.Client.requestData(foldersMetadataUrlFor(uid, token), callback, options);
} else {
throw ('Folder.findAll: unknown parent');
}
};
klass.allForUserMetadataReceive = function (uid, data) {
// silently ignore that this call is deprecated
};
return klass;
}();
MBX.Player = function () {
var klass, hdPlayerEmbed, flashPlayerEmbed, editorEmbed;
klass = {};
editorEmbed = function (uid, token, type, opts) {
var ret, width, height, wmode, wmodeEmbed, flashvars, params, attributes, id;
token = token.split('.')[1];
type = 'flv';
opts = opts || {};
width = opts.width || '416';
height = opts.height || '312';
if (!opts.wmode || (opts.wmode === 'none')) {
wmode = '';
wmodeEmbed = '';
}
else {
wmode = '<param name="wmode" value="' + opts.wmode + '">';
wmodeEmbed = 'wmode="' + opts.wmode + '"';
}
if (type !== 'hd' && type !== 'sd') {
type = 'sd';
}
id = uid + Math.floor(Math.random * 100000);
var video_url = "http%3A//www.motionbox.com/v1/videos/" + uid + "/player_manifest.xml%3Fapi_privacy_token%3D" + token;
ret = ['<object width="',
width,
'" height="',
height,
'" id="simple_editor_',
uid,
'_object" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" style="visibility: visible;">',
'<param value="http://bg-video.cp.motionbox.com/motionboxons/flash/SimpleEditor.swf" name="movie"/>',
'<param value="always" name="allowScriptAccess"/>',
wmode,
'<param value="video_url=',
video_url,
'&video_type=',
type,
'" name="flashvars"/>',
'<embed width="', width, '" height="', height, 
'" allowscriptaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer"  src="http://bg-video.cp.motionbox.com/motionboxons/flash/SimpleEditor.swf" type="application/x-shockwave-flash" ',
wmodeEmbed,
' id="simple_editor_',
uid,
'_embed"',
' flashvars="video_url=',
video_url, '&video_type=', type, '">',
'</object>'
].join('');
return ret;
};
hdPlayerEmbed = function (uid, token, type, opts) {
var ret, width, height, wmode, wmodeEmbed, flashvars, params, attributes, id;
opts = opts || {};
width = opts.width || '416';
height = opts.height || '312';
if (!opts.wmode || (opts.wmode === 'none')) {
wmode = '';
wmodeEmbed = '';
}
else {
wmode = '<param name="wmode" value="' + opts.wmode + '">';
wmodeEmbed = 'wmode="' + opts.wmode + '"';
}
if (type !== 'hd' && type !== 'sd') {
type = 'sd';
}
id = uid + Math.floor(Math.random * 100000);
ret = ['<object width="',
width,
'" height="',
height,
'" id="progressive_player_',
id,
'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" style="visibility: visible;">',
'<param value="http://bg-video.cp.motionbox.com/motionboxons/flash/VideoPlayer.swf" name="movie"/>',
'<param value="always" name="allowScriptAccess"/>',
'<param value="true" name="allowFullscreen"/>',
wmode,
'<param value="video_uid=',
uid,
'&security_token=',
token,
'&type=',
type,
'" name="flashvars"/>',
'<!--[if !IE]>-->',
'<object width="', width, '" height="', height, 
'" name="progressive_player" allowscriptaccess="always" allowfullscreen="true" data="http://bg-video.cp.motionbox.com/motionboxons/flash/VideoPlayer.swf" type="application/x-shockwave-flash" ',
wmodeEmbed,
' flashvars="video_uid=',
uid, '&security_token=', token, '&type=', type, '">',
'<!--<![endif]-->',
'<h2>To watch the video, you\'ll first need to  <a href="http://www.adobe.com/go/getflashplayer">install the flash player</a>.</h2>',
'<!--[if !IE]>-->',
'</object>',
'<!--<![endif]-->',
'</object>'
].join('');
return ret;
};
klass.embedFor = function (uid, token, type, opts) {
return hdPlayerEmbed(uid, token, type, opts);
};
klass.editorFor = function (uid, token, type, opts) {
return editorEmbed(uid, token, type, opts);
};
return klass;
}();
MBX.Thumbnail = function () {
var klass = {};
// BEGIN nasty code duplication on account of thumbnail location
klass.pathFor = function (version) {
if (version === 'dev1') {
return '/v2/ha';
} else if (version.match("prod[1-3]")) {
return '/v2/ha';
} else if (version.match("stg[0-9]+-[0-9]")) {
return '/v2/ha';
} else {
throw ('Thumbnail.pathFor: Unknown version - ' + version);
}
};
klass.baseHaUrlFor = function (version) {
return MBX.Client.baseUrlFor(version) + klass.pathFor(version);
};
klass.HALocation = function (resource, token) {
var version = token.split('.')[0];
return [klass.baseHaUrlFor(version), '/', resource].join('');
};
klass.metadataUrlFor = function (resource, uid, token, collection) {
var secret, folder, file;
secret = token.split('.')[1];
folder = [secret.charAt(0), secret.charAt(1), secret.charAt(2), secret.charAt(3)].join('/') + '/';
if (collection) {
file = [collection, uid, secret].join('-') + '.js';
} else {
file = [uid, secret].join('-') + '.js';
}
return [klass.HALocation(resource, token), '/', folder, file].join('');
};
// END nasty code duplication on account of thumbnail location
klass.urlFor = function (uid, token, quality) {
return klass.metadataUrlFor(quality + 's', uid, token, 'video');
};
return klass;
}();
MBX.Upload = {
status: function (url, callback, options) {
options = options || {};
options.jsonp = options.jsonp || "CentralDispatch";
if (!url.match(".js$")) {
url = url + ".js";
}
MBX.Client.requestData(url, callback, options);
}
};
MBX.User = function () {
var klass = {}, 
callbacks = {}, 
metadataUrlFor;
metadataUrlFor = function (uid, token) {
return MBX.Client.metadataUrlFor('users', uid, token);
};
klass.find = function (uid, token, callback, options) {
MBX.Client.requestData(metadataUrlFor(uid, token), callback, options);
};
klass.metadataReceive = function (uid, data) {
// silently ignore that this call is deprecated
};
return klass;
}();
MBX.Video = function () {
var klass = {},
allForFolderCallbacks = {},
videoCallbacks = {},
collectionMetadataUrlFor,
pathForVideo,
metadataUrlFor;
pathForVideo = function(version) {
return 'v2/ha';
};
collectionMetadataUrlFor = function (parent, uid, token) {
return MBX.Client.metadataUrlFor('videos', uid, token, parent);
};
metadataUrlFor = function (uid, token) {
var version, secret, folder, file;
version = token.split('.')[0];
secret = token.split('.')[1];
folder = [secret.charAt(0), secret.charAt(1), secret.charAt(2), secret.charAt(3)].join('/');
file = [uid, secret].join('-') + '.js';
return [MBX.Client.baseUrlFor(version), pathForVideo(version), 'videos', folder, file].join('/');
};
klass.encodeUrlFor = function (uid, token, format) {
var version, base;
version = MBX.Client.version(token);
return MBX.Client.nonHaBaseUrlFor(version) +
"/v2/videos/" +
uid +
"/encode.js?callback=CentralDispatch.receiveData&security_token=" +
MBX.Client.secret(token) +
"&encodeFormat=" +
format +
"&nocache=" +
(new Date()).valueOf();
};
klass.allForFolderMetadataReceive = function (uid, data) {
// silently ignore that this call is deprecated
};
klass.metadataReceive = function (uid, data) {
// silently ignore that this call is deprecated
};
klass.findAll = function (parent, uid, token, callback, options) {
if (parent === 'folder') {
MBX.Client.requestData(collectionMetadataUrlFor('folder', uid, token), callback, options);
} else {
throw ('Video.findAll: unknown parent');
}
};
klass.find = function (uid, token, callback, options) {
MBX.Client.requestData(metadataUrlFor(uid, token), callback, options);
};
klass.encode = function (uid, token, format, callback, options) {
var url = klass.encodeUrlFor(uid, token, format);
options = options || {};
options.expectedUrl = options.expectedUrl || url.split("?")[0];
return CentralDispatch.requestData(url, callback, options);
};
klass.encodingProgress = function (idsAndTokens, callback, options) {
var url = klass.encodingProgressUrlFor(idsAndTokens);
options = options || {};
options.jsonp = options.jsonp || "CentralDispatch";
return MBX.Client.requestData(url, callback, options);
};
klass.encodingProgressUrlFor = function (idsAndTokens) {
var uids, version, i;
uids = [];
for (i = 0; i < idsAndTokens.length; i += 1) {
uids[i] = idsAndTokens[i].uid;
}
version = MBX.Client.version(idsAndTokens[0].securityToken);
return MBX.Client.baseUrlFor(version) +
"/v2/encoding_progress/" +
uids.join("-") + '.js';
};
return klass;
}();
