﻿/// <reference path="jquery-1.2.6-vsdoc.js" />

(function($) {

	$.fn.annotateImage = function(options) {
		///	<summary>
		///		Creates annotations on the given image.
		///     Images are loaded from the "getUrl" propety passed into the options.
		///	</summary>
		var opts = $.extend({}, $.fn.annotateImage.defaults, options);
		var image = this;

		this.image = this;
		this.mode = 'view';

		// Assign defaults
		this.getUrl = opts.getUrl;
		this.saveUrl = opts.saveUrl;
		this.deleteUrl = opts.deleteUrl;
		this.editable = opts.editable;
		this.useAjax = opts.useAjax;
		this.notes = opts.notes;
		this.media_id = opts.media_id; // JK added
		this.album_id = opts.album_id; // JK added
		this.memberListUrl = opts.memberListUrl; // JK added
		this.addTagBtnId = opts.addTagBtnId; // JK added
		this.autoAdd = opts.autoAdd; // JK added
		this.inThisPhotoCssClass = opts.inThisPhotoCssClass; // JK added
		this.deletedNoteIds = opts.deletedNoteIds; // JK added

		// Add the canvas
		this.canvas = $('<div class="image-annotate-canvas"><div class="image-annotate-view"></div><div class="image-annotate-edit"><div class="image-annotate-edit-area"></div></div></div>');
		this.canvas.children('.image-annotate-edit').hide();
		this.canvas.children('.image-annotate-view').hide();
		this.image.after(this.canvas);

		// Give the canvas and the container their size and background
		this.canvas.height(this.height());
		this.canvas.width(this.width());
		this.canvas.css('background-image', 'url("' + this.attr('src') + '")');
		this.canvas.children('.image-annotate-view, .image-annotate-edit').height(this.height());
		this.canvas.children('.image-annotate-view, .image-annotate-edit').width(this.width());

		// Add the behavior: hide/show the notes when hovering the picture
		this.canvas.hover(function() {
			if ($(this).children('.image-annotate-edit').css('display') == 'none') {
				$(this).children('.image-annotate-view').show();
			}
		}, function() {
			$(this).children('.image-annotate-view').hide();
		});

		this.canvas.children('.image-annotate-view').hover(function() {
			$(this).show();
		}, function() {
			$(this).hide();
		});

		// JK - for now, always load via ajax
		// load the notes
		/*if (this.useAjax) {
			$.fn.annotateImage.ajaxLoad(this);
		} else {
			$.fn.annotateImage.load(this);
		}*/
		$.fn.annotateImage.ajaxLoad(this);

		// Add the "Add a note" button
		if (this.editable) {
			// <JK>
			/*this.button = $('<a class="image-annotate-add" id="image-annotate-add">Tag This Photo</a>');
			this.button.click(function() {
				$.fn.annotateImage.add(image);
			});
			this.canvas.after(this.button);*/
			
			if(this.autoAdd) {
				$.fn.annotateImage.setAddMode(image);
			}
			else {
				this.button = $('#' + this.addTagBtnId);
				this.button.click(function() {
					$.fn.annotateImage.setAddMode(image);
				});
			}
			// </JK>
		}
		
		 // Hide the original
		this.hide();

		return this;
	};

	/**
	* Plugin Defaults
	**/
	$.fn.annotateImage.defaults = {
		getUrl: '',
		saveUrl: '',
		deleteUrl: '',
		memberListUrl: '', // JK added
		media_id: 0, // JK added
		album_id: 0, // JK added
		addTagBtnId: '', // JK added
		autoAdd: false, // JK added
		inThisPhotoCssClass: '', // JK added
		editable: true,
		useAjax: true,
		notes: new Array(),
		deletedNoteIds: new Array() // JK added
	};

	$.fn.annotateImage.setAddMode = function(image) { // JK added function
		///	<summary>
		///		Put in Add Tag mode.
		///	</summary> 

		if(!image.autoAdd) {
			var tagMode = $('<div id="mode-indicator" style="padding:3px;display:none;width:100%;background-color:lightyellow;color:red;">Click on the photo to add a Tag</div>');
			var button = $('<a class="image-annotate-add" style="float: none">Done Tagging</a>');

			$('#' + image.addTagBtnId).unbind('click');
			
			tagMode.append(button);
			image.after(tagMode);
			tagMode.fadeIn('slow');

			button.click(function() {
				tagMode.remove();
				$('#' + image.addTagBtnId).click(function() {
					$.fn.annotateImage.setAddMode(image);
				});
				image.canvas.css('cursor', '');
				image.canvas.unbind('click');
				$('.image-annotate-edit-close').trigger('click');
			});
		}

		image.canvas.css('cursor', 'crosshair');
		image.canvas.click(function(e) {
			$(this).css('cursor', '');
			var left = e.pageX - this.offsetLeft;
			var top = e.pageY - this.offsetTop;
			$.fn.annotateImage.add(image, left, top); // JK added (left, top) to draw box where mouse clicks
		});
	};

	$.fn.annotateImage.clear = function(image) {
		///	<summary>
		///		Clears all existing annotations from the image.
		///	</summary>    
		for (var i = 0; i < image.notes.length; i++) {
			image.notes[image.notes[i]].destroy();
		}
		image.notes = new Array();
	};

	$.fn.annotateImage.ajaxLoad = function(image) {
		///	<summary>
		///		Loads the annotations from the "getUrl" property passed in on the
		///     options object.
		///	</summary>
		//$.getJSON(image.getUrl + '?ticks=' + $.fn.annotateImage.getTicks(), function(data) { // JK
		$.getJSON(image.getUrl + '&media_id=' + image.media_id + '&ticks=' + $.fn.annotateImage.getTicks(), function(data) { // JK - note "?session_id=xxx" is part of image.getUrl
			image.notes = data;
			$.fn.annotateImage.load(image);
		});
	};

	$.fn.annotateImage.load = function(image) {
		///	<summary>
		///		Loads the annotations from the notes property passed in on the
		///     options object.
		///	</summary>
		
		for (var i = 0; i < image.notes.length; i++) {
			// JK - de-normalize - stored as % in db - calc actual values
			image.notes[i].top = Math.round((image.notes[i].top * image.height()) / 100);
			image.notes[i].left = Math.round((image.notes[i].left * image.width()) / 100);
			image.notes[i].width = Math.round((image.notes[i].width * image.width()) / 100);
			image.notes[i].height = Math.round((image.notes[i].height * image.height()) / 100);

			image.notes[image.notes[i]] = new $.fn.annotateView(image, image.notes[i]);
		}

		$.fn.annotateImage.writeFacebookStrip(image); // JK - added
	};

	// JK - added function
	$.fn.annotateImage.writeFacebookStrip = function(image) {
		var buf = '';
		for (var i = 0; i < image.notes.length; i++) {
			if (i > 0) {
				buf += ', ';
			}
			buf += "<span class='highlight-tag'><a href='/photos/photos.asp?mid=" + image.notes[i].tagged_member_id + "'>" + image.notes[i].text + "</a> ";
			buf += "(<a href='/photos/photos.asp?mid=" + image.notes[i].tagged_member_id + "'>photos</a>";
			buf += (image.notes[i].editable) ? "<span style='display:inline'>" : "<span style='display:none'>";
			buf += " | <a class='remove-tag' style='cursor:pointer'>remove tag</a></span>";
			buf += ")</span>";
		}
		
		var $fbStripContainer;
		
		if (image.autoAdd) {
			$fbStripContainer = $(image).parent().parent().parent(); // TO DO - this is very specific and based on html structure - try to improve
		}
		else {
			$fbStripContainer = $(image).parent();
		}
		
		$fbStripContainer.find('.fb-strip').remove();
		
		if (image.notes.length) {
			$fbStripContainer.find('.' + image.inThisPhotoCssClass).html("<span class='fb-strip'>" + buf + "</span>");
		
			$('.highlight-tag', $fbStripContainer).hover(
				function(){
					if($('.image-annotate-edit', $(image.canvas)).css('display') == 'none')
					{
						var tags = $('.highlight-tag', $fbStripContainer);
						var lastNdx = tags.length - 1;
						var currentNdx = tags.index(this);

						$('.image-annotate-area', $(image.canvas)).hide();
						$('.image-annotate-note', $(image.canvas)).hide();
						$('.image-annotate-view', $(image.canvas)).show();
						$('.image-annotate-area', $(image.canvas)).eq(lastNdx-currentNdx).show();
						$('.image-annotate-note', $(image.canvas)).eq(currentNdx).show();
					}
				},
				function(){
						$('.image-annotate-note').hide();
						$('.image-annotate-view').hide();
						$('.image-annotate-area').show();
				}
			);

			$('.remove-tag', $fbStripContainer).click(
				function(){
					if($('.image-annotate-edit', $(image.canvas)).css('display') == 'none')
					{
						var tags = $('.remove-tag', $fbStripContainer);
						var lastNdx = tags.length - 1;
						var currentNdx = tags.index(this);

						$('.image-annotate-area', $(image.canvas)).eq(lastNdx-currentNdx).trigger('click');
						$('.image-annotate-edit-delete').trigger('click');

						$('.image-annotate-note').hide();
						$('.image-annotate-view').hide();
						$('.image-annotate-area').show();
					}
				}
			);
		}
	};
	
	$.fn.annotateImage.getTicks = function() {
		///	<summary>
		///		Gets a count og the ticks for the current date.
		///     This is used to ensure that URLs are always unique and not cached by the browser.
		///	</summary>        
		var now = new Date();
		return now.getTime();
	};

	$.fn.annotateImage.add = function(image, left, top) { // JK added left, top
		///	<summary>
		///		Adds a note to the image.
		///	</summary> 

		if (image.mode == 'view') {
			image.mode = 'edit';

			// Create/prepare the editable note elements
			var editable = new $.fn.annotateEdit(image, null, left, top); // JK added: null, left, top

			$.fn.annotateImage.createSaveButton(editable, image);
			$.fn.annotateImage.createCancelButton(editable, image);
		}
	};

	$.fn.annotateImage.createSaveButton = function(editable, image, note) {
		///	<summary>
		///		Creates a Save button on the editable note.
		///	</summary>
		var ok = $('<a class="image-annotate-edit-ok" style="display:none">OK</a>'); // JK - added style

		ok.click(function() {
//			var form = $('#image-annotate-edit-form form'); // JK
			var form = $('#save-form'); // JK
			var text = $('#image-annotate-text').val();
			var tagged_member_id = $('input[name="tagged_member_id"]', form).val(); // JK added

			$.fn.annotateImage.appendPosition(form, editable)
			image.mode = 'view';

			// Save via AJAX
			if (image.useAjax) {
				$.ajax({
					url: image.saveUrl,
					data: form.serialize(),
					error: function(e) { alert("An error occurred saving that note.") },
					// <JK - fix - bind new id from server to saved note>
					success: function(data) {
						if (data.annotation_id != undefined) {
							if (data.annotation_id > 0) {
								editable.note.id = data.annotation_id;
							}
							else {
								alert("This person is already tagged in the photo.")
								location.reload();
							}
						}
					},
					dataType: "json"
					// </JK - fix - bind new id from server to saved note>
				});
			}

			// Add to canvas
			if (note) {
				note.resetPosition(editable, text, tagged_member_id); // JK added tagged_member_id
			} else {
				editable.note.editable = true;
				note = new $.fn.annotateView(image, editable.note)
				note.resetPosition(editable, text, tagged_member_id); // JK added tagged_member_id
				image.notes.push(editable.note);
			}

			editable.destroy();
			
			$.fn.annotateImage.writeFacebookStrip(image); // JK - added
		});
		editable.form.append(ok);
	};

	$.fn.annotateImage.createCancelButton = function(editable, image) {
		///	<summary>
		///		Creates a Cancel button on the editable note.
		///	</summary>
		var cancel = $('<a class="image-annotate-edit-close">Cancel</a>');
		cancel.click(function() {
			editable.destroy();
			image.mode = 'view';
		});
//		editable.form.append(cancel); // JK
		$('.single-cell', editable.form).append(cancel);
	};

	$.fn.annotateEdit = function(image, note, left, top) { // JK added: left, top
		///	<summary>
		///		Defines an editable annotation area.
		///	</summary>

		$('.image-annotate-note').hide(); // JK ie6/7 fix

		$('.image-annotate-edit-close').trigger('click'); // JK - close any opened notes from other taggers on a page

		this.image = image;

		if (note) {
			this.note = note;
		} else {
			var newNote = new Object();
//			newNote.id = "new"; // JK - replaced with below 2 lines
			var d = new Date();
			newNote.id = "new_" + d.getTime();

			// <JK - edits>
//			newNote.width = 75;
//			newNote.height = 75;
			// default width and height (15%) - make it square
			var defaultWidth = Math.round((15 * image.width()) / 100);
			newNote.width = defaultWidth;
			newNote.height = defaultWidth;

			newNote.left = left-(newNote.width/2);
			newNote.top = top-(newNote.height/2);
			// </JK>

			newNote.text = "";
			this.note = newNote;
		}

		// Set area
		var area = image.canvas.children('.image-annotate-edit').children('.image-annotate-edit-area');
		this.area = area;
		this.area.css('height', this.note.height + 'px');
		this.area.css('width', this.note.width + 'px');
		this.area.css('left', this.note.left + 'px');
		this.area.css('top', this.note.top + 'px');

		// Show the edition canvas and hide the view canvas
		image.canvas.children('.image-annotate-view').hide();
		image.canvas.children('.image-annotate-edit').show();

		var form;
		
		//JK - added note logic - (edit (i.e. delete) vs. new)
		if(note) {
			this.area.css('cursor', 'default');
			form = $('<table id="image-annotate-edit-form" style="width:185px"><tr><td class="single-cell"><form></form></td></tr></table>');
		}
		else {
			this.area.css('cursor', 'move');

			// Add the note (which we'll load with the form afterwards)
			//var form = $('<div id="image-annotate-edit-form"><form><textarea id="image-annotate-text" name="text" rows="3" cols="30">' + this.note.text + '</textarea></form></div>');
			
			form = $('<table id="image-annotate-edit-form"><tr><td class="single-cell">'
							+ '<div id="loading-form-top"><img src="/images/loader.gif" /> Loading... </div>'
							+ '<div id="image-annotate-edit-form-top"></div>'
							+ '<form id="save-form">' // JK - added id
							+ '<input type="hidden" name="tagged_member_id"/>' // JK added input
							+ '<input style="display:none" id="image-annotate-text" name="text" value="' + this.note.text + '" autocomplete="off" size="20" />'
							+ '</form>'
						+ '</td></tr></table>');

			// Set the area as a draggable/resizable element contained in the image canvas.
			// Would be better to use the containment option for resizable but buggy
			/*area.resizable({ // JK: commented out resizable for now - buggy in IE
				handles: 'all',
				resize: function(e, ui) {
					if (parseInt(area.position().top) + parseInt(area.height()) + 2 > parseInt(image.canvas.height())) {
						area.height(parseInt(image.canvas.height()) - parseInt(area.position().top) - 2);
					}
					if (parseInt(area.position().left) + parseInt(area.width()) + 2 > parseInt(image.canvas.width())) {
						area.width(parseInt(image.canvas.width()) - parseInt(area.position().left) - 2);
					}
					if (parseInt(area.position().top) < 0) {
						area.height(parseInt(image.canvas.height())).css('top', 0);
					}
					if (parseInt(area.position().left) < 0) {
						area.width(parseInt(image.canvas.width())).css('left', 0);
					}
					form.css('left', area.offset().left + 'px');
					form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) + 'px');
				},
				stop: function(e, ui) {
					form.css('left', area.offset().left + 'px');
					form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) + 'px');
				}
			})*/
			area.draggable({
				containment: image.canvas,
				drag: function(e, ui) {
					form.css('left', area.offset().left + 'px');
					form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 7) + 'px'); // JK
				},
				stop: function(e, ui) {
					form.css('left', area.offset().left + 'px');
					form.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 7) + 'px'); // JK
				}
			});
		}

		this.form = form;

		$('body').append(this.form);
		this.form.css('left', this.area.offset().left + 'px');
		this.form.css('top', (parseInt(this.area.offset().top) + parseInt(this.area.height())+ 7) + 'px'); // JK

		$('#loading-form-top') // JK
			.hide()  // hide it initially
			.ajaxStart(function() {
				$(this).show();
			})
			.ajaxStop(function() {
				$(this).hide();
			})
		;

		if(!note) { // JK
			var url = image.memberListUrl + "&id=" + image.media_id
			$('#image-annotate-edit-form-top').load(url);
		}
			
		return this;
	};

	$.fn.annotateEdit.prototype.destroy = function() {
		///	<summary>
		///		Destroys an editable annotation area.
		///	</summary>        
		this.image.canvas.children('.image-annotate-edit').hide();
		this.area.resizable('destroy');
		this.area.draggable('destroy');
		this.area.css('height', '');
		this.area.css('width', '');
		this.area.css('left', '');
		this.area.css('top', '');
		this.form.remove();
		
		if($('#mode-indicator').length)
			this.image.canvas.css('cursor', 'crosshair'); // JK added

		if(this.image.autoAdd)
			this.image.canvas.css('cursor', 'crosshair'); // JK added
	}

	$.fn.annotateView = function(image, note) {
		///	<summary>
		///		Defines a annotation area.
		///	</summary>
		this.image = image;

		this.note = note;

		this.editable = (note.editable && image.editable);

		// Add the area
		this.area = $('<div class="image-annotate-area' + (this.editable ? ' image-annotate-area-editable' : '') + '"><div></div></div>');
		image.canvas.children('.image-annotate-view').prepend(this.area);

		// Add the note
		this.form = $('<div class="image-annotate-note">' + note.text + '</div>');
		this.form.hide();
		image.canvas.children('.image-annotate-view').append(this.form);
		this.form.children('span.actions').hide();

		// Set the position and size of the note
		this.setPosition();

		// Add the behavior: hide/display the note when hovering the area
		var annotation = this;
		this.area.hover(function() {
			annotation.show();
		}, function() {
			annotation.hide();
		});

		// Edit a note feature
		if (this.editable) {
			var form = this;
			this.area.click(function() {
				form.edit();
			});
		}
	};

	$.fn.annotateView.prototype.setPosition = function() {
		///	<summary>
		///		Sets the position of an annotation.
		///	</summary>
		this.area.children('div').height((parseInt(this.note.height) - 2) + 'px');
		this.area.children('div').width((parseInt(this.note.width) - 2) + 'px');
		this.area.css('left', (this.note.left) + 'px');
		this.area.css('top', (this.note.top) + 'px');
		this.form.css('left', (this.note.left) + 'px');
		this.form.css('top', (parseInt(this.note.top) + parseInt(this.note.height) + 7) + 'px');
	};

	$.fn.annotateView.prototype.show = function() {
		///	<summary>
		///		Highlights the annotation
		///	</summary>        

		//this.form.fadeIn(250); // JK
		this.form.show();

		if (!this.editable) {
			this.area.addClass('image-annotate-area-hover');
		} else {
			this.area.addClass('image-annotate-area-editable-hover');
		}
	};

	$.fn.annotateView.prototype.hide = function() {
		///	<summary>
		///		Removes the highlight from the annotation.
		///	</summary>      

		//this.form.fadeOut(250); // JK
		this.form.hide();
		
		this.area.removeClass('image-annotate-area-hover');
		this.area.removeClass('image-annotate-area-editable-hover');
	};

	$.fn.annotateView.prototype.destroy = function() {
		///	<summary>
		///		Destroys the annotation.
		///	</summary>      
		this.area.remove();
		this.form.remove();
	}

	$.fn.annotateView.prototype.edit = function() {
		///	<summary>
		///		Edits the annotation.
		///	</summary>      
		if (this.image.mode == 'view') {
			this.image.mode = 'edit';
			var annotation = this;

			// Create/prepare the editable note elements
			var editable = new $.fn.annotateEdit(this.image, this.note);

			//$.fn.annotateImage.createSaveButton(editable, this.image, annotation); // JK

			// Add the delete button
			var del = $('<a class="image-annotate-edit-delete">Delete</a>');
			del.click(function() {
				var form = $('#image-annotate-edit-form form');

				$.fn.annotateImage.appendPosition(form, editable)

				if (annotation.image.useAjax) {
					$.ajax({
					url: annotation.image.deleteUrl,
						data: form.serialize(),
						error: function(e) { alert("An error occurred deleting that note.") }
					});
				}

				if( editable.image.autoAdd && !editable.note.id.toString().match(/^new_/) ) // JK added - keep track of deleted notes for deferred save
					editable.image.deletedNoteIds.push(editable.note.id);

				// <JK added>
				var temp = new Array();
				var j = 0;
				for (var i = 0; i < editable.image.notes.length; i++)
					if(editable.note.id != editable.image.notes[i].id)
						temp[j++] = editable.image.notes[i];
				editable.image.notes = temp;
				$.fn.annotateImage.writeFacebookStrip(editable.image);
				// </JK added>

				annotation.image.mode = 'view';
				editable.destroy();
				annotation.destroy();
			});
			//editable.form.append(del); // JK
			$('.single-cell', editable.form).append(del);

			$.fn.annotateImage.createCancelButton(editable, this.image);
		}
	};

	$.fn.annotateImage.appendPosition = function(form, editable) {
		///	<summary>
		///		Appends the annotations coordinates to the given form that is posted to the server.
		///	</summary>

		// JK - normalize data (store in db as %)
		var t = Math.round((editable.area.position().top / editable.image.height()) * 100);
		var l = Math.round((editable.area.position().left / editable.image.width()) * 100);
		var h = Math.round((editable.area.height() / editable.image.height()) * 100);
		var w = Math.round((editable.area.width() / editable.image.width()) * 100);
		
		var areaFields = $('<input type="hidden" value="' + h + '" name="height"/>' +
						   '<input type="hidden" value="' + w + '" name="width"/>' +
						   '<input type="hidden" value="' + t + '" name="top"/>' +
						   '<input type="hidden" value="' + l + '" name="left"/>' +
						   '<input type="hidden" value="' + editable.note.id + '" name="id"/>' +
						   '<input type="hidden" value="' + editable.image.album_id + '" name="album_id"/>' + // JK added
						   '<input type="hidden" value="' + editable.image.media_id + '" name="media_id"/>'); // JK added

		form.append(areaFields);
	}

	$.fn.annotateView.prototype.resetPosition = function(editable, text, tagged_member_id) { // JK added tagged_member_id
		///	<summary>
		///		Sets the position of an annotation.
		///	</summary>

		this.form.html(text);

		// Resize
		this.area.children('div').height(editable.area.height() + 'px');
		this.area.children('div').width((editable.area.width() - 2) + 'px');
		this.area.css('left', (editable.area.position().left) + 'px');
		this.area.css('top', (editable.area.position().top) + 'px');
		this.form.css('left', (editable.area.position().left) + 'px');
		this.form.css('top', (parseInt(editable.area.position().top) + parseInt(editable.area.height()) + 7) + 'px');

		// Save new position to note
		this.note.top = editable.area.position().top;
		this.note.left = editable.area.position().left;
		this.note.height = editable.area.height();
		this.note.width = editable.area.width();
		this.note.text = text;
		this.note.id = editable.note.id;
		this.editable = true;
		this.note.tagged_member_id = tagged_member_id; // JK added tagged_member_id
	};

})(jQuery);
