(function ($, undefined) {
	
	$.widget('pm.imageCropper', {
		options: {
			initialSelection: 'auto'
		},
		_getImageDimensions: function() {
			return {width:this.image.width(), height:this.image.height()};
		},
		_create: function() {
			console.log('_create', this.options);
			this.preview = this.options.preview;
			this.cropData = {};
			this.image = $('<img alt="Crop Image"/>').css('display', 'none');
			this.element.append(this.image);
			this.options.imageUrl && this._setImageUrl();
			this.options.preview && this._setPreview();
		},
		_setOption: function(key, value) {
			console.log('_setOption', key, value, this.options);
			if (key == 'imageUrl' && value != this.options.imageUrl) {
				this.options.imageUrl = value;
				this._setImageUrl();
			}
			if (key == 'preview' && value[0] != this.options.preview[0]) {
				this.options.preview = value;
				this._setPreview();
			}
		},
		destroy: function() {
			this._removeJcrop();
			this.image.detach();
			if (this.previewImage) this.previewImage.detach();
			$.Widget.prototype.destroy.call(this);
		},
		_setImageUrl: function() {
			this._removeJcrop();
			
			var self = this;
			
			var img = new Image();
			img.onload = function() {
				console.log('img.onload');
				self.imageDimensions = {width:this.width, height:this.height};
				self._imageLoadListener();
			};
			img.src = this.options.imageUrl;
			
		},
		_removeJcrop: function() {
			if (this.jcrop) {
				this.jcrop.destroy();
				delete this.jcrop;
				delete this.jcropData;
			}
		},
		_setPreview: function() {
			console.log('_setPreview');
			this.preview = this.options.preview;
			this.previewImage = $('<img alt="Preview"/>');
			this.preview.append(this.previewImage);
		},
		_imageLoadListener: function() {
			this.image.attr('src', this.options.imageUrl);
			this.image.attr('width', this.imageDimensions.width);
			this.image.attr('height', this.imageDimensions.height);
			this.image.css('display', 'inline');
			
			this.jcropOptions = {};
			if (this.options.aspectRatio) this.jcropOptions.aspectRatio = this.options.aspectRatio;
			
			if (this.preview) {
				this.previewImage.attr('src', this.options.imageUrl);
				this.previewImage.css('display', 'inline');
				
				var	imageWidth = this.imageDimensions.width,
					imageHeight = this.imageDimensions.height,
					previewWidth = this.preview.width(),
					previewHeight = this.preview.height();
				
				this.previewListener = $.proxy(function(coords) {
					if (!this.previewImage) return;
					
					var rx = previewWidth / coords.w,
					ry = previewHeight / coords.h;
					
					this.previewImage.css({
						width: Math.round(rx*imageWidth)+'px',
						height: Math.round(ry*imageHeight)+'px',
						marginLeft: '-' + Math.round(rx*coords.x) + 'px',
						marginTop: '-' + Math.round(ry*coords.y) + 'px'
					});
				}, this);
				
				this.jcropOptions.onChange = this.previewListener;
				this.jcropOptions.onSelect = this.previewListener;
				if (!this.jcropOptions.aspectRatio) this.jcropOptions.aspectRatio = previewWidth/previewHeight;
			}
			
			this.jcrop = $.Jcrop(this.image, this.jcropOptions);
			
			if (this.options.initialSelection) {
				var sel = this.options.initialSelection;
				if (sel == 'auto') {
					var iar = imageWidth/imageHeight, ar = this.jcropOptions.aspectRatio ? this.jcropOptions.aspectRatio : 1;
					
					var sw, sh;
					
					if (ar > iar) {
						sw = imageWidth;
						sh = Math.round(sw/ar);
					} else {
						sh = imageHeight;
						sw = Math.round(sh*ar);
					}
					
					var x1 = 0;//Math.round((imageWidth-sw)/2);
					var y1 = 0;//Math.round((imageHeight-sh)/2);
					var x2 = x1+sw;
					var y2 = y1+sh;
				} else {
					var x1 = sel.x1, y1 = sel.y1,
						x2 = sel.x2, y2 = sel.y2;
				}
				this.jcrop.setSelect([x1, y1, x2, y2]);
			}
		},
		getCropData: function() {
			var coords = this.jcrop.tellSelect();
			return coords;
		}
	});
	
})(jQuery);
