/************************************************/
/* IPB3 Javascript								*/
/* -------------------------------------------- */
/* ips.slideshow.js - Gallery image notes code	*/
/* (c) IPS, Inc 2009							*/
/* -------------------------------------------- */
/* Author: Rikki Tissier						*/
/************************************************/

var _notes = window.IPBoard;

_notes.prototype.imagenotes = Class.create({
	
	/* Image ID */
	id: 0,
	/* Notes already made */
	notes: null,
	/* Wrapper */
	imageWrap: null,
	/* Mouseover handlers */
	mouseOvers: {},
	/* Mouseover for image */
	mainMouseover: null,
	/* Are we dragging */
	dragging: false,
	/* Default sizing */
	defaultSize: { 'width': 50, 'height': 50 },
	/* Incrementor */
	i: 0,
	/* Resizer objects */
	resizers: {},
	/* Currently editing...*/
	currentEdit: null,
	
	/*------------------------------*/
	/* Constructor 					*/
	initialize: function( image, notes, options )
	{
		Debug.write("Initializing ips.imagenotes.js");
		if( !$( image ) ){ return; }
		
		this.id = $( image ).identify();
		this.notes = notes;
		this.options = Object.extend({
			editable: false,
			add_note: null
		}, options || {} );
		
		this.initImage();
	},
	
	/*------------------------------*/
	/* Initialize image				*/
	initImage: function()
	{
		if( !$( this.id ).complete )
		{
			this.initImage.bind( this ).delay( .2 );
			return;
		}
			
		var imageDims = $( this.id ).getDimensions();
		
		// Wrap the image
		this.imageWrap = new Element( 'div', { id: this.id + '_wrap' } );
		$( this.id ).wrap( this.imageWrap );
		this.imageWrap.setStyle( { width: imageDims['width'] + 'px', height: imageDims['height'] + 'px' } ).addClassName('image_view_wrap');
		
		// Build current notes
		this.buildNotes();
		
		// Set events on image
		$( this.imageWrap ).observe( 'mouseover', this.imageHover.bindAsEventListener( this ) );
		$( this.imageWrap ).observe( 'mouseout', this.imageHoverOff.bindAsEventListener( this ) );
		
		// Add droppables if we can edit
		if( this.options.editable ){
			Droppables.add( this.id + '_wrap', { accept: 'note_wrap', containment: $( this.imageWrap ), onDrop: function(){ return false; }.bind(this) } );
		}
		
		// Add note button
		if( this.options.add_note ){
			$( this.options.add_note ).observe('click', this.addNote.bindAsEventListener( this ));
		}
		
		// Set up body events
		Event.observe( document.body, 'click', this.bodyClick.bindAsEventListener( this ) );
	},
	
	/*------------------------------*/
	addNote: function( e )
	{
		Event.stop(e);
		
		if( this.currentEdit ){
			return;
		}
		
		this.i++;
		
		var wrapDims = $( this.imageWrap ).getDimensions();
		
		this.buildNote( this.id + '_new_' + this.i, { 	content: '',
		 												width: this.defaultSize['width'], height: this.defaultSize['height'],
														top: Math.ceil( wrapDims['height'] / 2 ), left: Math.ceil( wrapDims['width'] / 2 )
													});
													
		// Show notes even if not mousing over
		this.imageHover( e, function(){ 
			this.noteSelect( null, this.id + '_new_' + this.i );
			/*new Effect.Pulsate( $( 'note_' + this.id + '_new_' + this.i ), { pulses: 2, duration: 0.5, afterFinish: function(){
				this.noteSelect( null, this.id + '_new_' + this.i );
			}.bind(this) } )*/
		}.bind(this) );
				
	},
	
	/*------------------------------*/
	/* image mouseover				*/
	imageHover: function( e, afterFinish )
	{
		clearTimeout( this.mainMouseover );
		
		this.mainMouseover = setTimeout( function(){
			$( this.imageWrap ).select('.note_wrap').each( function(item){
				new Effect.Appear( $( item ), { duration: 0.2, afterFinish: afterFinish || null } );
			});
		}.bind(this), 300 );		
	},
	
	/*------------------------------*/
	/* image mouseoff				*/
	imageHoverOff: function( e )
	{
		clearTimeout( this.mainMouseover );
		
		this.mainMouseover = setTimeout( function(){
			$( this.imageWrap ).select('.note_wrap').each( function(item){
				if( $( item ).readAttribute('editing') != 'yes' ){
					new Effect.Fade( $( item ), { duration: 0.2 } );
				}
			});
		}.bind( this ), 1000 );
	},
	
	/*------------------------------*/
	/* Build existing notes			*/
	buildNotes: function()
	{
		
		this.notes.each( function( item ){
			this.buildNote( this.id + '_' + item.key, item.value );						
		}.bind(this) );
	},
	
	/*------------------------------*/
	/* Builds a note				*/
	buildNote: function( id, info )
	{
		/* Info should contain:
		 * { content, left, top, width, height }
		 */
		
		var note = noteTemplate.evaluate( { id: id, text: info['content'] } );
		$( this.id + '_wrap' ).insert( note );
		
		/* IE won't recognize mouseover unless there's some kind of fill inside,
		 * so we'll set a very transparent background on it */
		if( Prototype.Browser.IE ){
			$( 'note_fill_' + id ).setStyle('background: #fff; opacity: 0.01');
		} 
		
		// Set the size
		$('note_' + id ).setStyle( { left: info['left'] + 'px', top: info['top'] + 'px' } ).hide();
		$('note_box_' + id ).setStyle( { width: info['width'] + 'px', height: info['height'] + 'px' } );
		
		// Set event
		$( 'note_box_' + id ).observe('mouseover', this.noteHover.bindAsEventListener( this, id ));
		$( 'note_box_' + id ).observe('mouseout', this.noteHoverOff.bindAsEventListener( this, id ));
		
		if( this.options.editable ){
			$( 'note_' + id ).addClassName('editable');
			$( 'note_box_' + id ).observe('click', this.noteSelect.bindAsEventListener( this, id ) );
			
			// Add draggable
			new Draggable( $('note_' + id), { 
				revert: 'failure',
				onDrag: function(){
					$('note_' + id ).addClassName('selected');
					$('note_text_' + id ).hide();
					this.dragging = true;
				}.bind(this),
				onEnd: function(){
					this.updateCoords( id );					
				}.bind(this)
			});
			
			this.resizers[ id ] = new ipb.resizer( 
				$('note_box_' + id ),
				$('note_handle_' + id ),
			 	{
					onStart: function(drag){
						$('note_' + id ).addClassName('selected');
						$('note_text_' + id ).hide();
						this.dragging = true;
					}.bind(this),
					onFinish: function(drag){
						this.updateCoords( id );	
					}.bind(this)							
				 }
			);
		}	
		
		Debug.write( id );	
	},
	
	updateCoords: function( id )
	{
		var realID = id.replace( this.id + '_', '');
		
		if( !this.notes.get( realID ) ){ return; } // This is a new, unsaved note
		
		var containerPos = $('note_' + id).positionedOffset();
		var boxSize = $('note_box_' + id).getDimensions();
		var noteId = this.notes.get( realID )['noteId'];
		var content = this.notes.get( realID )['content'];

		new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax&section=image&do=edit-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
						{
							method: 'post',
							parameters: {
								'top': containerPos['top'],
								'left': containerPos['left'],
								'width': boxSize['width'],
								'height': boxSize['height'],
								'note': content,
								'noteId': noteId
							},
							onSuccess: function(t)
							{
								Debug.write( t.responseText );
								
								switch( t.responseText )
								{
									case 'ok':
										this.notes.get( realID )['top'] = containerPos['top'];
										this.notes.get( realID )['left'] = containerPos['left'];
										this.notes.get( realID )['width'] = boxSize['width'];
										this.notes.get( realID )['height'] = boxSize['height'];
										
										Debug.write("Width: " + boxSize['width']);
										Debug.write("height: " + boxSize['height']);
									break;
									case 'nopermission':
										alert( ipb.lang['note_no_permission_e'] );
									break;
									case 'missing_data':
										alert( ipb.lang['required_data_missing'] );
									break;
								}
							}.bind( this )
						});
		
		setTimeout( function(){
			if( $('note_' + id).readAttribute('editing') != 'yes' ){
				$('note_' + id ).removeClassName('selected');
			}
			this.dragging = false;
		}.bind(this), 200);
		
	},
	
	/*------------------------------*/
	/* Note select					*/
	noteSelect: function( e, id )
	{		
		if( this.dragging ){ return; }	
		
		$( 'note_' + id ).addClassName('selected');
		
		if( !this.currentEdit )
		{
			this.currentEdit = id;
			
			$( 'note_' + id ).writeAttribute('editing', 'yes');
			$( 'note_text_' + id).hide();

			var realID = id.replace( this.id + '_', '');
		
			if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
				var content = '';
			} else {
				var content = this.notes.get( realID )['content'];
			}
		
			var noteForm = editTemplate.evaluate({ id: id, content: content });
			$( 'note_' + id ).insert( noteForm );		
			$('note_content_' + id).activate();
			
			if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
				$('note_cancel_' + id).hide();
			} else {
				$('note_cancel_' + id).show();
			}
			
			// Events
			$( 'note_save_' + id ).observe( 'click', this.formSave.bindAsEventListener( this, id ) );
			$( 'note_cancel_' + id ).observe( 'click', this.formCancel.bindAsEventListener( this, id ) );
			$( 'note_delete_' + id ).observe( 'click', this.formDelete.bindAsEventListener( this, id ) );
		}
	},
	
	/*------------------------------*/
	/* Save note					*/
	formSave: function( e, id )
	{
		if( e ){ Event.stop(e); }
		
		if( $F('note_content_' + id).blank() ){
			alert( ipb.lang['note_save_empty'] );
			return;
		}
		
		var realID = id.replace( this.id + '_', '');
		var content = $F( 'note_content_' + id );
		var newNote = false;
		var containerPos = {};
		var boxSize = {};
		var type = '';
		var noteId = null;
		var done = false;
		
		// Is this a new note?
		if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
			containerPos = $('note_' + id).positionedOffset();
			boxSize = $('note_box_' + id).getDimensions();
			newNote = true;
			type = 'add';	
		} else {
			containerPos = { 'left': this.notes.get( realID )['left'], 'top': this.notes.get( realID )['top'] };
			boxSize = { 'width': this.notes.get( realID )['width'], 'height': this.notes.get( realID )['height'] };	
			type = 'edit';
			noteId = this.notes.get( realID )['noteId'];
		}
		
		new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax&section=image&do=" + type + "-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
						{
							method: 'post',
							parameters: {
								'top': containerPos['top'],
								'left': containerPos['left'],
								'width': boxSize['width'],
								'height': boxSize['height'],
								'note': content,
								'noteId': noteId
							},
							onSuccess: function(t)
							{
								Debug.write( t.responseText );
								
								/*** ADDING A NOTE ***/
								if( type == 'add' )
								{
									if( t.responseText.startsWith('ok') )
									{
										noteId = t.responseText.replace('ok|', '');
										this.notes.set( realID, {
											'width': boxSize['width'],
											'height': boxSize['height'],
											'top': containerPos['top'],
											'left': containerPos['left'],
											'content': content,
											'noteId': noteId
										} );
										done = true;
									}
									else
									{
										switch( t.responseText )
										{			
											case 'missing_data':
												alert( ipb.lang['required_data_missing'] );
											break;
											case 'nopermission':
												alert( ipb.lang['notes_no_permission_a'] );
											break;
											case 'max_notes_reached':
												alert( ipb.lang['max_notes_reached'] );
											break;
										}
									}
								}
								/*** EDITING A NOTE ***/
								else
								{
									switch( t.responseText )
									{
										case 'ok':
											this.notes.get( realID )['content'] = content;
											done = true;											
										break;
										case 'missing_data':
											alert( ipb.lang['required_data_missing'] );
										break;
										case 'nopermission':
											alert( ipb.lang['notes_no_permission_e'] );
										break;
									}
								}
								
								if( done ){
									$('note_text_' + id).update( content );

									this.finishEditing( id );

									$('note_text_' + id).show();
									this.noteHoverOff( null, id );
								}					
							}.bind(this)
						});						
		
	},
	
	/*------------------------------*/
	/* Cancel note					*/
	formCancel: function( e, id )
	{
		if( e ){ Event.stop(e); }
		this.finishEditing( id );		
	},
	
	/*------------------------------*/
	/* Delete note					*/
	formDelete: function( e, id )
	{
		if( e ){ Event.stop(e); }
		
		if( confirm( ipb.lang['note_confirm_delete'] ) )
		{
			var realID = id.replace( this.id + '_', '');
			
			if( this.notes.get( realID ) )
			{
				new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax&section=image&do=remove-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
								{
									method: 'post',
									parameters: {
										'noteId': this.notes.get( realID )['noteId']
									},
									onSuccess: function(t)
									{
										switch( t.responseText )
										{
											case 'ok':												
												new Effect.Fade( $('note_' + id), { duration: 0.2, afterFinish: function(){
														this.finishEditing( id );
														$('note_' + id).remove();
														this.notes.unset( realID );
													}.bind( this )
												});												
											break;
											case 'nopermission':
												alert( ipb.lang['note_no_permission_d'] );
											break;
											case 'missing_data':
												alert( ipb.lang['required_data_missing'] );
											break;
										}
									}
								});
			}
			else
			{
				new Effect.Fade( $('note_' + id), { duration: 0.2, afterFinish: function(){
						this.finishEditing( id );
						$('note_' + id).remove();
					}.bind( this )
				});
			}				
		}
	},
	
	/*------------------------------*/
	/* Completed editing			*/
	finishEditing: function( id )
	{
		// Remove form
		$( 'note_form_' + id ).remove();
		$( 'note_' + id ).writeAttribute('editing', 'no').removeClassName('selected');
		this.currentEdit = null;
	},
	
	/*------------------------------*/
	/* Note mouseover				*/
	noteHover: function(e, id)
	{				
		if( !this.dragging && $('note_' + id).readAttribute('editing') != 'yes' )
		{
			clearTimeout( this.mouseOvers[ id ] );
		
			this.mouseOvers[ id ] = setTimeout( function(){
				new Effect.Appear( $( 'note_text_' + id ), { duration: 0.2 } );
			}.bind( this ), 300 );
		}
	},
	
	/*------------------------------*/
	/* Note mouseoff				*/
	noteHoverOff: function(e, id)
	{		
		clearTimeout( this.mouseOvers[ id ] );
		
		if( $('note_text_' + id ).visible() )
		{
			this.mouseOvers[ id ] = setTimeout( function(){
				new Effect.Fade( $( 'note_text_' + id ), { duration: 0.2 } );
			}.bind( this ), 800 );
		}
	},
	
	/*------------------------------*/
	/* Handles document click		*/
	bodyClick: function( e )
	{
		// Get all notes inside the wrapper
		$( this.imageWrap ).select('.note_wrap').each( function( elem ){
			if( !Event.element(e).descendantOf( elem ) ){
				if( $( elem ).readAttribute('editing') != 'yes' ){
					$( elem ).removeClassName('selected');
				}
			}
		});		
	}
	
});

/************************************************/
/* Element resizing class						*/
/************************************************/
var _resize = window.IPBoard;
_resize.prototype.resizer = Class.create({
	
	container: null,
	handler: null,
	movePosition: {'x': 0, 'y': 0},
	func: null,
	
	/*--------------------------*/
	/* Constructor 				*/
	initialize: function( container, handle, options )
	{
		if( !$( container ) || !$( handle ) ){
			return false;
		}
		
		this.container = $( container );
		this.handle = $( handle );
		this.options = Object.extend( {
			onStart: null,
			onFinish: null
		}, options || {});
		
		new Draggable( $( this.handle ), { 
			onStart: this.setUpResize.bindAsEventListener( this ),
			change: this.mouseMoved.bindAsEventListener( this ),
			onEnd: this.endResize.bindAsEventListener( this )
		});
		
	},
	
	/*---------------------------*/
	/* onStart event, gets sizes */			
	setUpResize: function( draggable, e )
	{
		this.containerPos = $( this.container ).positionedOffset();	
		this.handleSize = $( this.handle ).getDimensions();

		$( this.container ).makePositioned();
		$( this.handle ).makePositioned();
		
		// Set cursor
		document.body.addClassName('resizing');
		
		if( Object.isFunction( this.options.onStart ) ){
			this.options.onStart( draggable );
		}
	},
	
	/*--------------------------*/
	/* Finish resizing			*/
	endResize: function( draggable, e )
	{
		document.body.removeClassName('resizing');
		
		if( Object.isFunction( this.options.onFinish ) ){
			this.options.onFinish( draggable );
		}
	},
	
	/*--------------------------*/
	/* 'change' event			*/
	mouseMoved: function( draggable, e )
	{
		// Get position
		var pos = $( this.handle ).positionedOffset();
	
		var newWidth = ( pos['left'] - this.containerPos['left'] ) + this.handleSize['width'];
		var newHeight = ( pos['top'] - this.containerPos['top'] ) + this.handleSize['height'];
		
		if( newWidth < 25 ){
			newWidth = 25;
			$( this.handle ).setStyle( { left: ( ( this.containerPos['left'] + 25 ) - this.handleSize['width'] ) + 'px' } );
		}
		
		if( newHeight < 25 ){
			newHeight = 25;
			$( this.handle ).setStyle( { top: ( ( this.containerPos['top'] + 25 ) - this.handleSize['height'] ) + 'px' } );
		}
				
		$( this.container ).setStyle( { width: newWidth + 'px', height: newHeight + 'px' } );		
	}
	
});