/**
 * Scalar
 * Copyright 2013 The Alliance for Networking Visual Culture.
 * http://scalar.usc.edu/scalar
 * Alliance4NVC@gmail.com
 *
 * Licensed under the Educational Community License, Version 2.0
 * (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.osedu.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

(function($) {

	$.scalarmedia = function(m, e, options) {

		var mediaelement = m;
		var element = e;

		var media = {

			options: $.extend({
				'shy':true,
				'details': null,
				'caption': 'description'
			}, options),

			showAnnotation: function(e, relation, m, forceShow) {

				// make sure this is the right mediaelement
				if ( mediaelement.model.id == m.model.id ) {

					// and that we already know about the annotation
					if (annotations.indexOf(relation) != -1) {
						var currentAnnotationTable = currentAnnotation.find('table');
						var annotationTable = annotationPane.find('table');

						// if the annotation isn't already highlighted or we're showing it no matter what, then
						if ((currentRelation != relation) || forceShow) {

							// if the annotation tab is hidden and this is not a spatial annotation, then show the single annotation display
							// (spatial annotations will be displayed directly over the image, so we don't need to show them here)
							if ((annotationPane.css('display') == 'none') && ( relation.target.current.mediaSource.contentType != 'image' )) {
								currentAnnotationTable.empty();

								var row = $('<tr><td>'+relation.startString+'</td><td></td></tr>').appendTo(currentAnnotationTable);
								media.addContentForAnnotationToContainer( "single-anno-", relation.body, row.find( 'td' ).eq( 1 ) );

								row.data('relation', relation);
								row.data('media',mediaelement);
								row.on('click', function( event ) {
									// only clicks on the background should cue up the annotation
									if ( $( event.target ).is( 'td,h4,div,p,tr' ) ) {
										var relation = $(this).data('relation');
										$(this).data('media').seek(relation);
										media.sendMessage($(this).data('media'), media.annotationHasMessage(relation));
										if (( relation.target.current.mediaSource.contentType != 'document' ) && ( relation.target.current.mediaSource.contentType != 'image' ) && ( relation.target.current.mediaSource.contentType != '3D' ) && ( relation.target.current.mediaSource.contentType != '3D-GIS' )) {
											setTimeout(function() {
													if(!$(this).data('media').is_playing()) {
											$(this).data('media').play();
													}
											},250);
										}
									}
								});

								currentAnnotation.slideDown();

							// otherwise, update the list of all annotations
							} else {

								$(annotationTable).find('tr').removeClass('current');
								$(annotationTable).find('tr').each(function() {

									var rowRelation = $(this).data('relation');
									var col = $(this).find('td').eq(1);


									if ( rowRelation != null ) {

										// show the content of the selected annotation
										if (rowRelation == relation) {

											$(this).addClass('current');

											// only rebuild the annotation content if it isn't already showing
											if ( $( '.media_annotations #anno-' + rowRelation.body.slug ).length == 0 ) {
												col.empty();
												media.addContentForAnnotationToContainer( "anno-", rowRelation.body, col );

											} else {
												col.find( 'h4' ).contents().wrap( '<a href="' + rowRelation.body.url + '"></a>' );
												col.find( 'h4' ).addClass( 'heading_weight' );
											}

											col.find('div').eq( 0 ).slideDown();

										// hide the content of all other annotations
										} else {
											col.find( 'h4 > a' ).contents().unwrap();
											col.find( 'h4' ).removeClass( 'heading_weight' );
											col.find( 'div' ).eq( 0 ).slideUp();
										}
									}
								});
							}

							currentRelation = relation;

						} else {
							if (annotationPane.css('display') == 'none') {
								currentAnnotationTable.find('td').eq(0).text( relation.startString );
							}
						}
					}
				}
			},

      annotationHasMessage: function(annotation) {
        let result = false;
        if (annotation.body.current.properties['http://purl.org/dc/terms/abstract']) {
          result = annotation.body.current.properties['http://purl.org/dc/terms/abstract'][0].value;
        }
        return result;
      },

      sendMessage: function(mediaelement, message) {
    		if (message && mediaelement.view.mediaObjectView.hasFrameLoaded) {
          mediaelement.sendMessage(message);
    		}
    	},

			hideAnnotation: function(e, relation, m, forceHide) {

				if ( mediaelement.model.id == m.model.id ) {
					//if ((currentRelation != null) || forceHide) {

						if (annotationPane) {

							//console.log('hide '+((relation == null) ? 'null' : relation.body.getDisplayTitle())+' for '+mediaelement.model.node.getDisplayTitle());

							if (annotationPane.css('display') == 'none') {
								if (currentRelation == relation) {
									currentAnnotation.slideUp();
									currentRelation = null;
								}
							} else if (relation != null) {
								var annotationTable = annotationPane.find('table');
								//$(annotationTable).find('tr').removeClass('current');
								$(annotationTable).find('tr').each(function() {
									var rowRelation = $(this).data('relation');
									if (rowRelation == relation) {
										$(this).removeClass('current');
										if (rowRelation.body.current.content != null) {
											var col = $(this).find('td').eq(1);
											col.find('h4 > a').contents().unwrap();
											col.find('h4').removeClass( 'heading_weight' );
											col.find('div').eq(0).slideUp();
										}
									}
								});
								if (currentRelation == relation) currentRelation = null;
							}
						}
					//}
				}
			},

			addContentForAnnotationToContainer: function( idPrefix, annotation, container ) {

				var content, tag, tags, tagBar, tagItem, labelClass, i, n;

				// add the title
				var header = $('<h4 class="heading_weight"><a href="' + annotation.url + '">'+ annotation.getDisplayTitle() +'</a></h4>');
				container.append(header);

				content = $( '<div id="' + idPrefix + annotation.slug +'"></div>' ).appendTo( container );

				var width = container.parents('.mediainfo').width() - container.parents('tr').children('td').first().width() - 60;
				var height = parseInt(container.parents('.media_annotations').css('max-height')) - container.parents('.media_annotations').innerHeight() - 10;
				if(content.parents('.right,.left').length > 0){
					height = null;
				}
				// add the annotation description
				var description = annotation.getDescription();
				if(description.length > 0){
					var temp = $('<div>'+description+'</div>').appendTo(content);

					$(page.getMediaLinks(temp)).each(function(){
						if($(this).hasClass('inline')){
							$(this).wrap('<div></div>').hide().removeClass('inline');
						}
					});

					wrapOrphanParagraphs(temp);

					temp.children('p:not(:last-child),div:not(:last-child)').wrap('<div class="paragraph_wrapper"></div>');

					if(content.parents('.slot.right,.slot.left').length > 0){
						height = null;
					}

					$(page.getMediaLinks(content)).each(function(){
						$(this).attr({
							'data-align':'',
							'data-size':'full',
							'data-annotations':'[]',
							'class':'media_link'
						});
						var parent = $(this).parent();
						page.addNoteOrAnnotationMedia($(this),parent,width,height);
					});
				}
				// get incoming tags and display them as buttons
				tags = annotation.getRelatedNodes( "tag", "incoming" );
				n = tags.length;
				if ( n > 0 ) {
					tagBar = $( '<div class="mini-tag-bar">Tags:&nbsp; </div>' ).appendTo( content );
				}
				for ( i = 0; i < n; i++ ) {
					tagBar.append( " " );
					tag = tags[ i ];
					tagItem = $( '<a href="javascript:;" id="anno-tag-' + tag.slug + '" class="anno-tag btn btn-xs btn-default">' + tag.getDisplayTitle() + '</a>' ).appendTo( tagBar );
					tagItem.data( 'tag', tag );

					// when a tag button is clicked, toggle it on and all the others off,
					// and show its content below
					tagItem.on('click',  function( event ) {
						event.preventDefault();
						var me = $( this );
						if ( me.hasClass( 'btn-primary' ) ) {
							me.parent().find( '.anno-tag' ).removeClass( 'btn-primary' ).addClass( 'btn-default' );
							me.parent().parent().find( '.anno-tag-content' ).empty();
						} else {
							$( this ).parent().find( '.anno-tag' ).removeClass( 'btn-primary' ).addClass( 'btn-default' );
							$( this ).removeClass( 'btn-default' );
							$( this ).addClass( 'btn-primary' );
							var tag = $( this ).data( 'tag' );
							var nodeContent = me.parent().parent().find( '.anno-tag-content' ).empty();
							nodeContent.append( tag.getDescription() );
						}
					})
				}
				if ( n > 0 ) {
					content.append( '<p class="anno-tag-content"></p>' );
				}

				if(annotation.hasScalarType( 'media' ) && content.find('.annotation_media_'+annotation.slug).length == 0){
					var parent = $('<div class="node_media_'+node.slug+'"></div>').appendTo(content);
					var link = $( '<a href="'+annotation.current.sourceFile+'" data-annotations="[]" data-align="center" resource="'+annotation.slug+'"></a>' ).hide().appendTo(parent);
					page.addNoteOrAnnotationMedia(link,parent,width,height);
				}

			},

			minimizeAnnotationPane: function() {
				if (annotationPane) {
					var annotationTable = annotationPane.find('table');
					$(annotationTable).find('tr').each(function() {
						var rowRelation = $(this).data('relation');
						var col = $(this).find('td').eq(1);
						col.empty();
						col.append('<p>'+rowRelation.body.getDisplayTitle()+'</p>');
					});
				}
			},

			addNextRelatedMedia: function() {
				if (!relations) return
				relationIndex++
				if (relationIndex < relations.length) {
					var relation = relations[relationIndex];
					try {
						var obj = JSON.parse(relation)
						// if no error, then we got legal JSON and this item is not related media; try the next one
						this.addNextRelatedMedia()
						return
					} catch(error) {
						// no valid JSON found; continue
					}
					if (scalarapi.getFileExtension(relation) == 'vtt') {
						// if extension is 'vtt', then this item is a vtt file; try the next one
						this.addNextRelatedMedia()
						return
					} else {
						if (scalarapi.loadNode(relation, null, this.handleRelatedMediaLoaded, this.handleRelatedMediaError) == 'loaded') media.handleRelatedMediaLoaded()
					}
				} else {
					this.displayRelatedMedia()
				}
			},

			handleRelatedMediaLoaded: function() {
				var node = scalarapi.getNode(relations[relationIndex])
				relatedNodes.push(node)
				media.addNextRelatedMedia()
			},

			handleRelatedMediaError: function() {
				console.log('error loading related media')
			},

			showTab: function(tab, pane) {
				tab.parent().parent().find('.pane').hide();
				media.minimizeAnnotationPane();
				pane.show();
				tab.parent().find('.media_tab').removeClass('select');
				tab.addClass('select');
				if (currentRelation != null) {
					currentAnnotation.slideUp();
					media.showAnnotation(null, currentRelation, mediaelement, true);
				}
			},

			displayRelatedMedia: function() {
				if (relatedNodes.length > 0) {
					var relatedTab = $('<input type="radio" class="media_tab" name="media_tab" id="relatedTab"><label for="relatedTab">Related</label>').appendTo(mediaTabs);
					var relatedPane = $('<div class="media_related pane"></div>').appendTo(element);
					relatedNodes.forEach(function (node) {
						var nodeDescription = ''
						if (node.current.description) nodeDescription = node.current.description
						relatedPane.append('<p><a href="'+node.url+'"><strong>'+node.current.title+'</strong></a> ('+node.current.mediaSource.name+' '+node.current.mediaSource.contentType+')</br>'+nodeDescription+'</p>')
					})
					relatedPane.hide()
					relatedTab.on('click', function() { media.showTab($(this), relatedPane) });
				}
			}
		}

		var node = mediaelement.model.node;
		var relations = node.current.auxProperties['dcterms:relation']
		var relationIndex = -1;
		var relatedNodes = []

		if (element != null) {
			var currentAnnotation = $('<div class="current_annotation"><table></table></div>').appendTo(element);

			var currentRelation = null;

			var mediaTabs = $('<div class="media_tabs"></div>').appendTo(element);

			var foundAuxContent = false;

			var description;
			switch ( media.options.caption ) {

				case 'title':
				description = '<a class="citations-link" href="javascript:;">' + node.getDisplayTitle() + '</a>';
				break;

				case 'title-and-description':
				if ( node.current.description != null ) {
					description = '<a class="citations-link" href="javascript:;"><strong>' + node.getDisplayTitle() + '</strong></a><br>' + node.current.description;
				} else {
					description = node.getDisplayTitle();
				}
				break;

				case 'metadata':
				description = $('<div></div>');
				addMetadataTableForNodeToElement(node, description);
				description.unwrap();
				break;

				default:
				description = node.current.description;
				if ( node.current.description == null ) {
					description = '<p><i>No description available.</i></p>';
				}
				break;

			}
			if ( media.options.caption != 'none' ) {
				var descriptionPane = $('<div class="media_description pane"></div>').appendTo(element);

				// add TK labels
      	var labels = node.current.properties['http://localcontexts.org/tk/hasLabel'];
      	if ('undefined' != typeof(window['tklabels']) && labels != null) {
          var popoverTemplate = '<div class="popover tk-help caption_font" role="tooltip"><div class="arrow"></div><div class="popover-content"></div></div>';
          var labelWrapper = $('<div class="tk-labels-media"></div>').appendTo(descriptionPane);
          var $label, $img, labelNode, url, labelDescription;
      	  $(labels).each(function() {
        		var $label = $('<span resource="'+this.value+'" typeof="tk:TKLabel" style="display:inline-block;"></span>').appendTo(labelWrapper);
        		var labelNode = scalarapi.model.nodesByURL[this.value];
        		var url = labelNode.properties['http://simile.mit.edu/2003/10/ontologies/artstor#url'][0].value;
        		var labelDescription = labelNode.properties['http://purl.org/dc/terms/description'][0].value;
        		var $img = $('<img tabindex="0" rel="art:url" src="'+url+'" data-toggle="popover" data-placement="top" />').appendTo($label);
            $img.popover({
              trigger: "manual focus",
              html: true,
              template: popoverTemplate,
              content: '<img src="'+url+'" /><p class="supertitle">Traditional Knowledge</p><h3 class="heading_weight">'+labelNode.title+'</h3><p>'+labelDescription+'</p><p><a href="http://localcontexts.org/tk-labels/" target="_blank">More about Traditional Knowledge labels</a></p>'
            });
						$(labels).find('img').click(function(e) {
							$(this).popover('toggle');
							e.stopPropagation();
						})
        	});
      	}

				if (node.current.source != null) {
					if (media.options.caption != 'metadata') {
						description += '<br>Source: ' + linkify(node.current.source);
					} else {
						descriptionPane.addClass('media_metadata');
					}
				}
				descriptionPane.append(description);
				descriptionPane.find('a.citations-link').on('click',  function() {
					media.options[ 'details' ].show( node );
				} );
				var descriptionTab = $('<input type="radio" class="media_tab" name="media_tab" id="descriptionTab" checked="checked"><label for="descriptionTab">Description</label>').appendTo(mediaTabs);
				descriptionTab.on('click', function() { media.showTab($(this), descriptionPane) });
				element.find('.media_description').show();
			}
			foundAuxContent = true;

			var i, annotation, row, prop, value;
			var annotations = node.getRelations('annotation', 'incoming', 'index');

			//filter out unwanted Annotations
			var annotationWhiteList = $(m.link).data('annotations');
			if($(m.link).is('[data-annotations]') || annotationWhiteList){
				if(!annotationWhiteList){
					annotationWhiteList = [];
				} else if (typeof annotationWhiteList === "string") {
					annotationWhiteList = annotationWhiteList.split(",");
				} else if (typeof annotationWhiteList === "number") {
          annotationWhiteList = [annotationWhiteList.toString()];
        }
				var temp_annotations = [];
				for(var i = 0; i < annotations.length; i++){
					if(annotationWhiteList.indexOf(annotations[i].body.slug)!=-1){
						temp_annotations.push(annotations[i]);
					}
				}
				annotations = temp_annotations;
			}

			if (annotations.length > 0) {
				var annotationTab = $('<input type="radio" class="media_tab" name="media_tab" id="annotationsTab"><label for="annotationsTab">Annotations</label>').appendTo(mediaTabs);
				annotationTab.on('click', function() { media.showTab($(this), annotationPane) });
				var annotationPane = $('<div class="media_annotations pane"></div>').appendTo(element);
				var table = $('<table></table>').appendTo(annotationPane);
				for (i in annotations) {
					annotation = annotations[i];
					row = $('<tr><td>'+annotation.startString+'</td><td><p>'+annotation.body.getDisplayTitle()+'</p></td></tr>').appendTo(table);
					row.data('relation', annotation);
					row.data('media',mediaelement);
					row.on('click', function( event ) {
						// only clicks on the background should cue up the annotation
						if ( $( event.target ).is( 'td,h4,div,p,tr' ) ) {
							var relation = $(this).data('relation');
							$(this).data('media').seek(relation);
							media.sendMessage($(this).data('media'), media.annotationHasMessage(relation));
							var me = this;
							if (( relation.target.current.mediaSource.contentType != 'document' ) && ( relation.target.current.mediaSource.contentType != 'image' ) && ( relation.target.current.mediaSource.contentType != '3D' ) && ( relation.target.current.mediaSource.contentType != '3D-GIS' )) {
								setTimeout(function() {
									if(!$(me).data('media').is_playing()) {
								$(me).data('media').play();
									}
								},250);
							}
						}

					});
				}
				if (!foundAuxContent) {
					element.find('.media_annotations').show();
					annotationTab.addClass('select');
					foundAuxContent = true;
				}
			}

			// hide metadata tab if the media's description tab includes the metadata
			if (media.options.caption != 'metadata') {
				var metadataTab = $('<input type="radio" class="media_tab" name="media_tab" id="metadataTab"><label foc for="metadataTab">Details</label>').appendTo(mediaTabs);
				var metadataPane = $('<div class="media_metadata pane"></div>').appendTo(element);
				metadataTab.on('click', function() { media.showTab($(this), metadataPane) });
				addMetadataTableForNodeToElement(node, metadataPane);
				if (!foundAuxContent) {
					element.find('.media_metadata').show();
					metadataTab.addClass('select');
					foundAuxContent = true;
				}
			}

			if ('undefined'==typeof(scalarMediaHideCitationsTab) || !scalarMediaHideCitationsTab) {
				var detailsTab = $( '<input type="radio" class="media_tab" name="media_tab" id="detailsTab"><label for="detailsTab">Citations</label>' ).appendTo( mediaTabs );
				detailsTab.on('click',  function() {
					media.options[ 'details' ].show( node, null, null, detailsTab );
				} );
			}

			if ('undefined'==typeof(scalarMediaHideSourceFileTab) || !scalarMediaHideSourceFileTab) {
				var sourceTab = $( '<input type="radio" class="media_tab" name="media_tab" id="sourceTab"><label for="sourceTab">Source file</label>' ).appendTo( mediaTabs );
				sourceTab.on('click',  function() {
					window.open( node.current.sourceFile, 'popout' );
				} );
			}

			if (media.options.shy) {
				var wrapped_slot = mediaTabs.parents('.slot').hasClass('wrapped_slot');
				mediaelement.model.element.on('mouseenter', function() {
					var timeout = $(this).data('timeout');
					if (timeout != null) {
						clearTimeout(timeout);
					}
					mediaTabs.slideDown();
				})
				mediaelement.model.element.on('mouseleave', function() {
					if ( window.innerWidth > 480 ) {
						var timeout = $(this).data('timeout');
						if (timeout != null) {
							clearTimeout(timeout);
						}
						var timeout = setTimeout(function() {
							mediaTabs.slideUp();
						}, 1000);
						$(this).data('timeout', timeout);
					}
				})
			} else {
				mediaTabs.show();
			}

			mediaelement.view.footer.find('.media_info').on('mouseenter', function(e) {
				var position = $(e.currentTarget).parent().parent().parent().offset();
				metadata.css({
					'right': (parseInt($(window).width()) - position.left + 10)+'px',
					'top': position.top+'px'
				});
				metadata.fadeIn();
			})

			$('body').on('show_annotation', media.showAnnotation);
			$('body').on('hide_annotation', media.hideAnnotation);

			media.addNextRelatedMedia();

			element.addClass('caption_font');
			element.addClass('mediainfo');
			$('.media_metadata').addClass('caption_font');

			$('body').trigger('scalarMediaReady', [mediaelement.view])
		}

	}

})(jQuery);
