/*
 * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://CKFINDER.com/license
 *
 * The software, this file and its contents are subject to the CKFinder
 * License. Please read the license.txt file before using, installing, copying,
 * modifying or distribute this file or part of its contents. The contents of
 * this file is part of the Source Code of CKFinder.
 */

CKFinder.addPlugin( 'imageresize', {
	readOnly: false,
	connectorInitialized : function( api, xml ) {
		var node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@smallThumb' );
		if ( node )
			CKFinder.config.imageresize_thumbSmall = node.value;

		node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@mediumThumb' );
		if ( node )
			CKFinder.config.imageresize_thumbMedium = node.value;

		node = xml.selectSingleNode( 'Connector/PluginsInfo/imageresize/@largeThumb' );
		if ( node )
			CKFinder.config.imageresize_thumbLarge = node.value;
	},
	uiReady : function( api ) {
	var regexExt = /^(.*)\.([^\.]+)$/,
		regexFileName = /^(.*?)(?:_\d+x\d+)?\.([^\.]+)$/,
		regexGetSize = /^\s*(\d+)(px)?\s*$/i,
		regexGetSizeOrEmpty = /(^\s*(\d+)(px)?\s*$)|^$/i,
		imageDimension = { width : 0, height : 0 },
		file,
		doc;

	var updateFileName = function( dialog )
	{
		var width = dialog.getValueOf( 'tab1', 'width' ) || 0,
			height = dialog.getValueOf( 'tab1', 'height' ) || 0,
			e = dialog.getContentElement('tab1', 'createNewBox');

		if ( width && height )
		{
			var matches = file.name.match( regexFileName );
			dialog.setValueOf( 'tab1', 'fileName', matches[1] + "_" + width + "x" + height + "." + matches[2]);
			e.getElement().show();
		}
		else
			e.getElement().hide();
	};

	var onSizeChange = function()
	{
		var value = this.getValue(),	// This = input element.
			dialog = this.getDialog(),
			maxWidth = api.config.imagesMaxWidth,
			maxHeight = api.config.imagesMaxHeight,
			aMatch  =  value.match( regexGetSize ),
			width = imageDimension.width,
			height = imageDimension.height,
			newHeight,
			newWidth;

		if ( aMatch )
			value = aMatch[1];

		if ( !api.config.imageresize_allowEnlarging )
		{
			if ( width && width < maxWidth )
				maxWidth = width;

			if ( height && height < maxHeight )
				maxHeight = height;
		}

		if ( maxHeight > 0 && this.id == 'height' && value > maxHeight )
		{
			value = maxHeight;
			dialog.setValueOf( 'tab1', 'height', value );
		}

		if ( maxWidth > 0 && this.id == 'width' && value > maxWidth )
		{
			value = maxWidth;
			dialog.setValueOf( 'tab1', 'width', value );
		}

		// Only if ratio is locked
		if ( dialog.lockRatio && width && height )
		{
			if ( this.id == 'height' )
			{
				if ( value && value != '0' )
					value = Math.round( width * ( value  / height ) );

				if ( !isNaN( value ) )
				{
					// newWidth > maxWidth
					if ( maxWidth > 0 && value > maxWidth )
					{
						value = maxWidth;
						newHeight = Math.round( height * ( value  / width ) );
						dialog.setValueOf( 'tab1', 'height', newHeight );
					}

					dialog.setValueOf( 'tab1', 'width', value );
				}
			}
			else	//this.id = txtWidth.
			{
				if ( value && value != '0' )
					value = Math.round( height * ( value  / width ) );

				if ( !isNaN( value ) )
				{
					// newHeight > maxHeight
					if ( maxHeight > 0 && value > maxHeight )
					{
						value = maxHeight;
						newWidth = Math.round( width * ( value  / height ) );
						dialog.setValueOf( 'tab1', 'width', newWidth );
					}

					dialog.setValueOf( 'tab1', 'height', value );
				}
			}
		}

		updateFileName( dialog );
	};

	var resetSize = function( dialog )
	{
		if ( imageDimension.width && imageDimension.height )
		{
			dialog.setValueOf( 'tab1', 'width', imageDimension.width );
			dialog.setValueOf( 'tab1', 'height', imageDimension.height );
			updateFileName( dialog );
		}
	};

	var switchLockRatio = function( dialog, value )
	{
		var doc = dialog.getElement().getDocument(),
			ratioButton = doc.getById( 'btnLockSizes' );

		if ( imageDimension.width && imageDimension.height )
		{
			if ( value == 'check' )	// Check image ratio and original image ratio.
			{
				var width = dialog.getValueOf( 'tab1', 'width' ),
					height = dialog.getValueOf( 'tab1', 'height' ),
					originalRatio = imageDimension.width * 1000 / imageDimension.height,
					thisRatio = width * 1000 / height;
				dialog.lockRatio  = false;	// Default: unlock ratio

				if ( !width && !height )
					dialog.lockRatio = true; // If someone didn't start typing, lock ratio.
				else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) )
				{
					if ( Math.round( originalRatio ) == Math.round( thisRatio ) )
						dialog.lockRatio = true;
				}
			}
			else if ( value != undefined )
				dialog.lockRatio = value;
			else
				dialog.lockRatio = !dialog.lockRatio;
		}
		else if ( value != 'check' )	// I can't lock ratio if ratio is unknown.
			dialog.lockRatio = false;

		if ( dialog.lockRatio )
			ratioButton.removeClass( 'ckf_btn_unlocked' );
		else
			ratioButton.addClass( 'ckf_btn_unlocked' );

		return dialog.lockRatio;
	};

	CKFinder.dialog.add( 'resizeDialog', function( api )
	{
		return {
			title : api.lang.Imageresize.dialogTitle.replace( '%s', api.getSelectedFile().name ),
			// TODO resizable : CKFINDER.DIALOG_RESIZE_BOTH
			minWidth : 390,
			minHeight : 230,
			onShow : function() {
				var dialog = this,
					thumbSmall = CKFinder.config.imageresize_thumbSmall,
					thumbMedium = CKFinder.config.imageresize_thumbMedium,
					thumbLarge = CKFinder.config.imageresize_thumbLarge;

				doc = dialog.getElement().getDocument();
				file = api.getSelectedFile();

				this.setTitle( api.lang.Imageresize.dialogTitle.replace( '%s', file.name ) );

				var previewImg = doc.getById('previewImage');
				var sizeSpan = doc.getById('imageSize');

				previewImg.setAttribute('src', file.getThumbnailUrl( true ));

				var updateImgDimension = function( width, height ) {
					if ( !width || !height )
					{
						sizeSpan.setText( '' );
						return;
					}

					imageDimension.width = width;
					imageDimension.height = height;
					sizeSpan.setText( width + " x " + height + " px" );
					CKFinder.tools.setTimeout( function(){ switchLockRatio( dialog, 'check' ); }, 0, dialog );
				};

				api.connector.sendCommand( "ImageResizeInfo", {
						fileName : file.name
					},
					function( xml ) {
						if ( xml.checkError() )
							return;
						var width = xml.selectSingleNode( 'Connector/ImageInfo/@width' ),
							height = xml.selectSingleNode( 'Connector/ImageInfo/@height' ),
							result;

						if ( width && height )
						{
							width = parseInt( width.value, 10 );
							height = parseInt( height.value, 10 );
							updateImgDimension( width, height );

							var checkThumbs = function( id, size ) {
								if ( !size )
									return;

								var reThumb = /^(\d+)x(\d+)$/;
									result = reThumb.exec( size );

								var el = dialog.getContentElement( 'tab1', id );
								if ( 0 + result[1] > width && 0 + result[2] > height )
								{
									el.disable();
									el.getElement().setAttribute('title', api.lang.Imageresize.imageSmall).addClass('cke_disabled');
								}
								else
								{
									el.enable();
									el.getElement().setAttribute('title', '').removeClass('cke_disabled');
								}
							};

							checkThumbs('smallThumb', thumbSmall );
							checkThumbs('mediumThumb', thumbMedium );
							checkThumbs('largeThumb', thumbLarge );
						}
					},
					file.folder.type,
					file.folder
				);

				if ( !thumbSmall )
					dialog.getContentElement('tab1', 'smallThumb').getElement().hide();

				if ( !thumbMedium )
					dialog.getContentElement('tab1', 'mediumThumb').getElement().hide();

				if ( !thumbLarge )
					dialog.getContentElement('tab1', 'largeThumb').getElement().hide();

				if ( !thumbSmall && !thumbMedium && !thumbLarge )
					dialog.getContentElement('tab1', 'thumbsLabel').getElement().hide();

				dialog.setValueOf( 'tab1', 'fileName', file.name );
				dialog.getContentElement('tab1', 'width').focus();
				dialog.getContentElement('tab1', 'fileName').setValue('');
				dialog.getContentElement('tab1', 'createNewBox').getElement().hide();
				updateImgDimension( 0,0 );
			},
			onOk : function() {
				var dialog = this,
					width = dialog.getValueOf( 'tab1', 'width' ),
					height = dialog.getValueOf( 'tab1', 'height' ),
					small = dialog.getValueOf( 'tab1', 'smallThumb' ),
					medium = dialog.getValueOf( 'tab1', 'mediumThumb' ),
					large = dialog.getValueOf( 'tab1', 'largeThumb' ),
					fileName = dialog.getValueOf( 'tab1', 'fileName' ),
					createNew = dialog.getValueOf( 'tab1', 'createNew' );

				if ( width && !height )
				{
					api.openMsgDialog( '', api.lang.Imageresize.invalidHeight );
					return false;
				}
				else if ( !width && height )
				{
					api.openMsgDialog( '', api.lang.Imageresize.invalidWidth );
					return false;
				}
				if ( !api.config.imageresize_allowEnlarging && ( parseInt( width, 10 ) > imageDimension.width || parseInt( height, 10 ) > imageDimension.height ) )
				{
					var str = api.lang.Imageresize.sizeTooBig;
					api.openMsgDialog( '', str.replace( "%size", imageDimension.width + "x" + imageDimension.height ) );
					return false;
				}

				if ( ( width && height ) || small || medium || large )
				{
					if ( !createNew )
						fileName = file.name;

					api.connector.sendCommandPost( "ImageResize", null, {
							width : width,
							height : height,
							fileName : file.name,
							newFileName : fileName,
							overwrite : createNew ? 0 : 1,
							small : small ? 1 : 0,
							medium : medium ? 1 : 0,
							large : large ? 1 : 0
						},
						function( xml ) {
							if ( xml.checkError() )
								return;
							api.openMsgDialog( '', api.lang.Imageresize.resizeSuccess );
							api.refreshOpenedFolder();
						},
						file.folder.type,
						file.folder
					);
				}
				return undefined;
			},
			contents : [
				{
					id : 'tab1',
					label : '',
					title : '',
					expand : true,
					padding : 0,
					elements :
					[
						{
							type : 'hbox',
							widths : [ '180px', '280px' ],
							children:
							[
								{
									type : 'vbox',
									children:
									[
										{
											type : 'html',
											html : '' +
											'<style type="text/css">' +
											'a.ckf_btn_reset' +
											'{' +
												'float: right;' +
												'background-position: 0 -32px;' +
												'background-image: url("' + CKFinder.getPluginPath('imageresize') + 'images/mini.gif");' +
												'width: 16px;' +
												'height: 16px;' +
												'background-repeat: no-repeat;' +
												'border: 1px none;' +
												'font-size: 1px;' +
											'}' +

											'a.ckf_btn_locked,' +
											'a.ckf_btn_unlocked' +
											'{' +
												'float: left;' +
												'background-position: 0 0;' +
												'background-image: url("' + CKFinder.getPluginPath('imageresize') + 'images/mini.gif");' +
												'width: 16px;' +
												'height: 16px;' +
												'background-repeat: no-repeat;' +
												'border: none 1px;' +
												'font-size: 1px;' +
											'}' +

											'a.ckf_btn_unlocked' +
											'{' +
												'background-position: 0 -16px;' +
												'background-image: url("' + CKFinder.getPluginPath('imageresize') + '/images/mini.gif");' +
											'}' +

											'.ckf_btn_over' +
											'{' +
												'border: outset 1px;' +
												'cursor: pointer;' +
												'cursor: hand;' +
											'}' +
											'</style>' +

											'<div style="height:100px;padding:7px">' +
											'<img id="previewImage" src="" style="margin-bottom:4px;" /><br />' +
											'<span style="font-size:9px;" id="imageSize"></span>' +
											'</div>'
										},
										{
											type : 'html',
											id : 'thumbsLabel',
											html : '<strong>' + api.lang.Imageresize.thumbnailNew + '</strong>'
										},
										{
											type : 'checkbox',
											id : 'smallThumb',
											checked : false,
											label : api.lang.Imageresize.thumbnailSmall.replace( '%s', CKFinder.config.imageresize_thumbSmall )
										},
										{
											type : 'checkbox',
											id : 'mediumThumb',
											checked : false,
											label : api.lang.Imageresize.thumbnailMedium.replace( '%s', CKFinder.config.imageresize_thumbMedium )
										},
										{
											type : 'checkbox',
											id : 'largeThumb',
											checked : false,
											label : api.lang.Imageresize.thumbnailLarge.replace( '%s', CKFinder.config.imageresize_thumbLarge )
										}
									]
								},
								{
									type : 'vbox',
									children :
									[
										{
											type : 'html',
											html : '<strong>' + api.lang.Imageresize.newSize + '</strong>'
										},
										{
											type : 'hbox',
											widths : [ '80%', '20%' ],
											children:
											[
												{
													type : 'vbox',
													children:
													[
														{
															type : 'text',
															labelLayout : 'horizontal',
															label : api.lang.Imageresize.width,
															onKeyUp : onSizeChange,
															validate: function()
															{
																var value = this.getValue();
																if ( value )
																{
																	var aMatch  =  value.match( regexGetSize );
																	if ( !aMatch || parseInt( aMatch[1], 10 ) < 1 )
																	{
																		api.openMsgDialog( '', api.lang.Imageresize.invalidWidth );
																		return false;
																	}
																}
																return true;
															},
															id : 'width'
														},
														{
															type : 'text',
															labelLayout : 'horizontal',
															label : api.lang.Imageresize.height,
															onKeyUp : onSizeChange,
															validate: function()
															{
																var value = this.getValue();
																if ( value )
																{
																	var aMatch  =  value.match( regexGetSize );
																	if ( !aMatch || parseInt( aMatch[1], 10 ) < 1 )
																	{
																		api.openMsgDialog( '', api.lang.Imageresize.invalidHeight );
																		return false;
																	}
																}
																return true;
															},
															id : 'height'
														}
													]
												},
												{
													type : 'html',
													onLoad : function()
													{
														var doc = this.getElement().getDocument(),
															dialog = this.getDialog();
														// Activate Reset button
														var	resetButton = doc.getById( 'btnResetSize' ),
															ratioButton = doc.getById( 'btnLockSizes' );
														if ( resetButton )
														{
															resetButton.on( 'click', function(evt)
																{
																	resetSize( this );
																	evt.data.preventDefault();
																}, dialog );
															resetButton.on( 'mouseover', function()
																{
																	this.addClass( 'ckf_btn_over' );
																}, resetButton );
															resetButton.on( 'mouseout', function()
																{
																	this.removeClass( 'ckf_btn_over' );
																}, resetButton );
														}
														// Activate (Un)LockRatio button
														if ( ratioButton )
														{
															ratioButton.on( 'click', function(evt)
																{
																	var locked = switchLockRatio( this ),
																		width = this.getValueOf( 'tab1', 'width' );

																	if ( imageDimension.width && width )
																	{
																		var height = imageDimension.height / imageDimension.width * width;
																		if ( !isNaN( height ) )
																		{
																			this.setValueOf( 'tab1', 'height', Math.round( height ) );
																			updateFileName( dialog );
																		}
																	}
																	evt.data.preventDefault();
																}, dialog );
															ratioButton.on( 'mouseover', function()
																{
																	this.addClass( 'ckf_btn_over' );
																}, ratioButton );
															ratioButton.on( 'mouseout', function()
																{
																	this.removeClass( 'ckf_btn_over' );
																}, ratioButton );
														}
													},
													html : '<div style="margin-top:4px">'+
														'<a href="javascript:void(0)" tabindex="-1" title="' + api.lang.Imageresize.lockRatio + '" class="ckf_btn_locked ckf_btn_unlocked" id="btnLockSizes"></a>' +
														'<a href="javascript:void(0)" tabindex="-1" title="' + api.lang.Imageresize.resetSize + '" class="ckf_btn_reset" id="btnResetSize"></a>'+
														'</div>'
												}
											]
										},
										{
											type : 'vbox',
											id : 'createNewBox',
											hidden : true,
											children:
											[
												{
													type : 'checkbox',
													checked : true,
													id : 'createNew',
													label : api.lang.Imageresize.newImage,
													'default' : true,
													onChange : function() {
														var dialog = this.getDialog();
														var filenameInput = dialog.getContentElement('tab1', 'fileName');
														if ( filenameInput ) {
															if (!this.getValue())
																filenameInput.getElement().hide();
															else
																filenameInput.getElement().show();
														}
													}
												},
												{
													type : 'text',
													label : '',
													validate : function() {
														var dialog = this.getDialog(),
															createNew = dialog.getContentElement('tab1', 'createNew'),
															value = this.getValue(),
															matches = value.match( regexExt );

														if ( createNew && dialog.getValueOf( 'tab1', 'width' ) && dialog.getValueOf( 'tab1', 'height' ) )
														{
															if ( !value || !matches ) {
																api.openMsgDialog( '', api.lang.Imageresize.invalidName );
																return false;
															}
															if ( file.ext != matches[2] ) {
																api.openMsgDialog( '', api.lang.Imageresize.noExtensionChange );
																return false;
															}
														}
														return true;
													},
													id : 'fileName'
												}
											]
										}
									]
								}
							]
						}
					]
				}
			],
			// TODO http://dev.fckeditor.net/ticket/4750
			buttons : [ CKFinder.dialog.okButton, CKFinder.dialog.cancelButton ]
		};
	} );

	api.addFileContextMenuOption( { label : api.lang.Imageresize.contextMenuName, command : "resizeImage" } , function( api, file )
			{
				api.openDialog( 'resizeDialog' );
			},
			function ( file )
			{
				// Disable for files other than images.
				if ( !file.isImage() || !api.getSelectedFolder().type )
					return false;
				if ( file.folder.acl.fileDelete && file.folder.acl.fileUpload )
					return true;
				else
					return -1;
			});
	}
} );
