/**
 * jquery.Jcrop.js (Beta)
 * jQuery Image Cropping Plugin
 * @author Kelly Hallman <khallman@wrack.org>
 * Copyright (c) 2008 Kelly Hallman - released under MIT License {{{
 *
 * 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.

 * }}}
 */
jQuery.Jcrop = function(obj,opt)
{
	// Extend the default options {{{

	var defaults = {
		// Basic Settings
		trackDocument:		false,
		baseClass:			'jcrop',
		addClass:			null,

		// Styling Options
		bgColor:			'black',

		bgOpacity:			.6,
		borderOpacity:		.4,
		handleOpacity:		.5,

		handlePad:			5,
		handleSize:			9,
		handleOffset:		5,
		edgeMargin:			14,

		aspectRatio:		0,
		keySupport:			true,
		cornerHandles:		true,
		sideHandles:		true,
		drawBorders:		true,
		dragEdges:			true,

		boundary:			8,
		animationDelay:		20,
		swingSpeed:			3,


		minSelect:			[ 0, 0 ],
		//maxSize:			[ 0, 0 ],
		//minSize:			[ 0, 0 ],

		// Callbacks / Event Handlers
		onChange: function() { },
		onSelect: function() { }

	};
	var options = defaults;
	setOptions(opt);

	// }}}
	// Initialize some jQuery objects {{{

	var 
		$img = jQuery(obj)
			.css({ position: 'absolute' })
		,

		boundx = $img.width(),
		boundy = $img.height(),

		$div = jQuery('<div />').width(boundx).height(boundy)
			.addClass(cssClass('holder'))
			.css({
				position: 'relative',
				//overflow: 'hidden',
				backgroundColor: options.bgColor
			})
	;

	if (options.addClass) $div.addClass(options.addClass);
	$img.wrap($div);

	/* }}} */

	var docOffset = getPos(obj), btndown, aspectLock, lc, dimmed, animating,
		lastsel = [0,0,0,0],
		shift_down;

	var Coords = function()/*{{{*/
	{
		var x1 = x2 = y1 = y2 = 0;

		this.setPressed = function(pos)/*{{{*/
		{
			pos = rebound(pos);
			x2 = x1 = pos[0];
			y2 = y1 = pos[1];
		};
		/*}}}*/
		this.setCurrent = function(pos)/*{{{*/
		{
			pos = rebound(pos);
			ox = pos[0] - x2;
			oy = pos[1] - y2;
			x2 = pos[0];
			y2 = pos[1];
		};
		/*}}}*/
		this.getOffset = function()/*{{{*/
		{
			return [ ox, oy ];
		};
		/*}}}*/
		this.moveOffset = function(offset)/*{{{*/
		{
			var ox = offset[0], oy = offset[1];
			if (0 > x1 + ox) ox -= ox + x1;
			if (0 > y1 + oy) oy -= oy + y1;
			//if (boundy > y2 + oy) oy -= -oy
			if (boundy < y2 + oy) oy += boundy - (y2 + oy);
			if (boundx < x2 + ox) ox += boundx - (x2 + ox);

			x1 += ox;
			x2 += ox;
			y1 += oy;
			y2 += oy;
		};
		/*}}}*/
		this.getCorner = function(ord)/*{{{*/
		{
			var c = getFixed();
			switch(ord)
			{
				case 'ne': return [ c.x2, c.y ];
				case 'nw': return [ c.x, c.y ];
				case 'se': return [ c.x2, c.y2 ];
				case 'sw': return [ c.x, c.y2 ];
			}
		};
		/*}}}*/
		this.getFixed = function()/*{{{*/
		{
			if (!options.aspectRatio && !aspectLock) return getRect();

			var aspect = options.aspectRatio ? options.aspectRatio : aspectLock,
				min = options.minSize,
				max = options.maxSize,
				rw = x2 - x1,
				rh = y2 - y1,
				rwa = Math.abs(rw),
				rha = Math.abs(rh),
				real_ratio = rwa / rha,
				xx, yy
			;
			
			if (real_ratio < aspect)
			{
				yy = y2;
				w = rha * aspect;
				xx = rw < 0 ? x1 - w : w + x1;

				if (xx < 0)
				{
					xx = 0;
					h = Math.abs((xx - x1) / aspect);
					yy = rh < 0 ? y1 - h: h + y1;
				}
				else if (xx > boundx)
				{
					xx = boundx;
					h = Math.abs((xx - x1) / aspect);
					yy = rh < 0 ? y1 - h : h + y1;
				}
			}
			else
			{
				xx = x2;
				h = rwa / aspect;
				yy = rh < 0 ? y1 - h : y1 + h;
				if (yy < 0)
				{
					yy = 0;
					w = Math.abs((yy - y1) * aspect);
					xx = rw < 0 ? x1 - w : w + x1;
				}
				else if (yy > boundy)
				{
					yy = boundy;
					w = Math.abs(yy - y1) * aspect;
					xx = rw < 0 ? x1 - w : w + x1;
				}
			}
			return last = makeObj(fixCoords(x1,y1,xx,yy));
		};
		/*}}}*/
		function rebound(p)/*{{{*/
		{
			if (p[0] < 0) p[0] = 0;
			if (p[1] < 0) p[1] = 0;
			if (p[0] > boundx) p[0] = boundx;
			if (p[1] > boundy) p[1] = boundy;
			return [p[0],p[1]];
		};
		/*}}}*/
		function fixCoords(x1,y1,x2,y2)/*{{{*/
		{
			var xa = x1, xb = x2, ya = y1, yb = y2;
			if (x2 < x1)
			{
				xa = x2;
				xb = x1;
			}
			if (y2 < y1)
			{
				ya = y2;
				yb = y1;
			}
			return [ Math.round(xa), Math.round(ya), Math.round(xb), Math.round(yb) ];
		};
		/*}}}*/
		function getRect()/*{{{*/
		{
			return makeObj(fixCoords(x1,y1,x2,y2));
		};
		/*}}}*/
		function makeObj(a)/*{{{*/
		{
			return { x: a[0], y: a[1], x2: a[2], y2: a[3],
				w: a[2] - a[0], h: a[3] - a[1] };
		};
		/*}}}*/

		this.fixCoords = fixCoords;

		return this;
	}();

	/*}}}*/
	var Selection = function()/*{{{*/
	{
		var start, end, dragmode, awake, hdep = 370;
		var $img2 = jQuery('<img />')/*{{{*/
				.attr('src',$img.attr('src'))
				.css('position','absolute')
		;/*}}}*/
		var $img_holder = jQuery('<div />')/*{{{*/
			.width(pct(100)).height(pct(100))
			.css({
				zIndex: 310,
				position: 'absolute',
				overflow: 'hidden'
			})
			.append($img2)
		;/*}}}*/
		var $hdl_holder = jQuery('<div />')/*{{{*/
			.width(pct(100)).height(pct(100))
			.css({
				zIndex: 320
				//position: 'absolute'
			})
		;/*}}}*/
		var $sel = jQuery('<div />')/*{{{*/
			.css({
				position: 'absolute',
				zIndex: 300
			})
			.insertBefore($img)
			.append($img_holder,$hdl_holder)
		;/*}}}*/
		var borders = { };

		if (options.drawBorders) {
			borders = {
					top: insertBorder('hline')
						.css('top',jQuery.browser.msie?px(-1):px(0)),
					bottom: insertBorder('hline'),
					left: insertBorder('vline'),
					right: insertBorder('vline')
			};
		}

		var handle = { };
		var seehandles = false;
		var hhs = options.handleOffset;
		/* Insert draggable elements {{{*/

		if (options.dragEdges) {
			handle.t = insertDragbar('n');
			handle.b = insertDragbar('s');
			handle.r = insertDragbar('e');
			handle.l = insertDragbar('w');
		}

		if (options.sideHandles)
			createHandles(['n','s','e','w']);

		if (options.cornerHandles)
			createHandles(['sw','nw','ne','se']);

		/*}}}*/
		// Private Methods
		function insertBorder(type)/*{{{*/
		{
			var jq = jQuery('<div />')
				.css({position: 'absolute', opacity: options.borderOpacity })
				.addClass(cssClass(type));
			$img_holder.append(jq);
			return jq;
		};
		/*}}}*/
		function dragDiv(ord,zi)/*{{{*/
		{
			var jq = jQuery('<div />')
				.mousedown(createDragger(ord))
				.css({
					cursor: ord+'-resize',
					position: 'absolute',
					zIndex: zi 
				})
			;
			$hdl_holder.append(jq);
			return jq;
		};
		/*}}}*/
		function insertHandle(ord)/*{{{*/
		{
			return dragDiv(ord,hdep++)
				.css({ top: px(-hhs+1), left: px(-hhs+1), opacity: options.handleOpacity })
				.addClass(cssClass('handle'));
		};
		/*}}}*/
		function insertDragbar(ord)/*{{{*/
		{
			var s = options.handleSize,
				o = hhs,
				h = s, w = s,
				t = o, l = o;

			switch(ord)
			{
				case 'n': case 's': w = pct(100); break;
				case 'e': case 'w': h = pct(100); break;
			}

			return dragDiv(ord,hdep++).width(w).height(h)
				.css({ top: px(-t+1), left: px(-l+1)});
		};
		/*}}}*/
		function createHandles(li)/*{{{*/
		{
			for(i in li) handle[li[i]] = insertHandle(li[i]);
		};
		/*}}}*/
		function moveHandles(c)/*{{{*/
		{
			var midvert  = Math.round((c.h / 2) - hhs),
				midhoriz = Math.round((c.w / 2) - hhs),
				north = west = -hhs+1,
				east = c.w - hhs,
				south = c.h - hhs,
				x, y;

			'e' in handle &&
				handle.e.css({ top: px(midvert), left: px(east) }) &&
				handle.w.css({ top: px(midvert) }) &&
				handle.s.css({ top: px(south), left: px(midhoriz) }) &&
				handle.n.css({ left: px(midhoriz) });

			'ne' in handle &&
				handle.ne.css({ left: px(east) }) &&
				handle.se.css({ top: px(south), left: px(east) }) &&
				handle.sw.css({ top: px(south) });

			'b' in handle &&
				handle.b.css({ top: px(south) }) &&
				handle.r.css({ left: px(east) });
		};
		/*}}}*/
		this.updateVisible = function ()/*{{{*/
		{ if (awake) return update(); };
		/*}}}*/
		this.update = function update()/*{{{*/
		{
			c = Coords.getFixed();

			resize(c.w,c.h);
			moveto(c.x,c.y);

			options.drawBorders &&
				borders['right'].css({ left: px(c.w-1) }) &&
					borders['bottom'].css({ top: px(c.h-1) });

			seehandles && moveHandles(c);
			awake || show();

			options.onChange(Coords.getFixed());
		};
		/*}}}*/
		function moveto(x,y)/*{{{*/
		{
			$img2.css({ top: px(-y), left: px(-x) });
			$sel.css({ top: px(y), left: px(x) });
		};
		/*}}}*/
		function resize(w,h)/*{{{*/
		{
			$sel.width(w).height(h);
		};
		/*}}}*/
		this.show = function show()/*{{{*/
		{
			$sel.show();
			$img.css('opacity',options.bgOpacity);
			awake = true;
		};
		/*}}}*/
		this.release = function release()/*{{{*/
		{
			disableHandles();
			$sel.hide();
			$img.css('opacity',1);
			awake = false;
		};
		/*}}}*/
		this.hide = function hide()/*{{{*/
		{
			release();
			$img.css('opacity',1);
			awake = false;
		};
		/*}}}*/
		function refresh()/*{{{*/
		{
			var p = Coords.getFixed();
			Coords.setPressed([p.x,p.y]);
			Coords.setCurrent([p.x2,p.y2]);
		};
		/*}}}*/
		this.enableHandles = function enableHandles()/*{{{*/
		{ 
			seehandles = true;
			moveHandles(Coords.getFixed());
			$hdl_holder.show();
		};
		/*}}}*/
		this.disableHandles = function disableHandles()/*{{{*/
		{
			seehandles = false;
			$hdl_holder.hide();
		};
		/*}}}*/
		this.animMode = function animMode(v)/*{{{*/
		{
			(animating = v) ? disableHandles(): enableHandles();
		};
		/*}}}*/
		this.getLastSel = function()/*{{{*/
		{
			return lastsel;
		};
		/*}}}*/
		this.done = function()/*{{{*/
		{
			var c = Coords.getFixed();
			lastsel = [ c.x, c.y, c.x2, c.y2 ];
			animMode(false);
			refresh();
		};
		/*}}}*/

		disableHandles();

		$img_holder.append
		(
			jQuery('<div />')
				.addClass(cssClass('tracker'))
				.mousedown(createDragger('move'))
				.css({ cursor: 'move', position: 'absolute', zIndex: 360, opacity: 0 })
		);

		return this;
	}();
	/*}}}*/
	var Tracker = function()/*{{{*/
	{
		var
			bound = options.boundary,
			$trk = jQuery('<div />')
				.addClass(cssClass('tracker'))
				.width(boundx+(bound*2)).height(boundy+(bound*2))
				.css({ position: 'absolute', top: px(-bound), left: px(-bound), zIndex: 290, opacity: 0 })
				.mousedown(newSelection),
			onMove		= function() { },
			onDone		= function() { },
			trackDoc	= options.trackDocument;

		if (!trackDoc)
		{
			$trk
				.mousemove(trackMove)
				.mouseup(trackUp)
				.mouseout(trackUp)
			;
		}

		function toFront()/*{{{*/
		{
			if (trackDoc)
			{
				jQuery(document)
					.mousemove(trackMove)
					.mouseup(trackUp)
				;
			}
			$trk.css({zIndex:450});
		}
		/*}}}*/
		function toBack()/*{{{*/
		{
			if (trackDoc)
			{
				jQuery(document)
					.unbind('mousemove',trackMove)
					.unbind('mouseup',trackUp)
				;
			}
			$trk.css({zIndex:290});
		}
		/*}}}*/
		function trackMove(e)/*{{{*/
		{
			onMove(mouseAbs(e));
		};
		/*}}}*/
		function trackUp(e)/*{{{*/
		{
			e.preventDefault();
			e.stopPropagation();

			if (btndown)
			{
				btndown = false;

				onDone(mouseAbs(e));
				options.onSelect(Coords.getFixed());
				toBack();
				onMove = function() { };
				onDone = function() { };
			}

			return false;
		};
		/*}}}*/
		this.activateHandlers = function(move,done)/* {{{ */
		{
			btndown = true;
			onMove = move;
			onDone = done;
			toFront();
			return false;
		};
		/* }}} */

		this.setCursor = function(t) { $trk.css('cursor',t); };

		$img.before($trk);
		return this;
	}();
	/*}}}*/
	var KeyManager = function()/*{{{*/
	{
		var $keymgr = jQuery('<input type="radio" />')
				.css({ position: 'absolute', left: '-30px' })
				.keydown(parseKey)
				.keyup(watchShift)
				.blur(onBlur),

			$keywrap = jQuery('<div />')
				.css({
					position: 'absolute',
					overflow: 'hidden'
				})
				.append($keymgr)
		;

		this.watchKeys = function()/*{{{*/
		{
			if (options.keySupport)
			{
				$keymgr.show();
				$keymgr.focus();
			}
		};
		/*}}}*/
		function onBlur(e)/*{{{*/
		{
			$keymgr.hide();
		};
		/*}}}*/
		function watchShift(e)/*{{{*/
		{
			var init_shift = shift_down, fc;
			shift_down = e.shiftKey ? true : false;

			if (init_shift != shift_down) {
				if (shift_down && btndown) {
					fc = Coords.getFixed();
					aspectLock = fc.w / fc.h;
				} else aspectLock = 0;
			}
			e.stopPropagation();
			e.preventDefault();
			return false;
		};
		/*}}}*/
		function doNudge(e,x,y)/*{{{*/
		{
			Coords.moveOffset([x,y]);
			Selection.updateVisible();
			e.preventDefault();
			e.stopPropagation();
		};
		/*}}}*/
		function parseKey(e)/*{{{*/
		{
			if (e.ctrlKey) return true;
			watchShift(e);
			var nudge = shift_down ? 10 : 1;
			switch(e.keyCode)
			{
				case 37: doNudge(e,-nudge,0); break;
				case 39: doNudge(e,nudge,0); break;
				case 38: doNudge(e,0,-nudge); break;
				case 40: doNudge(e,0,nudge); break;

				case 27: Selection.release(); break;

				case 9: return true;
			}

			return false;
		};
		/*}}}*/
		
		if (options.keySupport) $keywrap.insertBefore($img);
		return this;
	}();
	/*}}}*/

	// Internal helper methods {{{

	function px(n) { return '' + parseInt(n) + 'px'; };
	function pct(n) { return '' + parseInt(n) + '%'; };
	function cssClass(cl) { return options.baseClass + '-' + cl; };

	function getPos (obj)/*{{{*/
	{
		var x = obj.offsetLeft || 0;
		var y = obj.offsetTop || 0;

		while (obj = obj.offsetParent)
		{
			x += obj.offsetLeft;
			y += obj.offsetTop;
		}
    return [ Math.min(x), Math.min(y) ];
	};
	/*}}}*/
	function mouseAbs(e)/*{{{*/
	{
    // Carbon Five - changed to clientX, clientY to work within modals.
    return [ (e.clientX - docOffset[0]), (e.clientY - docOffset[1]) ];
	};
	/*}}}*/
	function myCursor(type)/*{{{*/
	{
		if (type != lc)
		{
			Tracker.setCursor(type);
			//Handles.xsetCursor(type);
			lc = type;
		}
	};
	/*}}}*/
	function startDragMode(mode,pos)/*{{{*/
	{
		docOffset = getPos(obj);
		Tracker.setCursor(mode=='move'?mode:mode+'-resize');

		if (mode == 'move')
			return Tracker.activateHandlers(createMover(pos), doneSelect);

		var fc = Selection.getFixed();
		Coords.setPressed(Coords.getCorner(oppLockCorner(mode)));
		Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);
	};
	/*}}}*/
	function newSelection(e)/*{{{*/
	{
		btndown = true;
		docOffset = getPos(obj);
		if (shift_down) aspectLock = 1;
		Selection.release();
		Selection.disableHandles();
		myCursor('crosshair');
		Coords.setPressed(mouseAbs(e));
		Tracker.activateHandlers(selectDrag,doneSelect);
		KeyManager.watchKeys();
		e.stopPropagation();
		e.preventDefault();
		return false;
	};
	/*}}}*/
	function selectDrag(pos)/*{{{*/
	{
		Coords.setCurrent(pos);
		Selection.update();

	};
	/*}}}*/
	function doneSelect(pos)/*{{{*/
	{
		c = Coords.getFixed();
		if (c.w > options.minSelect[0] && c.h > options.minSelect[1])
		{
			Selection.enableHandles();
			Selection.done();
		}
		else
		{
			Selection.release();
		}
		Tracker.setCursor('crosshair');
	};
	/*}}}*/
	function dragmodeHandler(mode,f)/*{{{*/
	{
		return function(pos) {
			if (!options.aspectRatio && !aspectLock) switch(mode)
			{
				case 'e': pos[1] = f.y2; break;
				case 'w': pos[1] = f.y2; break;
				case 'n': pos[0] = f.x2; break;
				case 's': pos[0] = f.x2; break;
			}
			else switch(mode)
			{
				case 'e': pos[1] = f.y+1; break;
				case 'w': pos[1] = f.y+1; break;
				case 'n': pos[0] = f.x+1; break;
				case 's': pos[0] = f.x+1; break;
			}
			Coords.setCurrent(pos);
			Selection.update();
		};
	};
	/*}}}*/
	function createMover(pos)/*{{{*/
	{
		var lloc = pos;
		KeyManager.watchKeys();

		return function(pos)
		{
			Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
			lloc = pos;
			
			Selection.update();
		};
	};
	/*}}}*/
	function oppLockCorner(ord)/*{{{*/
	{
		switch(ord)
		{
			case 'n': return 'sw';
			case 's': return 'nw';
			case 'e': return 'nw';
			case 'w': return 'ne';
			case 'ne': return 'sw';
			case 'nw': return 'se';
			case 'se': return 'nw';
			case 'sw': return 'ne';
		};
	};
	/*}}}*/
	function createDragger(ord)/*{{{*/
	{
		return function(e) {
			btndown = true;
			startDragMode(ord,mouseAbs(e));
			e.stopPropagation();
			e.preventDefault();
			return false;
		};
	};
	/*}}}*/

	// }}}
	// Public API {{{
	
	this.animateTo = animateTo;
	function animateTo(x1,y1,x2,y2)/*{{{*/
	{
		if (animating) return;
		var animto = Coords.fixCoords(x1,y1,x2,y2);
		var c = Coords.getFixed();
		var animat = initcr = [ c.x, c.y, c.x2, c.y2 ];
		var interv = options.animationDelay;
		//var ix1 = (animto[0] - initcr[0]) / steps;
		//var iy1 = (animto[1] - initcr[1]) / steps;
		//var ix2 = (animto[2] - initcr[2]) / steps;
		//var iy2 = (animto[3] - initcr[3]) / steps;

		var x = animat[0];
		var y = animat[1];
		var x2 = animat[2];
		var y2 = animat[3];
		var ix1 = animto[0] - initcr[0];
		var iy1 = animto[1] - initcr[1];
		var ix2 = animto[2] - initcr[2];
		var iy2 = animto[3] - initcr[3];
		var pcent = 0;
		var velocity = options.swingSpeed;

		Selection.animMode(true);

		var animator = function()
		{
			return function()
			{
				pcent += (100 - pcent) / velocity;

				animat[0] = x + ((pcent / 100) * ix1);
				animat[1] = y + ((pcent / 100) * iy1);
				animat[2] = x2 + ((pcent / 100) * ix2);
				animat[3] = y2 + ((pcent / 100) * iy2);

				if (pcent < 100) animateStart();
					else Selection.done();

				if (pcent >= 99.8) pcent = 100;

				setSelect(animat);
			};
		}();

		function animateStart()
			{ window.setTimeout(animator,interv); };

		animateStart();

	};
	/*}}}*/
	function setSelect(l) /*{{{*/
	{
		Coords.setPressed([l[0],l[1]]);
		Coords.setCurrent([l[2],l[3]]);
		Selection.update();
	};
	/*}}}*/
	function setOptions(opt)/*{{{*/
	{
		if (typeof(opt) != 'object') opt = { };
		options = jQuery.extend(options,opt);

		if (typeof(options.onChange)!=='function')
			options.onChange = function() { };

		if (typeof(options.onSelect)!=='function')
			options.onSelect = function() { };
	};
	/*}}}*/
	this.setSelect = setSelect;
	this.setOptions = function(opt)
	{
		setOptions(opt);
		if ('setSelect' in opt) { setSelect(opt.setSelect); Selection.done(); }
	};

	if (typeof(opt) != 'object') opt = { };
	if ('setSelect' in opt) { setSelect(opt.setSelect); Selection.done(); }
	// }}}

	Tracker.setCursor('crosshair');
	return this;
};

jQuery.fn.Jcrop = function(options)/*{{{*/
{
	function attachWhenDone(from)
	{
		//var loadsrc = from.src;
		//if ('useImg' in options) loadsrc = options.useImg;
		if (typeof(options) !== 'object') options = { };

		if (!('trackDocument' in options))
			options.trackDocument = (jQuery.browser.msie && parseInt(jQuery.browser.version) < 8) ? false : true;

		if (!('keySupport' in options))
			options.keySupport = jQuery.browser.msie ? false : true;

		var loadsrc = options.useImg || from.src;
		var img = new Image();
		img.onload = function() {
			jQuery(from).hide().after(img);
			from.Jcrop = jQuery.Jcrop(img,options);
		};
		img.src = loadsrc;

		return {
			setOptions: function (){ },
			animateTo: function (){ }
		};
	};
	this.each(function()
	{
		if ('Jcrop' in this)
		{
			if (options == 'api') return this.Jcrop;
			else this.Jcrop.setOptions(options);
		}
		//else this.Jcrop = jQuery.Jcrop(this,options);
		else this.Jcrop = attachWhenDone(this);
	});
	return this;
};
/*}}}*/

/**
 * CVS version information, do not construe as actual version info
 * $Id: jquery.Jcrop.js,v 1.17 2008/08/27 23:05:28 khallman Exp $
 */

