/* 
Share Annotation Plugin v1.0 (https://github.com/danielcebrian/share-annotator)
Copyright (C) 2014 Daniel Cebri�n Robles
License: https://github.com/danielcebrian/share-annotator/blob/master/License.rst

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
// Generated by CoffeeScript 1.6.3
var _ref,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

Annotator.Plugin.Share = (function(_super) {
	__extends(Share, _super);
	
	//Default Share configuration
	Share.prototype.options = {
		shareIn:['facebook','twitter','email','google'],
		getUrl:{
			'facebook':function(title,link,noteText){
				return 'https://www.facebook.com/sharer/sharer.php?s=100&p[url]='+link+'&p[title]='+encodeURIComponent('Open Video Annotation')+'&p[summary]='+noteText;
			},
			'twitter':function(title,link,noteText){
				return 'https://twitter.com/intent/tweet?original_referer='+link+'&source=tweetbutton&url='+link+ "&via=OpenVideoAnnotation&text=" +encodeURIComponent('I want to share the next Open Video Annotation: ');
			},
			'google':function(title,link,noteText){
				return 'https://plus.google.com/share?url='+link;
			},
			'email': function(title,link,noteText){
				return 'mailto:?subject='+title+'&body='+link;
			}
		},
		baseUrl:'', //baseUrl = the base url for all the shared annotations
	};

	function Share(element,options) {
		if (typeof options!='undefined')
			this.options.shareIn = typeof options.shareIn!='undefined'?options.shareIn:this.options.shareIn;
		this.buildHTMLShareButton = __bind(this.buildHTMLShareButton, this);
		this.runningAPI = __bind(this.runningAPI, this);
		this.updateViewer = __bind(this.updateViewer, this);
		_ref = Share.__super__.constructor.apply(this, arguments);
		return _ref;
	}

	Share.prototype.field = null;

	Share.prototype.input = null;

	Share.prototype.pluginInit = function() {
		console.log("Share-pluginInit");
		//Check that annotator is working
		if (!Annotator.supported()) {
			return;
		}
		
		//-- Editor
		this.field = this.annotator.editor.addField({
			type: 'input', //options (textarea,input,select,checkbox)
		});

		//Modify the element created with annotator to be an invisible span
		var newfield = Annotator.$('<li class="annotator-item">'+this.buildHTMLShareButton('Share without saving:')+'</li>');
		Annotator.$(this.field).replaceWith(newfield);
		this.field=newfield[0];
		
		//Create the actions for the buttons
		this.buttonsActions(this.field,2,this.options.baseUrl); //2 is the method of the API that will be for share without saving
		
		//Init the API plugin
		var APIoptions = this.initAPI();
		
		this.runAPI(APIoptions);
		
		//-- Viewer
		var newview = this.annotator.viewer.addField({
			load: this.updateViewer,
		});

		return this.input = $(this.field).find(':input');
	};
	
	//Share button HTML
	Share.prototype.buildHTMLShareButton = function(title,id) {
		var title = title || '',
			id = typeof id!='undefined'?'annotationId="'+id+'"':'',
			titleText = title!=''?'<div class="share-text-annotator">'+title+'</div>':'',
			shareButton = '<div class="share-button-annotator share-button" '+id+'></div>',
			popup = '<div class="share-popup-overlay-bg" style="z-index:30000000000"><div class="share-popup"><div class="share-popup-items"></div><div class="close-btn">Close</div></div></div>';
		return '<div class="share-container-annotator">'+titleText+shareButton+popup+'</div>';
	}
	
	//template for the design of the Share Plugin
	Share.prototype.buildHTMLPopup = function(title) {
		var buttons = '';
		if (typeof this.options.shareIn!='undefined'){
			this.options.shareIn.forEach(function(item) { 
				buttons += '<div class="share-'+item+'-annotator share-button">'+item.charAt(0).toUpperCase() + item.slice(1)+'</div>';
			});
		}
		this.uri = typeof this.uri!='undefined'?this.uri:'';
		var title = '<div class="share-popup-title">'+title.replace(":","")+'</div>',
			copy = '<div class="share-popup-copy">Copy and Share:</div>',
			uri = '<input type="text" class="share-popup-uri" onclick="javascript:this.select();" readonly="true" value="'+this.uri+'">',
			popup = title + buttons + copy + uri;
		return popup;
	}
	
	//Create the actions for the buttons
	Share.prototype.buttonsActions = function(field,method,url) {
		var share = this;
		
		// hide popup when user clicks on close button
		$(field).find('.close-btn').click(function() {
			$('.share-popup-overlay-bg').hide();
		});
		// hides the popup if user clicks anywhere outside the container
		$(field).find('.share-popup-overlay-bg').click(function() {
			$('.share-popup-overlay-bg').hide();
		});
		// prevents the overlay from closing if user clicks inside the popup overlay
		$(field).find('.share-popup').click(function() {
			return false;
		});
		// Share button
		$(field).find('.share-button-annotator.share-button').click(function() {
		    event.preventDefault(); // disable normal link function so that it doesn't refresh the page
		    var _field = this,
		    	ovaId = $(this).attr('annotationId'),
		    	title = method == 1?'Share':'Share without saving';
		    
		    // share.uri will be useful for buildHTMLPopup functions
		    share.uri = share.createAPIURL(method,ovaId,url); 
		    
		    //display your popup
		    $(this).parent().find('.share-popup-overlay-bg').show(); 
		    
		    //build buttons
		    $(this).parent().find('.share-popup-items').html(share.buildHTMLPopup(title)); 
		    
		    //buttons actions
			if (typeof share.options.shareIn!='undefined'){
				share.options.shareIn.forEach(function(item) {
					$(_field).parent().find('.share-'+item+'-annotator.share-button').click(function() {
						var url = share.createAPIURL(method,ovaId,url),
							title = "Sharing a annotation with Open Video Annotation";
							link = encodeURIComponent(url),
							noteText = share.getSource('ovaText'),
							finalUrl = '';
						if (method==1){
							var viewer = share.annotator.viewer,
								textarea = $(viewer.element).find('div:first').html();
							noteText = encodeURIComponent(textarea);
						}
						finalUrl = typeof share.options.getUrl[item]!='undefined'?share.options.getUrl[item](title,link,noteText):'';
						if(typeof share.options.getUrl[item]!='undefined')
							window.open(finalUrl);
					}); 
				});
			}
		});
	};
	
	
	Share.prototype.createAPIURL = function(method,ovaId,url) {
		var annotator = this.annotator,
			editor = annotator.editor,
			method = method || 1,
			//url = location.protocol + '//' + location.host + location.pathname,
			url = url || window.location.href;
		
		url += (url.indexOf('?') >= 0)?'&':'?';
			
		if (method === 1){
			var ovaId = typeof ovaId!='undefined'?ovaId:'';
			url += 'ovaId=' + ovaId;
		}else if (method === 2){
			var ovaStart = this.getSource('ovaStart'),
				ovaEnd = this.getSource('ovaEnd'),
				ovaText = this.getSource('ovaText');
			url += 'ovaStart='+ ovaStart
					+'&ovaEnd='+ ovaEnd
					+'&ovaText='+ ovaText;
			if(typeof editor.VideoJS!='undefined' && editor.VideoJS !== -1){//Video Annotation
				var	ovaContainer = this.getSource('ovaContainer'),
					ovaSrc = this.getSource('ovaSrc');
				url += '&ovaContainer='+ovaContainer
					+'&ovaSrc='+ ovaSrc;
			}else{//Text Annotation
				var	ovastartOffset = this.getSource('ovastartOffset'),
					ovaendOffset = this.getSource('ovaendOffset');
				url += '&ovastartOffset='+ovastartOffset
					+'&ovaendOffset='+ ovaendOffset;
			}
		}
		return url;
	};
	
	Share.prototype.getSource = function(source) {
		var	source = source || '';
		if (source == 'ovaId') {//method 1
			source=this.annotation.id;
		}else{//method 2
			var annotator = this.annotator,
				editor = annotator.editor,
				textarea = $(editor.element).find('textarea')[0];
			if(source == 'ovaText')
				source = textarea.value;
			if (typeof editor.VideoJS!='undefined' && editor.VideoJS !== -1){//Video Annotation
				if(source == 'ovaContainer')
					source = editor.VideoJS;
				else if(source == 'ovaSrc')
					source = annotator.mplayer[editor.VideoJS].tech.options_.source.src;
				else if(source == 'ovaStart')
					source = annotator.mplayer[editor.VideoJS].rangeslider.getValues().start;
				else if(source == 'ovaEnd')
					source = annotator.mplayer[editor.VideoJS].rangeslider.getValues().end;
		
			}else{//Text Annotation
				var annotation = editor.annotation;
				if(source == 'ovastartOffset')
					source = annotation.ranges[0].startOffset;
				else if(source == 'ovaendOffset')
					source = annotation.ranges[0].endOffset;
				else if(source == 'ovaStart')
					source = annotation.ranges[0].start;
				else if(source == 'ovaEnd')
					source = annotation.ranges[0].end;
			}
		}
		return encodeURIComponent(source);
	};
	
	Share.prototype.initAPI = function() {
		console.log("initAPI");
		// -- Detect API in the URL -- //
		/*
		The first option is to give a known id of an annotation
		Example http://url.com/#id=rTcpOjIMT2aF1apDtboC-Q
		*/
		var API = {},
			ovaId = this.getParameterByName('ovaId'), //Method 1 (Obligatory)
			start = this.getParameterByName('ovaStart'), //Method 2 (Obligatory)
			end = this.getParameterByName('ovaEnd'), //Method 2 (Obligatory)
			container = this.getParameterByName('ovaContainer'), //Method 2 (Obligatory)
			src = this.getParameterByName('ovaSrc'),//Method 2 (Obligatory)
			text = this.getParameterByName('ovaText'),//Method 2 
			user = this.getParameterByName('ovaUser'),//Method 2 
			startOffset = this.getParameterByName('ovastartOffset'),//Method 2 
			endOffset = this.getParameterByName('ovaendOffset');//Method 2 
		
		//remove the variables from the url browser
		var stripped_url = top.location.href;
		if (ovaId != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaId');
		if (start != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaStart');
		if (end != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaEnd');
		if (container != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaContainer');
		if (src != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaSrc');
		if (text != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaText');
		if (user != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaUser');
		if (startOffset != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovastartOffset');
		if (endOffset != '') stripped_url = this.removeVariableFromURL(stripped_url, 'ovaendOffset');
  		window.history.pushState("object or string", "Title", stripped_url);
  		
		
		// Method 1 API with the Id of the annotation
		//Example: http://danielcebrian.com/annotations/demo.html?&ovaId=wtva_SjnQb2HtqppDihKug
		if(ovaId != ''){
			$.extend(API,{method:1,ovaId:ovaId});
		}
		//Method 2 API with all the parameter to load the annotation
		//Example with video: http://danielcebrian.com/annotations/demo.html?ovaContainer=vid1&ovaSrc=http%3A%2F%2Fvideo-js.zencoder.com%2Foceans-clip.mp4&ovaStart=2&ovaEnd=10&ovaText=This%20is%20test&ovaUser=Test%20User
		//Example with text: http://danielcebrian.com/annotations/demo.html?ovaStart=%2Fp%5B1%5D&ovaEnd=%2Fp%5B1%5D&ovastartOffset=542&ovaendOffset=572&ovaText=API
	
		if(start!='' && end!='' && container!='' && src!=''){//video api
			$.extend(API,{method:2,start:start,end:end,container:container,src:src,text:text,user:user});
		}else if(start!='' && end!='' && startOffset!='' && endOffset!=''){//text api
			$.extend(API,{method:2,start:start,end:end,startOffset:startOffset,endOffset:endOffset,text:text,user:user});
		}
		return API;
	}
	Share.prototype.runningAPI =  function (annotations,API){
		console.log("runningAPI");
		var wrapper = $('.annotator-wrapper').parent()[0],
			mplayer,
			osda,
			self=this;
			
		//Set Annotator in wrapper to fix quick DOM
		$.data(wrapper, 'annotator', self.annotator);//Set the object in the span
		annotator = window.annotator = $.data(wrapper, 'annotator');
		mplayer = typeof annotator.mplayer!='undefined'?annotator.mplayer:[];
		osda = typeof annotator.osda!='undefined'?annotator.osda:[];
		
		//Detect if the URL has an API element
		if (typeof API!='undefined' && typeof API.method!='undefined' && (API.method=='1'||API.method=='2')) {
			if(API.method=='1'){
				var allannotations = annotator.plugins['Store'].annotations,
					ovaId = decodeURIComponent(API.ovaId);
				
				for (var item in allannotations) {
					var an = allannotations[item];
					if (typeof an.id!='undefined' && an.id == ovaId){//this is the annotation
						if(self._isVideo(an)){//It is a video
							if (typeof mplayer[an.target.container]!='undefined'){
								var player = mplayer[an.target.container];
								if (player.id_ == an.target.container){
									var anFound = an;
									videojs(player.id_).ready(function(){
										if (player.techName != 'Youtube'){
											player.preload('auto');
										}
										player.autoPlayAPI = anFound;
										player.play();
									});
								}
							}
						}else if(self._isVideo(an)){//It is a OpenSeaDragon Annotation
							if (typeof mplayer[an.target.container]!='undefined'){
								var player = mplayer[an.target.container];
								if (player.id_ == an.target.container){
									var anFound = an;
									videojs(player.id_).ready(function(){
										if (player.techName != 'Youtube'){
											player.preload('auto');
										}
										player.autoPlayAPI = anFound;
										player.play();
									});
								}
							}
						}else{//It is a text
							var hasRanges = typeof an.ranges!='undefined' && typeof an.ranges[0] !='undefined',
								startOffset = hasRanges?an.ranges[0].startOffset:'',
								endOffset = hasRanges?an.ranges[0].endOffset:'';
				
							if(typeof startOffset!='undefined' && typeof endOffset!='undefined'){ 
								//change the color
								$(an.highlights).addClass('api'); 
								//animate to the annotation
								$('html,body').animate({
									scrollTop: $(an.highlights[0]).offset().top},
									'slow');
							}
						}
					}
				}
			}else if (API.method=='2'){
				if (typeof mplayer!='undefined'){
					//variable for Video
					var	container = decodeURIComponent(API.container),
						player = mplayer[container],
						isVideo = (typeof player!='undefined' && container==player.id_),
						isNumber = (!isNaN(parseFloat(API.start)) && isFinite(API.start) && !isNaN(parseFloat(API.end)) && isFinite(API.end)),
						isSource = false;
						
					if(isVideo){
						//Compare without extension
						var src = decodeURIComponent(API.src),
							targetSrc = src.substring(0,src.lastIndexOf(".")),
							playerSrc = player.tech.options_.source.src==''?player.tag.currentSrc:player.tech.options_.source.src;
						playerSrc = playerSrc.substring(0,playerSrc.lastIndexOf("."))
						isSource = (targetSrc == playerSrc);
					}
		
					//Open Video Annotation
					if(isVideo && isNumber && isSource){ 
						var annotation = {
								rangeTime: {
									start:API.start,
									end:API.end
								},
								created: new Date().toISOString(),
								updated: new Date().toISOString(),
								target:{
									container: container,
									src: src
								},
								media: 'video',
								text:decodeURIComponent(API.text),
								user:decodeURIComponent(API.user)
							};
						videojs(player.id_).ready(function(){
							if (player.techName != 'Youtube'){
								player.preload('auto');
							}
							player.autoPlayAPI = annotation;
							player.play();
						});
					}
				}
				//variable for text
				var startOffset = API.startOffset,
					endOffset = API.endOffset;
				
				//Text Annotation
				if(!isVideo && typeof startOffset!='undefined' && typeof endOffset!='undefined'){ 
					var annotation = {
						ranges: [{
							start:decodeURIComponent(API.start),
							end:decodeURIComponent(API.end),
							startOffset:decodeURIComponent(API.startOffset),
							endOffset:decodeURIComponent(API.endOffset),
						}],
						created: new Date().toISOString(),
						updated: new Date().toISOString(),
						media: 'text',
						text:decodeURIComponent(API.text),
						user:decodeURIComponent(API.user)
					};
					//show the annotation
					annotator.setupAnnotation(annotation);
					//to change the color
					$(annotation.highlights).addClass('api'); 
					//animate to the annotation
					$('html,body').animate({
						scrollTop: $(annotation.highlights[0]).offset().top},
						'slow');
				}
				
			}
		}
		//Let know to others API that this plugin is loaded
		annotator.isShareLoaded = true;
		annotator.publish('shareloaded');
	}
	Share.prototype.runAPI = function(API) {
		var self = this;
		var func = function (annotations){
			self.runningAPI(annotations,API);
			self.annotator.unsubscribe("annotationsLoaded",func);	
		};
		this.annotator
			//-- Finished the Annotator DOM
			.subscribe("annotationsLoaded",func);
	}
	
	Share.prototype._isVideo = function(an){
		//Detect if the annotation is a Open Video Annotation
		var an = an || {}
			rt = an.rangeTime,
			isVideo = (typeof an.media!='undefined' && an.media=='video'),
			hasContainer = (typeof an.target!='undefined' && typeof an.target.container!='undefined' ),
			isNumber = (typeof rt!='undefined' && !isNaN(parseFloat(rt.start)) && isFinite(rt.start) && !isNaN(parseFloat(rt.end)) && isFinite(rt.end));
		return (isVideo && hasContainer && isNumber);
	}
	
	Share.prototype.getParameterByName = function(name) {
		name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
		var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
			//results = regex.exec(location.search),
        	results = regex.exec('?'+window.location.href.split('?')[1]);
		return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
	};
	
	Share.prototype.removeVariableFromURL = function(url_string, variable_name) {
		var URL = String(url_string);
		var regex = new RegExp( "\\?" + variable_name + "=[^&]*&?", "gi");
		URL = URL.replace(regex,'?');
		regex = new RegExp( "\\&" + variable_name + "=[^&]*&?", "gi");
		URL = URL.replace(regex,'&');
		URL = URL.replace(/(\?|&)$/,'');
		regex = null;
		return URL;
	}

	Share.prototype.updateViewer = function(field, annotation) {
		this.annotation = annotation;
		
		var self = this,
			field = $(field),
			ret = field.addClass('share-viewer-annotator').html(function() {
				var string;
				return self.buildHTMLShareButton('Share:',self.getSource('ovaId'));
			});
			
			
		//Create the actions for the buttons
		this.buttonsActions(field[0],1,this.options.baseUrl); //1 is the method of the API that will be for share some annotation in the database
		return ret;
	};

	return Share;

})(Annotator.Plugin);