/**
 * Image Notes for jQuery
 * 
 * Copyright (c) 2008 Peter Szakszon
 * 
 * 
 * 
 * Based on 
 * 
 * 		Interface Elements for jQuery
 * 		http://interface.eyecon.ro
 * 
 * 		Copyright (c) 2006 Stefan Petre
 * 		Dual licensed under the MIT (MIT-LICENSE.txt) 
 * 		and GPL (GPL-LICENSE.txt) licenses.
 * 
 * 
 * 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */


(function($) {


	/**
	 * Plugin definition
	 */ 
	$.fn.imageNotes = function(options)
	{
		
		var container;
		var container_position = {left: 0, top: 0};
		var container_size = {width: 0, height: 0};
		var resizableArea;
		var newnoteform;
		var newnoteform_size = {width: 0, height: 0};
		
		var in_editing = false;			// is container in editing
		var wait_for_ajax = true;		// for first load
		
		var notes = [];

		var current_note_index = -1;
		
		var defs = {
			add: '',					// id of the add element
			show: '',
			editable: false,			// cotainer is editable or not
			text_limit_max_char: 100,
			text_limit_alert_message: 'A szöveg hossza maximum %c% karakter lehet',
			error_message_on_save: 'Sikertelen mentés',
			exist_message_on_save: 'Az adott koordinátán már van komment',
			error_message_on_delete: 'Sikertelen törlés',
			save_label: 'Mentés',
			cancel_label: 'Mégsem',
			delete_label: 'Törlés',
			resizableArea_border_width: 2,
			onload_notes: function(){},		// callback for load
			onsave_note: function(note){},		// callback for save
			ondelete_note: function(note_id){},		// callback for delete
			dont_worry_about_commas: 1
		};
	    
		
		// Extend default options with those provided,
		// first "session" defaults (defs) and then plugin defaults (defaults).
		// Note that the first arg to extend is an empty object -
		// this is to keep from overriding our "defaults" object.
		var opts = $.extend(defs, options);
		opts = $.extend({}, $.fn.imageNotes.defaults, opts);
		
		
	        
		
		// If image have padding (in pixels) calculate the valid 
		// coordinates of the area of dragging to prevent floppy notes

		var offset = $(this).offset();
		
		container_position.left = offset.left + parseInt($(this).css('padding-left'));
		container_position.top = offset.top + parseInt($(this).css('padding-top'));
		container_size.width = $(this).width();
		container_size.height = $(this).height();
		
		
		
		// Container
		var container = document.createElement('div');
		$(container).attr('id', '_in_container');
		$(container).css({
			position: 'absolute',
			left: container_position.left,
			top: container_position.top,
			width: container_size.width,
			height: container_size.height,
			dont_worry_about_commas: 1
		});

		$('body').append(container);
		
		
		
		
		var resizableArea = document.createElement('div');
		$(container).append($(resizableArea).attr('id','in_resizableArea'));

		
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerSE'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerE'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerNE'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerN'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerNW'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerW'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerSW'));
		$(resizableArea).append($(document.createElement('div')).addClass('resizer').attr('id','resizerS'));
		
		
		
		// new note form
		var newnoteform = document.createElement('div');
		$(newnoteform).attr('id', 'in_newnoteform');

		/*
		$(newnoteform).css({
			left: parseInt($(resizableArea).css('left')),
			top: parseInt($(resizableArea).css('top')) + parseInt($(resizableArea).css('height')) + 20,
			dont_worry_about_commas: 1
		});
		*/
		
		// textarea
		var textarea = document.createElement('textarea');
		$(textarea).attr('id', 'in_notetextarea');
		
		/*
		$(textarea).css({
			width: 220,
			height: 50,
			display: 'block'
		});
		*/
		
		
		$(newnoteform).append(textarea);
		
		
		// save button
		var save_button = document.createElement('input');
		$(save_button).attr({type: 'button', value: defs.save_label});
		$(newnoteform).append(save_button);

		// cancel button
		var cancel_button = document.createElement('input');
		$(cancel_button).attr({type: 'button', value: defs.cancel_label});
		$(newnoteform).append(cancel_button);
		
		// delete button
		var delete_button = document.createElement('input');
		$(delete_button).attr({type: 'button', value: defs.delete_label});
		$(newnoteform).append(delete_button);
		
		
		
		$(container).append(newnoteform);

		
		
		
		
		
		
		/**
		 * Attach events
		 */
		
		
		$(resizableArea).Resizable({
			minWidth: 20,
			minHeight: 20,
			minTop: 1,
			minLeft: 1,
			maxRight: container_size.width - (2 * defs.resizableArea_border_width) + 1,
			maxBottom: container_size.height - (2 * defs.resizableArea_border_width) + 1,
			dragHandle: true,

			handlers: {
				se:	'#resizerSE',
				e:	'#resizerE',
				ne:	'#resizerNE',
				n:	'#resizerN',
				nw:	'#resizerNW',
				w:	'#resizerW',
				sw:	'#resizerSW',
				s:	'#resizerS'
			},
			
			onDrag : function(x, y) {
				$(newnoteform).css({
					left: x,
					top: y + parseInt($(this).css('height')) + 20
				});
			},
			
			onResize : function(size, position) {
				$(newnoteform).css({
					left: position.left,
					top: position.top + size.height + 20
				});
			}

		});
		
		
		$('#' + defs.add).click(function(){
			
			if (!in_editing && defs.editable && !wait_for_ajax)
			{
				hide_notes();
				current_note_index = -1;
				show_new_note(10, 10, 100, 50, '');
			}
		});
		
		
		
		$('#' + defs.show).click(function(){			
			if (!wait_for_ajax)
			{
				show_notes();
				current_note_index = -1;
			}
		});
		
		
		
		
		$(save_button).click(function(){
			save_note();
		});
		
		$(cancel_button).click(function(){
			cancel_note();
		});
	
		$(delete_button).click(function(){
			delete_note();
		});
		
		
		
	
		$('#_in_container').hover(
			function(){
				show_notes();
			}, 
			function(){
				hide_notes();
			}
		);
		
		
		
		
		load_notes();

		
		/**
		 * Load/reload notes
		 */
		function load_notes()
		{
			// empty notes
			notes = [];
			
			// remove notes from container
			$('#' + $(container).attr('id') + ' .in_notefield').remove();
			$('#' + $(container).attr('id') + ' .in_notetext').remove();
			
			
			var tmp_notes = defs.onload_notes();
			
			
			$(tmp_notes).each(function(){
				if (this.note_id && this.text && this.left && this.top && this.width && this.height)
				{
					notes[notes.length] = {
						note_id: parseInt(this.note_id),
						text: this.text,
						left: parseInt(this.left),
						top: parseInt(this.top),
						width: parseInt(this.width),
						height: parseInt(this.height),
						editable: this.editable,
						link: this.link,
						author: this.author,
						size: this.width * this.height
					};
				}
			});
			
			
			// order notes by their size of resizableArea (desc)  
			notes = merge_sort(notes, comparison);

			//alert(notes.length);
			
			// build notes
			build_notes();

			// free ajax lock after load/reload
			wait_for_ajax = false;
			
			
			
		}
		
		
		/**
		 * Comparator for ordering notes by their size of resizableArea (desc)
		 * that big notes do not cover smaller notes
		 * 
		 */
		function comparison(left, right)
		{
			if(left.size == right.size)
				return 0;
			else if(left.size > right.size)
				return -1;
			else
				return 1;
		}
		
	
		/**
		 * Show new note form
		 */
		function show_new_note(left, top, width, height, text)
		{
			if (!in_editing && defs.editable && !wait_for_ajax)
			{
				in_editing = true;
				
				$(resizableArea).css({
					left: left,
					top: top,
					width: width,
					height: height,
					dont_worry_about_commas: 1
				});
				
				
				$(newnoteform).css({
					left: left,
					top: top + height + 20,
					dont_worry_about_commas: 1
				});

				
				$('#in_notetextarea').val(text);

				
				$('.resizer').show();
				$('#in_resizableArea').show(); 
				$('#in_newnoteform').show(); 
			}
		}
		
		/**
		 * Hide new note form
		 */
		function hide_new_note_form()
		{
			$('.resizer').hide();
			$('#in_resizableArea').hide(); 
			$('#in_newnoteform').hide(); 
		}

	
		
		
		function save_note()
		{
			
			var text = $.trim($('#in_notetextarea').val());
			
			if (text.length > 0) 
			{
				if (text.length < defs.text_limit_max_char)
				{
					wait_for_ajax = true;
					hide_new_note_form();
					
					$('#in_notetextarea').val('');

					// new note
					if (current_note_index == -1)	
					{
						var new_note = {
							note_id: -1,
							text: text,
							left: parseInt($(resizableArea).css('left')),
							top: parseInt($(resizableArea).css('top')),
							width: parseInt($(resizableArea).css('width')),
							height: parseInt($(resizableArea).css('height'))
						};
						
						
						var note_id = defs.onsave_note(new_note);
						
						note_id = parseInt(note_id);
						if (note_id != 0 && note_id > 0)
						{
							// reload notes
							load_notes();
							in_editing = false;
							show_notes();
							
						}
						else
						{
							if (note_id == -2) alert(defs.exist_message_on_save);
							else alert(defs.error_message_on_save);
							
							wait_for_ajax = false;
							in_editing = false;
						}
					}
					// edit note
					else	
					{
						var edit_note = {};
						edit_note.note_id = notes[current_note_index].note_id;
						edit_note.text = text;
						edit_note.left = parseInt($(resizableArea).css('left'));
						edit_note.top = parseInt($(resizableArea).css('top'));
						edit_note.width = parseInt($(resizableArea).css('width'));
						edit_note.height = parseInt($(resizableArea).css('height'));
						
						
						var note_id = defs.onsave_note(edit_note);
						
						note_id = parseInt(note_id);
						if (note_id != 0 && note_id > 0)
						{
							// reload notes
							load_notes();
							in_editing = false;
							show_notes();
							
						}
						else
						{
							if (note_id == -2) alert(defs.exist_message_on_save);
							else alert(defs.error_message_on_save);
							
							
							
							
							wait_for_ajax = false;
							in_editing = false;
						}
						
					}
					
					
				}
				else
				{
					alert(defs.text_limit_alert_message.replace(/%c%/, defs.text_limit_max_char));
				}
			}
			
		}
		
		
		function cancel_note()
		{
			wait_for_ajax = true;
			hide_new_note_form();
			
			
			wait_for_ajax = false;
			in_editing = false;
			show_notes();
		}
		
		
		function delete_note()
		{
			wait_for_ajax = true;
			hide_new_note_form();
			
			if (current_note_index > -1)
			{
				var result = defs.ondelete_note(notes[current_note_index].note_id);
				if (result) {
					load_notes();
					in_editing = false;
				}
			}
			else
			{
				wait_for_ajax = false;
				in_editing = false;
			}
			
			show_notes();
		}
		
		function build_notes()
		{
			$(notes).each(function(i, val){
				var notediv = document.createElement('div');
				var notetext = document.createElement('div');
				
				$(notediv).attr('class','in_notefield');
				$(notediv).attr('id','in_notefield_' + i);
				$(notediv).css({
					position: 'absolute',
					left: this.left,
					top: this.top,
					width: this.width,
					height: this.height,
					display: 'none',
					border: '1px solid #FFFFFF'
				});
				
				
				
				
				$(notetext).text(this.text + ' - ' + this.author);
				$(notetext).attr('id', 'in_notetext_' + i);
				$(notetext).attr('class','in_notetext');
				$(notetext).css({
					position: 'absolute',
					left: this.left,
					top: this.top + this.height + 5 ,
					display: 'none'
				});

				
				
				$(notediv).click(function(){
					var index = $(this).attr('id').replace(/in_notefield_/, '');
					
					if(index > -1)
					{
						var note = notes[index];
						
						if (!in_editing && defs.editable && !wait_for_ajax && note.editable)
						{
							hide_notes();
							current_note_index = index;
							show_new_note(note.left, note.top, note.width, note.height, note.text);
						}
						else
						{
							document.location.href = note.link;
						}
					}
				});
				
				
				
				
				$(notediv).hover(
					function(){
						$(this).css('border', '2px solid #FFFF00');
						var index = $(this).attr('id').replace(/in_notefield_/, '');
						$('#in_notetext_' + index).show();
					}, 
					function(){
						$(this).css('border', '1px solid #FFFFFF');
						var index = $(this).attr('id').replace(/in_notefield_/, '');
						$('#in_notetext_' + index).hide();
					}
				);
				
				
				
				//alert('add');
				$(container).append(notediv);
				$(container).append(notetext);
				
			});
			
		}
		
		function show_notes()
		{
			if (!in_editing && !wait_for_ajax)
			{
				$('#' + $(container).attr('id') + ' .in_notefield').show();
			}
		}
		
		
		function hide_notes()
		{
			if (!in_editing && !wait_for_ajax)
			{
				$('#' + $(container).attr('id') + ' .in_notefield').hide();
				$('#' + $(container).attr('id') + ' .in_notetext').hide();
				
			}
		}
		
		
	}


	/**
	 * Plugin defaults
	 */
	$.fn.imageNotes.defaults = {

	}
	
	
})(jQuery); 
	

