/**
 * jquery.Jcrop.js v0.9.8
 * jQuery Image Cropping Plugin
 * @author Kelly Hallman <khallman@gmail.com>
 * Copyright (c) 2008-2009 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.

 * }}}
 */

(function($) {

$.Jcrop = function(obj,opt)
{
	// Initialization {{{

	// Sanitize some options {{{
	var obj = obj, opt = opt;

	if (typeof(obj) !== 'object') obj = $(obj)[0];
	if (typeof(opt) !== 'object') opt = { };

	// Some on-the-fly fixes for MSIE...sigh
	if (!('trackDocument' in opt))
	{
		opt.trackDocument = $.browser.msie ? false : true;
		if ($.browser.msie && $.browser.version.split('.')[0] == '8')
			opt.trackDocument = true;
	}

	if (!('keySupport' in opt))
			opt.keySupport = $.browser.msie ? false : true;
		
	// }}}
	// 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,

		boxWidth:			0,
		boxHeight:			0,

		boundary:			8,
		animationDelay:		20,
		swingSpeed:			3,

		allowSelect:		true,
		allowMove:			true,
		allowResize:		true,

		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 $origimg = $(obj);
	var $img = $origimg.clone().removeAttr('id').css({ position: 'absolute' });

	$img.width($origimg.width());
	$img.height($origimg.height());
	$origimg.after($img).hide();

	presize($img,options.boxWidth,options.boxHeight);

	var boundx = $img.width(),
		boundy = $img.height(),

		$div = $('<div />')
			.width(boundx).height(boundy)
			.addClass(cssClass('holder'))
			.css({
				position: 'relative',
				backgroundColor: options.bgColor
			}).insertAfter($origimg).append($img);
	;
	
	if (options.addClass) $div.addClass(options.addClass);
	//$img.wrap($div);

	var $img2 = $('<img />')/*{{{*/
			.attr('src',$img.attr('src'))
			.css('position','absolute')
			.width(boundx).height(boundy)
	;/*}}}*/
	var $img_holder = $('<div />')/*{{{*/
		.width(pct(100)).height(pct(100))
		.css({
			zIndex: 310,
			position: 'absolute',
			overflow: 'hidden'
		})
		.append($img2)
	;/*}}}*/
	var $hdl_holder = $('<div />')/*{{{*/
		.width(pct(100)).height(pct(100))
		.css('zIndex',320);
	/*}}}*/
	var $sel = $('<div />')/*{{{*/
		.css({
			position: 'absolute',
			zIndex: 300
		})
		.insertBefore($img)
		.append($img_holder,$hdl_holder)
	;/*}}}*/

	var bound = options.boundary;
	var $trk = newTracker().width(boundx+(bound*2)).height(boundy+(bound*2))
		.css({ position: 'absolute', top: px(-bound), left: px(-bound), zIndex: 290 })
		.mousedown(newSelection);	
	
	/* }}} */
	// Set more variables {{{

	var xlimit, ylimit, xmin, ymin;
	var xscale, yscale, enabled = true;
	var docOffset = getPos($img),
		// Internal states
		btndown, lastcurs, dimmed, animating,
		shift_down;

	// }}}
		

		// }}}
	// Internal Modules {{{

	var Coords = function()/*{{{*/
	{
		var x1 = 0, y1 = 0, x2 = 0, y2 = 0, ox, oy;

		function setPressed(pos)/*{{{*/
		{
			var pos = rebound(pos);
			x2 = x1 = pos[0];
			y2 = y1 = pos[1];
		};
		/*}}}*/
		function setCurrent(pos)/*{{{*/
		{
			var pos = rebound(pos);
			ox = pos[0] - x2;
			oy = pos[1] - y2;
			x2 = pos[0];
			y2 = pos[1];
		};
		/*}}}*/
		function getOffset()/*{{{*/
		{
			return [ ox, oy ];
		};
		/*}}}*/
		function moveOffset(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 += boundy - (y2 + oy);
			if (boundx < x2 + ox) ox += boundx - (x2 + ox);

			x1 += ox;
			x2 += ox;
			y1 += oy;
			y2 += oy;
		};
		/*}}}*/
		function getCorner(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 ];
			}
		};
		/*}}}*/
		function getFixed()/*{{{*/
		{
			if (!options.aspectRatio) return getRect();
			// This function could use some optimization I think...
			var aspect = options.aspectRatio,
				min_x = options.minSize[0]/xscale, 
				min_y = options.minSize[1]/yscale,
				max_x = options.maxSize[0]/xscale, 
				max_y = options.maxSize[1]/yscale,
				rw = x2 - x1,
				rh = y2 - y1,
				rwa = Math.abs(rw),
				rha = Math.abs(rh),
				real_ratio = rwa / rha,
				xx, yy
			;
			if (max_x == 0) { max_x = boundx * 10 }
			if (max_y == 0) { max_y = boundy * 10 }
			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;
				}
			}

			// Magic %-)
			if(xx > x1) { // right side
			  if(xx - x1 < min_x) {
				xx = x1 + min_x;
			  } else if (xx - x1 > max_x) {
				xx = x1 + max_x;
			  }
			  if(yy > y1) {
				yy = y1 + (xx - x1)/aspect;
			  } else {
				yy = y1 - (xx - x1)/aspect;
			  }
			} else if (xx < x1) { // left side
			  if(x1 - xx < min_x) {
				xx = x1 - min_x
			  } else if (x1 - xx > max_x) {
				xx = x1 - max_x;
			  }
			  if(yy > y1) {
				yy = y1 + (x1 - xx)/aspect;
			  } else {
				yy = y1 - (x1 - xx)/aspect;
			  }
			}

			if(xx < 0) {
				x1 -= xx;
				xx = 0;
			} else  if (xx > boundx) {
				x1 -= xx - boundx;
				xx = boundx;
			}

			if(yy < 0) {
				y1 -= yy;
				yy = 0;
			} else  if (yy > boundy) {
				y1 -= yy - boundy;
				yy = boundy;
			}

			return last = makeObj(flipCoords(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 flipCoords(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()/*{{{*/
		{
			var xsize = x2 - x1;
			var ysize = y2 - y1;

			if (xlimit && (Math.abs(xsize) > xlimit))
				x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
			if (ylimit && (Math.abs(ysize) > ylimit))
				y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);

			if (ymin && (Math.abs(ysize) < ymin))
				y2 = (ysize > 0) ? (y1 + ymin) : (y1 - ymin);
			if (xmin && (Math.abs(xsize) < xmin))
				x2 = (xsize > 0) ? (x1 + xmin) : (x1 - xmin);

			if (x1 < 0) { x2 -= x1; x1 -= x1; }
			if (y1 < 0) { y2 -= y1; y1 -= y1; }
			if (x2 < 0) { x1 -= x2; x2 -= x2; }
			if (y2 < 0) { y1 -= y2; y2 -= y2; }
			if (x2 > boundx) { var delta = x2 - boundx; x1 -= delta; x2 -= delta; }
			if (y2 > boundy) { var delta = y2 - boundy; y1 -= delta; y2 -= delta; }
			if (x1 > boundx) { var delta = x1 - boundy; y2 -= delta; y1 -= delta; }
			if (y1 > boundy) { var delta = y1 - boundy; y2 -= delta; y1 -= delta; }

			return makeObj(flipCoords(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] };
		};
		/*}}}*/

		return {
			flipCoords: flipCoords,
			setPressed: setPressed,
			setCurrent: setCurrent,
			getOffset: getOffset,
			moveOffset: moveOffset,
			getCorner: getCorner,
			getFixed: getFixed
		};
	}();

	/*}}}*/
	var Selection = function()/*{{{*/
	{
		var start, end, dragmode, awake, hdep = 370;
		var borders = { };
		var handle = { };
		var seehandles = false;
		var hhs = options.handleOffset;

		/* Insert draggable elements {{{*/

		// Insert border divs for outline
		if (options.drawBorders) {
			borders = {
					top: insertBorder('hline')
						.css('top',$.browser.msie?px(-1):px(0)),
					bottom: insertBorder('hline'),
					left: insertBorder('vline'),
					right: insertBorder('vline')
			};
		}

		// Insert handles on edges
		if (options.dragEdges) {
			handle.t = insertDragbar('n');
			handle.b = insertDragbar('s');
			handle.r = insertDragbar('e');
			handle.l = insertDragbar('w');
		}

		// Insert side handles
		options.sideHandles &&
			createHandles(['n','s','e','w']);

		// Insert corner handles
		options.cornerHandles &&
			createHandles(['sw','nw','ne','se']);

		/*}}}*/
		// Private Methods
		function insertBorder(type)/*{{{*/
		{
			var jq = $('<div />')
				.css({position: 'absolute', opacity: options.borderOpacity })
				.addClass(cssClass(type));
			$img_holder.append(jq);
			return jq;
		};
		/*}}}*/
		function dragDiv(ord,zi)/*{{{*/
		{
			var jq = $('<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) });
		};
		/*}}}*/
		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);
		};
		/*}}}*/
		function refresh()/*{{{*/
		{
			var c = Coords.getFixed();

			Coords.setPressed([c.x,c.y]);
			Coords.setCurrent([c.x2,c.y2]);

			updateVisible();
		};
		/*}}}*/

		// Internal Methods
		function updateVisible()/*{{{*/
			{ if (awake) return update(); };
		/*}}}*/
		function update()/*{{{*/
		{
			var 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(unscale(c));
		};
		/*}}}*/
		function show()/*{{{*/
		{
			$sel.show();
			$img.css('opacity',options.bgOpacity);
			awake = true;
		};
		/*}}}*/
		function release()/*{{{*/
		{
			disableHandles();
			$sel.hide();
			$img.css('opacity',1);
			awake = false;
		};
		/*}}}*/
		function showHandles()//{{{
		{
			if (seehandles)
			{
				moveHandles(Coords.getFixed());
				$hdl_holder.show();
			}
		};
		//}}}
		function enableHandles()/*{{{*/
		{ 
			seehandles = true;
			if (options.allowResize)
			{
				moveHandles(Coords.getFixed());
				$hdl_holder.show();
				return true;
			}
		};
		/*}}}*/
		function disableHandles()/*{{{*/
		{
			seehandles = false;
			$hdl_holder.hide();
		};
		/*}}}*/
		function animMode(v)/*{{{*/
		{
			(animating = v) ? disableHandles(): enableHandles();
		};
		/*}}}*/
		function done()/*{{{*/
		{
			animMode(false);
			refresh();
		};
		/*}}}*/

		var $track = newTracker().mousedown(createDragger('move'))
				.css({ cursor: 'move', position: 'absolute', zIndex: 360 })

		$img_holder.append($track);
		disableHandles();

		return {
			updateVisible: updateVisible,
			update: update,
			release: release,
			refresh: refresh,
			setCursor: function (cursor) { $track.css('cursor',cursor); },
			enableHandles: enableHandles,
			enableOnly: function() { seehandles = true; },
			showHandles: showHandles,
			disableHandles: disableHandles,
			animMode: animMode,
			done: done
		};
	}();
	/*}}}*/
	var Tracker = function()/*{{{*/
	{
		var onMove		= function() { },
			onDone		= function() { },
			trackDoc	= options.trackDocument;

		if (!trackDoc)
		{
			$trk
				.mousemove(trackMove)
				.mouseup(trackUp)
				.mouseout(trackUp)
			;
		}

		function toFront()/*{{{*/
		{
			$trk.css({zIndex:450});
			if (trackDoc)
			{
				$(document)
					.mousemove(trackMove)
					.mouseup(trackUp)
				;
			}
		}
		/*}}}*/
		function toBack()/*{{{*/
		{
			$trk.css({zIndex:290});
			if (trackDoc)
			{
				$(document)
					.unbind('mousemove',trackMove)
					.unbind('mouseup',trackUp)
				;
			}
		}
		/*}}}*/
		function trackMove(e)/*{{{*/
		{
			onMove(mouseAbs(e));
		};
		/*}}}*/
		function trackUp(e)/*{{{*/
		{
			e.preventDefault();
			e.stopPropagation();

			if (btndown)
			{
				btndown = false;

				onDone(mouseAbs(e));
				options.onSelect(unscale(Coords.getFixed()));
				toBack();
				onMove = function() { };
				onDone = function() { };
			}

			return false;
		};
		/*}}}*/

		function activateHandlers(move,done)/* {{{ */
		{
			btndown = true;
			onMove = move;
			onDone = done;
			toFront();
			return false;
		};
		/* }}} */

		function setCursor(t) { $trk.css('cursor',t); };

		$img.before($trk);
		return {
			activateHandlers: activateHandlers,
			setCursor: setCursor
		};
	}();
	/*}}}*/
	var KeyManager = function()/*{{{*/
	{
		var $keymgr = $('<input type="radio" />')
				.css({ position: 'absolute', left: '-30px' })
				.keypress(parseKey)
				.blur(onBlur),

			$keywrap = $('<div />')
				.css({
					position: 'absolute',
					overflow: 'hidden'
				})
				.append($keymgr)
		;

		function watchKeys()/*{{{*/
		{
			if (options.keySupport)
			{
				$keymgr.show();
				$keymgr.focus();
			}
		};
		/*}}}*/
		function onBlur(e)/*{{{*/
		{
			$keymgr.hide();
		};
		/*}}}*/
		function doNudge(e,x,y)/*{{{*/
		{
			if (options.allowMove) {
				Coords.moveOffset([x,y]);
				Selection.updateVisible();
			};
			e.preventDefault();
			e.stopPropagation();
		};
		/*}}}*/
		function parseKey(e)/*{{{*/
		{
			if (e.ctrlKey) return true;
			shift_down = e.shiftKey ? true : false;
			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 nothing(e);
		};
		/*}}}*/
		
		if (options.keySupport) $keywrap.insertBefore($img);
		return {
			watchKeys: watchKeys
		};
	}();
	/*}}}*/

	// }}}
	// Internal Methods {{{

	function px(n) { return '' + parseInt(n) + 'px'; };
	function pct(n) { return '' + parseInt(n) + '%'; };
	function cssClass(cl) { return options.baseClass + '-' + cl; };
	function getPos(obj)/*{{{*/
	{
		// Updated in v0.9.4 to use built-in dimensions plugin
		var pos = $(obj).offset();
		return [ pos.left, pos.top ];
	};
	/*}}}*/
	function mouseAbs(e)/*{{{*/
	{
		return [ (e.pageX - docOffset[0]), (e.pageY - docOffset[1]) ];
	};
	/*}}}*/
	function myCursor(type)/*{{{*/
	{
		if (type != lastcurs)
		{
			Tracker.setCursor(type);
			//Handles.xsetCursor(type);
			lastcurs = type;
		}
	};
	/*}}}*/
	function startDragMode(mode,pos)/*{{{*/
	{
		docOffset = getPos($img);
		Tracker.setCursor(mode=='move'?mode:mode+'-resize');

		if (mode == 'move')
			return Tracker.activateHandlers(createMover(pos), doneSelect);

		var fc = Coords.getFixed();
		var opp = oppLockCorner(mode);
		var opc = Coords.getCorner(oppLockCorner(opp));

		Coords.setPressed(Coords.getCorner(opp));
		Coords.setCurrent(opc);

		Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);
	};
	/*}}}*/
	function dragmodeHandler(mode,f)/*{{{*/
	{
		return function(pos) {
			if (!options.aspectRatio) 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) {
			if (options.disabled) return false;
			if ((ord == 'move') && !options.allowMove) return false;
			btndown = true;
			startDragMode(ord,mouseAbs(e));
			e.stopPropagation();
			e.preventDefault();
			return false;
		};
	};
	/*}}}*/
	function presize($obj,w,h)/*{{{*/
	{
		var nw = $obj.width(), nh = $obj.height();
		if ((nw > w) && w > 0)
		{
			nw = w;
			nh = (w/$obj.width()) * $obj.height();
		}
		if ((nh > h) && h > 0)
		{
			nh = h;
			nw = (h/$obj.height()) * $obj.width();
		}
		xscale = $obj.width() / nw;
		yscale = $obj.height() / nh;
		$obj.width(nw).height(nh);
	};
	/*}}}*/
	function unscale(c)/*{{{*/
	{
		return {
			x: parseInt(c.x * xscale), y: parseInt(c.y * yscale), 
			x2: parseInt(c.x2 * xscale), y2: parseInt(c.y2 * yscale), 
			w: parseInt(c.w * xscale), h: parseInt(c.h * yscale)
		};
	};
	/*}}}*/
	function doneSelect(pos)/*{{{*/
	{
		var c = Coords.getFixed();
		if (c.w > options.minSelect[0] && c.h > options.minSelect[1])
		{
			Selection.enableHandles();
			Selection.done();
		}
		else
		{
			Selection.release();
		}
		Tracker.setCursor( options.allowSelect?'crosshair':'default' );
	};
	/*}}}*/
	function newSelection(e)/*{{{*/
	{
		if (options.disabled) return false;
		if (!options.allowSelect) return false;
		btndown = true;
		docOffset = getPos($img);
		Selection.disableHandles();
		myCursor('crosshair');
		var pos = mouseAbs(e);
		Coords.setPressed(pos);
		Tracker.activateHandlers(selectDrag,doneSelect);
		KeyManager.watchKeys();
		Selection.update();

		e.stopPropagation();
		e.preventDefault();
		return false;
	};
	/*}}}*/
	function selectDrag(pos)/*{{{*/
	{
		Coords.setCurrent(pos);
		Selection.update();
	};
	/*}}}*/
	function newTracker()
	{
		var trk = $('<div></div>').addClass(cssClass('tracker'));
		$.browser.msie && trk.css({ opacity: 0, backgroundColor: 'white' });
		return trk;
	};

	// }}}
	// API methods {{{
		
	function animateTo(a)/*{{{*/
	{
		var x1 = a[0] / xscale,
			y1 = a[1] / yscale,
			x2 = a[2] / xscale,
			y2 = a[3] / yscale;

		if (animating) return;

		var animto = Coords.flipCoords(x1,y1,x2,y2);
		var c = Coords.getFixed();
		var animat = initcr = [ c.x, c.y, c.x2, c.y2 ];
		var interv = options.animationDelay;

		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;

				setSelectRaw(animat);
			};
		}();

		function animateStart()
			{ window.setTimeout(animator,interv); };

		animateStart();
	};
	/*}}}*/
	function setSelect(rect)//{{{
	{
		setSelectRaw([rect[0]/xscale,rect[1]/yscale,rect[2]/xscale,rect[3]/yscale]);
	};
	//}}}
	function setSelectRaw(l) /*{{{*/
	{
		Coords.setPressed([l[0],l[1]]);
		Coords.setCurrent([l[2],l[3]]);
		Selection.update();
	};
	/*}}}*/
	function setOptions(opt)/*{{{*/
	{
		if (typeof(opt) != 'object') opt = { };
		options = $.extend(options,opt);

		if (typeof(options.onChange)!=='function')
			options.onChange = function() { };

		if (typeof(options.onSelect)!=='function')
			options.onSelect = function() { };

	};
	/*}}}*/
	function tellSelect()/*{{{*/
	{
		return unscale(Coords.getFixed());
	};
	/*}}}*/
	function tellScaled()/*{{{*/
	{
		return Coords.getFixed();
	};
	/*}}}*/
	function setOptionsNew(opt)/*{{{*/
	{
		setOptions(opt);
		interfaceUpdate();
	};
	/*}}}*/
	function disableCrop()//{{{
	{
		options.disabled = true;
		Selection.disableHandles();
		Selection.setCursor('default');
		Tracker.setCursor('default');
	};
	//}}}
	function enableCrop()//{{{
	{
		options.disabled = false;
		interfaceUpdate();
	};
	//}}}
	function cancelCrop()//{{{
	{
		Selection.done();
		Tracker.activateHandlers(null,null);
	};
	//}}}
	function destroy()//{{{
	{
		$div.remove();
		$origimg.show();
	};
	//}}}

	function interfaceUpdate(alt)//{{{
	// This method tweaks the interface based on options object.
	// Called when options are changed and at end of initialization.
	{
		options.allowResize ?
			alt?Selection.enableOnly():Selection.enableHandles():
			Selection.disableHandles();

		Tracker.setCursor( options.allowSelect? 'crosshair': 'default' );
		Selection.setCursor( options.allowMove? 'move': 'default' );

		$div.css('backgroundColor',options.bgColor);

		if ('setSelect' in options) {
			setSelect(opt.setSelect);
			Selection.done();
			delete(options.setSelect);
		}

		if ('trueSize' in options) {
			xscale = options.trueSize[0] / boundx;
			yscale = options.trueSize[1] / boundy;
		}

		xlimit = options.maxSize[0] || 0;
		ylimit = options.maxSize[1] || 0;
		xmin = options.minSize[0] || 0;
		ymin = options.minSize[1] || 0;

		if ('outerImage' in options)
		{
			$img.attr('src',options.outerImage);
			delete(options.outerImage);
		}

		Selection.refresh();
		
		if ( typeof options.onInit == 'function' ) {
			options.onInit();
		}
	};
	//}}}

	// }}}

	$hdl_holder.hide();
	interfaceUpdate(true);
	
	var api = {
		animateTo: animateTo,
		setSelect: setSelect,
		setOptions: setOptionsNew,
		tellSelect: tellSelect,
		tellScaled: tellScaled,

		disable: disableCrop,
		enable: enableCrop,
		cancel: cancelCrop,

		focus: KeyManager.watchKeys,

		getBounds: function() { return [ boundx * xscale, boundy * yscale ]; },
		getWidgetSize: function() { return [ boundx, boundy ]; },

		release: Selection.release,
		destroy: destroy
	};

	$origimg.data('Jcrop',api);
	return api;
};

$.fn.Jcrop = function(options)/*{{{*/
{
	function attachWhenDone(from)/*{{{*/
	{
		var loadsrc = options.useImg || from.src;
		var img = new Image();
		img.onload = function() { $.Jcrop(from,options); };
		img.src = loadsrc;
	};
	/*}}}*/
	if (typeof(options) !== 'object') options = { };

	// Iterate over each object, attach Jcrop
	this.each(function()
	{
		// If we've already attached to this object
		if ($(this).data('Jcrop'))
		{
			// The API can be requested this way (undocumented)
			if (options == 'api') return $(this).data('Jcrop');
			// Otherwise, we just reset the options...
			else $(this).data('Jcrop').setOptions(options);
		}
		// If we haven't been attached, preload and attach
		else attachWhenDone(this);
	});

	// Return "this" so we're chainable a la jQuery plugin-style!
	return this;
};
/*}}}*/

})(jQuery);

/*** BREAK ***/

/*
Copyright (c) 2009 Ronnie Garcia, Travis Nickels

This file is part of Uploadify v1.6.2

Permission is hereby granted, free of charge, to any person obtaining a copy
of Uploadify 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.

UPLOADIFY 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.
*/

var flashVer = -1;
if (navigator.plugins != null && navigator.plugins.length > 0) {
	if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
		var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
		var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
		var descArray = flashDescription.split(" ");
		var tempArrayMajor = descArray[2].split(".");			
		var versionMajor = tempArrayMajor[0];
		var versionMinor = tempArrayMajor[1];
		var versionRevision = descArray[3];
		if (versionRevision == "") {
			versionRevision = descArray[4];
		}
		if (versionRevision[0] == "d") {
			versionRevision = versionRevision.substring(1);
		} else if (versionRevision[0] == "r") {
			ersionRevision = versionRevision.substring(1);
			if (versionRevision.indexOf("d") > 0) {
				versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
			}
		}
		var flashVer = versionMajor + "." + versionMinor	 + "." + versionRevision;
	}
} else if ( $.browser.msie ) {
	var version;
	var axo;
	var e;
	try {
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}	
	flashVer = version.replace("WIN ","").replace(",",".");
}
if (flashVer != -1) {
	flashVer = flashVer.split(".")[0];
}

if(jQuery)(
	function($){
		$.extend($.fn,{
			fileUpload:function(options) {
				if (flashVer >= 9) {
					$(this).each(function(){
						settings = $.extend({
						uploader:      'uploader.swf',
						script:        'uploader.php',
						folder:        '',
						height:        30,
						width:         110,
						cancelImg:     'cancel.png',
						wmode:         'opaque',
						scriptAccess:  'sameDomain',
						fileDataName:  'Filedata',
						displayData:   'percentage',
						onInit:        function() {},
						onSelect:      function() {},
						onCheck:       function() {},
						onCancel:      function() {},
						onError:       function() {},
						onProgress:    function() {},
						onComplete:    function() {}
					}, options);
					var pagePath = '';// location.pathname;
					// pagePath = pagePath.split('/');
					// pagePath.pop();
					// pagePath = pagePath.join('/') + '/';
					var data = '&pagepath=' + pagePath;
					if (settings.buttonImg) data += '&buttonImg=' + escape(settings.buttonImg);
					if (settings.buttonText) data += '&buttonText=' + escape(settings.buttonText);
					if (settings.rollover) data += '&rollover=true';
					data += '&script=' + settings.script;
					data += '&folder=' + escape(settings.folder);
					if (settings.scriptData) {
						var scriptDataString = '';
						for (var name in settings.scriptData) {
							scriptDataString += '&' + name + '=' + settings.scriptData[name];
						}
						data += '&scriptData=' + escape(scriptDataString); 
					}
					data += '&btnWidth=' + settings.width;
					data += '&btnHeight=' + settings.height;
					data += '&wmode=' + settings.wmode;
					if (settings.hideButton) data += '&hideButton=true';
					if (settings.fileDesc) data += '&fileDesc=' + settings.fileDesc + '&fileExt=' + settings.fileExt;
					if (settings.multi) data += '&multi=true';
					if (settings.auto) data += '&auto=true';
					if (settings.sizeLimit) data += '&sizeLimit=' + settings.sizeLimit;
					if (settings.simUploadLimit) data += '&simUploadLimit=' + settings.simUploadLimit;
					if (settings.checkScript) data += '&checkScript=' + settings.checkScript;
					if (settings.fileDataName) data += '&fileDataName=' + settings.fileDataName;
					if ($.browser.msie) {
						flashElement = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + settings.width + '" height="' + settings.height + '" id="' + $(this).attr("id")  + 'Uploader" class="fileUploaderBtn">\
						<param name="movie" value="' + settings.uploader + '?fileUploadID=' + $(this).attr("id") + data + '" />\
						<param name="quality" value="high" />\
						<param name="wmode" value="' + settings.wmode + '" />\
						<param name="allowScriptAccess" value="' + settings.scriptAccess + '">\
						<param name="swfversion" value="9.0.0.0" />\
						</object>';
					} else {
						flashElement = '<embed src="' + settings.uploader + '?fileUploadID=' + $(this).attr("id") + data + '" quality="high" width="' + settings.width + '" height="' + settings.height + '" id="' + $(this).attr("id") + 'Uploader" class="fileUploaderBtn" name="' + $(this).attr("id") + 'Uploader" allowScriptAccess="' + settings.scriptAccess + '" wmode="' + settings.wmode + '" type="application/x-shockwave-flash" />';
					}
					if (settings.onInit() !== false) {
						$(this).css('display','none');
						if ($.browser.msie) {
							$(this).after('<div id="' + $(this).attr("id")  + 'Uploader"></div>');
							document.getElementById($(this).attr("id")  + 'Uploader').outerHTML = flashElement;
						} else {
							$(this).after(flashElement);
						}
						$("#" + $(this).attr('id') + "Uploader").after('<div id="' + $(this).attr('id') + 'Queue" class="fileUploadQueue"></div>');
					}
					$(this).bind("rfuSelect", {'action': settings.onSelect}, function(event, queueID, fileObj) {
						if (event.data.action(event, queueID, fileObj) !== false) {
							var byteSize = Math.round(fileObj.size / 1024 * 100) * .01;
							var suffix = 'KB';
							if (byteSize > 1000) {
								byteSize = Math.round(byteSize *.001 * 100) * .01;
								suffix = 'MB';
							}
							var sizeParts = byteSize.toString().split('.');
							if (sizeParts.length > 1) {
								byteSize = sizeParts[0] + '.' + sizeParts[1].substr(0,2);
							} else {
								byteSize = sizeParts[0];
							}
							if (fileObj.name.length > 20) {
								fileName = fileObj.name.substr(0,20) + '...';
							} else {
								fileName = fileObj.name;
							}
							$('#' + $(this).attr('id') + 'Queue').append('<div id="' + $(this).attr('id') + queueID + '" class="fileUploadQueueItem">\
									<div class="cancel">\
										<a href="javascript:$(\'#' + $(this).attr('id') + '\').fileUploadCancel(\'' + queueID + '\')"><img src="' + settings.cancelImg + '" border="0" /></a>\
									</div>\
									<span class="fileName">' + fileName + ' (' + byteSize + suffix + ')</span><span class="percentage">&nbsp;</span>\
									<div class="fileUploadProgress" style="width: 100%;">\
										<div id="' + $(this).attr('id') + queueID + 'ProgressBar" class="fileUploadProgressBar" style="width: 1px; height: 3px;"></div>\
									</div>\
								</div>');
						}
					});
					if (typeof(settings.onSelectOnce) == 'function') {
						$(this).bind("rfuSelectOnce", settings.onSelectOnce);
					}
					$(this).bind("rfuCheckExist", {'action': settings.onCheck}, function(event, checkScript, fileQueue, folder, single) {
						var postData = new Object();
						postData.folder = pagePath + folder;
						for (var queueID in fileQueue) {
							postData[queueID] = fileQueue[queueID];
							if (single) {
								var singleFileID = queueID;
							}
						}
						$.post(checkScript, postData, function(data) {
							for(var key in data) {
								if (event.data.action(event, checkScript, fileQueue, folder, single) !== false) {
									var replaceFile = confirm('Do you want to replace the file \'' + data[key] + '\'?');
									if (!replaceFile) {
										document.getElementById($(event.target).attr('id') + 'Uploader').cancelFileUpload(key);
									}
								}
							}
							if (single) {
								document.getElementById($(event.target).attr('id') + 'Uploader').startFileUpload(singleFileID, true);
							} else {
								document.getElementById($(event.target).attr('id') + 'Uploader').startFileUpload(null, true);
							}
						}, "json");
					});
					$(this).bind("rfuCancel", {'action': settings.onCancel}, function(event, queueID, fileObj, data) {
						if (event.data.action(event, queueID, fileObj, data) !== false) {
							$("#" + $(this).attr('id') + queueID).fadeOut(250, function() { $("#" + $(this).attr('id') + queueID).remove()});
						}
					});
					$(this).bind("rfuClearQueue", {'action': settings.onClearQueue}, function() {
						if (event.data.action() !== false) {
							$('#' + $(this).attr('id') + 'Queue').contents().fadeOut(250, function() {$('#' + $(this).attr('id') + 'Queue').empty()});
						}
					});
					$(this).bind("rfuError", {'action': settings.onError}, function(event, queueID, fileObj, errorObj) {
						if (event.data.action(event, queueID, fileObj, errorObj) !== false) {
							$("#" + $(this).attr('id') + queueID + " .fileName").text(errorObj.type + " Error - " + fileObj.name);
							$("#" + $(this).attr('id') + queueID).css({'border': '3px solid #FBCBBC', 'background-color': '#FDE5DD'});
						}
					});
					$(this).bind("rfuProgress", {'action': settings.onProgress, 'toDisplay': settings.displayData}, function(event, queueID, fileObj, data) {
						if (event.data.action(event, queueID, fileObj, data) !== false) {
							$("#" + $(this).attr('id') + queueID + "ProgressBar").css('width', data.percentage + '%');
							if (event.data.toDisplay == 'percentage') displayData = ' - ' + data.percentage + '%';
							if (event.data.toDisplay == 'speed') displayData = ' - ' + data.speed + 'KB/s';
							if (event.data.toDisplay == null) displayData = ' ';
							$("#" + $(this).attr('id') + queueID + " .percentage").text(displayData);
						}
					});
					$(this).bind("rfuComplete", {'action': settings.onComplete}, function(event, queueID, fileObj, response, data) {
						if (event.data.action(event, queueID, fileObj, unescape(response), data) !== false) {
							$("#" + $(this).attr('id') + queueID).fadeOut(250, function() { $("#" + $(this).attr('id') + queueID).remove()});
							$("#" + $(this).attr('id') + queueID + " .percentage").text(' - Completed');
						}
					});
					if (typeof(settings.onAllComplete) == 'function') {
						$(this).bind("rfuAllComplete", settings.onAllComplete);
					}
				});
			}
		},
		fileUploadSettings:function(settingName, settingValue) {
			$(this).each(function() {
				document.getElementById($(this).attr('id') + 'Uploader').updateSettings(settingName,settingValue);
			});
		},
		fileUploadStart:function(queueID) {
			$(this).each(function() {
				document.getElementById($(this).attr('id') + 'Uploader').startFileUpload(queueID, false);
			});
		},
		fileUploadCancel:function(queueID) {
			$(this).each(function() {
				document.getElementById($(this).attr('id') + 'Uploader').cancelFileUpload(queueID);
			});
		},
		fileUploadClearQueue:function() {
			$(this).each(function() {
				document.getElementById($(this).attr('id') + 'Uploader').clearFileUploadQueue();
			});
		}
	})
})(jQuery);
/*** BREAK ***/

/**
 * @project talenthouse
 * @package th.ui.profile_crop
 * @since   07.05.2009
 *
 *	Handles profile pic upload and crop panel 
 * 
 */
th.ui.profile_crop = {

	// Filenames
	pp_FilenameOriginal:'original.jpg',
	pp_FilenameLarge:	'221x271.jpg',
	pp_FilenameMedium:	'114x114.jpg',

	cropImageWidth: 117,
	cropImageHeight: 145,
	sourceImageWidth: 0,
	sourceImageHeight: 0,
	coords: {},
	username: '',

	imageUrlRoot: '',
	imageSrc: '',
	thumbSrc: '',
	
	url: '',
	path: '',

	updateurl: '',
	
	srcImageId: '',
	srcImagePanelId: '',
	previewImageId: '',

	started: false,
	
	initialised: false, 
	
	init: function( _username , _srcImagePanelId , _previewImageId , _imageUrlRoot, _imageSrc , _thumbSrc , _saveUrl , _path , _updateurl , _preloadContainerId , _pp_FilenameOriginal, _pp_FilenameLarge, _pp_FilenameMedium) {

		th.ui.profile_crop.username = _username; 

		th.ui.profile_crop.imageUrlRoot = _imageUrlRoot;
		th.ui.profile_crop.imageSrc = _imageSrc;
		th.ui.profile_crop.thumbSrc = _thumbSrc;

		th.ui.profile_crop.srcImagePanelId = _srcImagePanelId;
		th.ui.profile_crop.preloadContainerId = _preloadContainerId;
		th.ui.profile_crop.previewImageId = _previewImageId;

		th.ui.profile_crop.url = _saveUrl;
		th.ui.profile_crop.path = _path;
		th.ui.profile_crop.updateurl = _updateurl;
		
		th.ui.profile_crop.pp_FilenameOriginal = _pp_FilenameOriginal;
		th.ui.profile_crop.pp_FilenameMedium = _pp_FilenameMedium; 
		th.ui.profile_crop.pp_FilenameLarge = _pp_FilenameLarge;
		
		th.ui.profile_crop.loadCrop();
	},
	
	updateImageFilenames: function( _imageSrc , _thumbSrc ) 
	{
		th.ui.profile_crop.imageSrc = _imageSrc;
		if ( typeof _thumbSrc != 'undefined' ) {
			th.ui.profile_crop.thumbSrc = _thumbSrc;
		}
	},
	
	loadCrop: function()
	{
		th.ui.profile_crop.started = false;
		
		$(th.ui.profile_crop.previewImageId + '_actual').css('display', 'block');
		$(th.ui.profile_crop.previewImageId).css('display', 'none');
		$('#btn_save_crop').css('display', 'none');
		
		th.ui.profile_crop.initialised = false;
		
		th.ui.profile_crop.srcImageId = th.ui.profile_crop.srcImagePanelId + '_img';

		$('#' + th.ui.profile_crop.srcImagePanelId).html('');

		// Initialise Preview Image
		$(th.ui.profile_crop.previewImageId + '_actual').attr('style', 'width: 114px; height:137px;');
		$(th.ui.profile_crop.previewImageId + '_actual').attr('src', th.ui.profile_crop.imageUrlRoot + th.ui.profile_crop.thumbSrc );
		$(th.ui.profile_crop.previewImageId).attr('src', th.ui.profile_crop.imageUrlRoot + th.ui.profile_crop.imageSrc ); 
		
		// th.ui.loadingAnimation.start('#cropContainer');
		
		$('#cropContainer').append('<div id="crop_loading_anim" style="width:510px;height:301px;"><div style="margin: 130px auto; width: 100px;"><div id="loading_crop"></div></div>');
		swfobject.embedSWF( th.params.swfLoadingAnim, "loading_crop", "50", "50", "9.0.0", th.params.bucketPath + '/flash/expressInstall.swf', {}, { bgcolor: "#000000", wmode: "transparent" } );

		$('#cropContainer').css('padding', '0px');
		
		$(new Image()).load(function() {
				$(this).appendTo('#' + th.ui.profile_crop.srcImagePanelId);
				
				th.ui.profile_crop.sourceImageWidth = $('#' + th.ui.profile_crop.srcImageId).width();
				th.ui.profile_crop.sourceImageHeight = $('#' + th.ui.profile_crop.srcImageId).height();
				
				jQuery('#' + th.ui.profile_crop.srcImageId).Jcrop({
					boxWidth: 510,
					boxHeight: 400,
					setSelect: [ 0, 0, 1000, 1000 ],
					enterbind: th.ui.profile_crop.save,
					onChange: th.ui.profile_crop.preview,
					onSelect: th.ui.profile_crop.select,
					aspectRatio: th.ui.profile_crop.cropImageWidth /  th.ui.profile_crop.cropImageHeight,
					onInit: function() { 
						th.ui.profile_crop.initialised = true;
						$('#crop_loading_anim').remove();
						$('#cropContainer').css('padding', '20px');
					} 
				});
				
				// setTimeout(function() { objCrop.animateTo([ 10, 10, 500, 500]); } , 500);
				
			}).attr('id',th.ui.profile_crop.srcImageId).attr('src',th.ui.profile_crop.imageUrlRoot + th.ui.profile_crop.imageSrc);
	},

	preview: function (coords)
	{
		th.ui.profile_crop.coords = coords;
		
		if ( th.ui.profile_crop.initialised === true ) {
	
			if (th.ui.profile_crop.previewImageId != '')
			{
				$(th.ui.profile_crop.previewImageId + '_actual').css('display', 'none');
				$(th.ui.profile_crop.previewImageId).css('display', 'block'); 
				$('#btn_save_crop').css('display', 'block');
				
				if (parseInt(coords.w) > 0)
				{
					var rx = th.ui.profile_crop.cropImageWidth / coords.w;
					var ry = th.ui.profile_crop.cropImageHeight / coords.h;
		
					jQuery(th.ui.profile_crop.previewImageId).css({
						width: Math.round(rx * th.ui.profile_crop.sourceImageWidth) + 'px',
						height: Math.round(ry * th.ui.profile_crop.sourceImageHeight) + 'px',
						marginLeft: '-' + Math.round(rx * coords.x) + 'px',
						marginTop: '-' + Math.round(ry * coords.y) + 'px'
					});
				}
			}
		}

	},
	
	select: function (c)
	{
		th.ui.profile_crop.coords = c;
	},

	
	save: function (callback)
	{
		var c = th.ui.profile_crop.coords;
		if (typeof c == 'undefined') {
			return;
		}
		if (typeof c.x == 'undefined') {
			return;
		}
		
		// Loading Animation
		th.ui.loadingAnimation.start(th.ui.profile_crop.preloadContainerId);		
		th_crop_upload_setLoadingMsg(PP_PROCESSING_THUMB);
		
		// Send Crop Request
		$.post (
			'/myaccount/profilepicture/crop',
			{
				path: th.ui.profile_crop.path,
				x: c.x,
				y: c.y,
				x2: c.x2,
				y2: c.y2,
				w: c.w,
				h: c.h,
				s3Url: th.ui.profile_crop.imageUrlRoot + th.ui.profile_crop.imageSrc
			},
			function(response){

				$.post (
						th.ui.profile_crop.updateurl,
						{
							filename: response
						},
						function(jsonString){
						    //update flash
                            th.flash.updateUserData(JSON.parse(jsonString));
							th.ui.profile_crop.updateImageFilenames(response + '/' + th.ui.profile_crop.pp_FilenameOriginal, response + '/' + th.ui.profile_crop.pp_FilenameLarge);
							th.ui.profile_crop.loadCrop();
							th.ui.loadingAnimation.stop();
						}
					);
			}
		);
		
	}
	
};


/**
 * UPLOAD INITIALISATION & CALLBACK SCRIPTS
 * 
 * @param targetId
 * @param script
 * @param folder
 * @param activeTab
 * @param projectId
 * @return
 */

th_crop_upload_updateurl = '';

function th_crop_upload_Load( targetId , script, folder , updateurl ) 
{
	th_crop_upload_updateurl = updateurl;
	
	$(targetId).fileUpload ({

		'script':			script,
		'folder':			folder,
		
		'uploader':			th.params.bucketPath + '/flash/uploader.swf',
		'cancelImg':		th.params.bucketPath + '/images/blank.png',
		'scriptAccess':		'always',
		'multi':			false,
		'auto':				true,
		'buttonImg':		th.params.bucketPath + '/images/browse.png',
		'width':			72,
		'height':			24,
		'simUploadLimit':	1,
		'fileDesc':			'Files',
		'fileExt':			'*.jpg:5;*.gif:5;*.png:5;*.tiff:5;',

		//'wmode':			'Window',

		'onInit':			th_crop_upload_onInit,
		'onSelect':			th_crop_upload_onProgress,							
		'onProgress':		th_crop_upload_onProgress,
		'onComplete':		th_crop_upload_onComplete,
		'onCancel':			th_crop_upload_onCancel,
		'onError':			th_crop_upload_onCancel
	});

};

function th_crop_upload_onInit() {
	$('div#crop_selectfiles').css('display', 'block');
	return true;
};


function th_crop_upload_onProgress(event, queueID, fileObj, data) 
{
	try 
	{
		if (typeof data == 'object') {
			if ( data.percentage == 100 ) {
				// th.log('UPLOAD: Progress 100% [' + queueID + ']');
				
				th_crop_upload_setLoadingMsg(PP_PROCESSING_IMAGE);
				
			} else {
				th_crop_upload_setLoadingMsg(PP_UPLOADING + ': ' + data.percentage + '%');
			}
		}
	} catch( e ) { }
	
	return true;
};

function th_crop_upload_onComplete(event, queueID, fileObj, response, data) 
{
	if (response=='false') 
	{
		//	alert('Upload Failure');
	}
	else 
	{
		$('#cropArea').css('display', 'block');
		th.ui.profile_crop.updateImageFilenames(response + '/' + th.ui.profile_crop.pp_FilenameOriginal );
		th_crop_upload_setLoadingMsg(PP_COMPLETE);
		th.ui.loadingAnimation.stop();
		th.ui.profile_crop.loadCrop();
		/*
		$.post (
				th_crop_upload_updateurl,
				{
					filename: response
				},
				function() 
				{
					$('#cropArea').css('display', 'block');
					th.ui.profile_crop.updateImageFilenames(response + '/' + th.ui.profile_crop.pp_FilenameOriginal, response + '/' + th.ui.profile_crop.pp_FilenameLarge);
					th_crop_upload_setLoadingMsg(PP_COMPLETE);
					th.ui.loadingAnimation.stop();
					th.ui.profile_crop.loadCrop();
				}
			);
		*/
	}
	
	return true;
};
	

function th_crop_upload_onCancel(event, queueID, fileObj, data) 
{
	try {
		// Cancel upload
		$('#TH_Uploader').fileUploadCancel(queueID); 
		$('#TH_Uploader' + queueID).remove();

		th.ui.loadingAnimation.stop();
		return true;
	}
	finally 
	{ 
		return true; 
	}; 

	return true;
};



function th_crop_upload_setLoadingMsg(msg) 
{
	// th.log('UPLOAD: Update Message');
	if ( $('#exposeMask').size() < 1 ) {
		th.ui.loadingAnimation.start('#content_profilepicture');
	}
	
	$('#loadingMsg').html( msg );
	$('#loadingMsg').css('display', 'block');

};



/*** BREAK ***/

$(document).ready(function() {

	th.afterlogin.add(
		function() {
			$("#ac_search").th_autocomplete_search({ urlLookup:"/search/site/do/" });
			$("#ac_search").focus();
		}
	);
	
	$("#ac_search").th_autocomplete_search({ urlLookup:"/search/site/do/" });
	$("#ac_search").focus();

	
});

/**
 * @project talenthouse
 * @package jQuery.fn.th_autocomplete
 * @since   28.05.2009
 *
 * Autocomplete Control for Collaborators page
 * 
 */

jQuery.fn.th_autocomplete_search = function(options) 
{
	var tmp = this;
	var settings = 
	{
		ul         : tmp,
		urlLookup  : [""],
		acOptions  : {
			minChars: 4,
			width: '360',
			scrollHeight: 300,
			multiple: false,
			matchCase: true,
			matchContains: false,
			autoFill: false,
			scroll: true,
			delay:300,
			cacheLength: 20,
			matchSubset: false,
			selectFirst: false,
			dataType: 'json',
			allowEmail: false,
			noHideOnBlur: false,
			noHideOnEmptyResult: false,
			showPersistently: false,
			displayOnFocus: true,
			absPosition: true,
			formatResult: function(data, i, max){
				return data.lastname;
			},
			dataInputIds: 'input#ac_search',
			parse: function(resp) {

				var artists = new Array();
				if (typeof resp.artists != 'undefined' && resp.artists != null )
				{
					if (resp.artists.length > 0) {
						artists = $.map(resp.artists,
				    		function(row) {
								row.type='artist';
				                return {
					                data: row,
					                value: row.firstname + ' ' + row.lastname,
					                result: row.firstname + ' ' + row.lastname
				                }
		                	}
						);
					}
				}
				
				var projects = new Array();
				if (typeof resp.projects != 'undefined' && resp.projects != null )
				{
					if (resp.projects.length > 0) {
						projects = $.map(resp.projects,
				    		function(row) {
								row.type='project';
				                return {
					                data: row,
					                value: row.name,
					                result: row.name
				                }
		                	}
						);
					}
				}
				
				return jQuery.merge(artists, projects);
			},
			attachTo: '#ac_search_results',
			formatItem: function(row, i, max) {
				var titleText = '&nbsp;';
				if (row.type == 'project') 
				{
					titleText = 'Project:';

					return '<a onclick="th.flash.goToProject(\'' + row.owner + '\', \'' + row.id + '\');th.flash.showUserpageButton();$.scrollTo(\'div#flash\');return false;"><span class="rounded_all" style="background: rgb(204, 204, 204) url('+row.image+') no-repeat scroll center center; width: 50px; height: 50px;">&nbsp;</span>' 
					+ row.name + '<br/>' + row.location + '</a>';
					return '';
				}
				if (row.type == 'artist') 
				{
					titleText = 'Artist:';
					// return '<div style="float:left; width: 80px;"><h3>'+titleText+'</h3></div><div style="float:left;"><table><tr><td style=\"vertical-align: top; padding: 2px;\"><img src=\"'+row.image+'\" style=\"width:30px; height: 30px;\" /></td><td style=\"vertical-align: top; padding: 0px 2px; line-height: 16px;\">'+row.firstname + ' ' + row.lastname +'<br/><span style=\"color: #666666;\">'+row.location+'</span></td></tr></table></div><div style="clear: both;></div>"';
					// return row.image+ ++row.location+';
					return '<a href="/'+row.nickname+'"><span class="rounded_all" style="background: rgb(204, 204, 204) url('+row.image+') no-repeat scroll center center;">&nbsp;</span>' 
								+ row.firstname + ' ' + row.lastname + '<br/>' + row.nickname + '</a>';
				}
			},
			header: '<div style="float:right;"><a class="close" href="javascript:;" onclick="$(\'#ac_search_results\').css(\'display\', \'none\'); return false;">Hide</a></div><div style="clear:both;>"',
			footer: '</div>',
			onselectfocus: function(item) {
	        //	$('.do_you_mean_star').css('display', 'none');
			//	$('.do_you_mean_star', $(item)).css('display', 'block');
	        },
	        onchange: function() {
	        },
			notifyShowHide: function(visible) {
				if ( visible ) {
					th.flash.blur();
				} else {
					th.flash.unblur();
				}
			}
		},
		foundClass : ".acfb-data",
		inputClass : ".acfb-input"
    }
    
	
	if(options) { jQuery.extend(settings, options); }
	
	var acfb = { params  : settings }
	
	$(tmp).autocomplete(settings.urlLookup,settings.acOptions);

	$(tmp).result(function(event,data,formatted){
		
		if (typeof data == 'object')
		{
			if (data.type=='artist')
			{
				// Push values from selected user to form fields
				location.href="/"+data.nickname;
			} 
			else 
			{
				th.flash.goToProject(data.owner, data.id);
				th.flash.showUserpageButton();
				$.scrollTo('div#flash');
			}
		}
		
		
	});
	return acfb;
};


/*** BREAK ***/

/**
 * @project talenthouse
 * @package th.myaccount
 * @author  Herbert Roth <herbert@kronomy.com>
 * @since   13.05.2009
 *
 * 
 */

th.myaccount = {
		
		hidecreativeprofilefields: function(field, closeClass)
		{
			if (typeof closeClass == 'undefined') {
				closeClass == 'height_twenty';
			}
			
			$('#' + field).each(function(){
				var rel=$(this).attr('rel');
	
				$('[rel*=' + rel + ']').each(function()
				{
					if ($(this).attr('id') != field) {
						
						// Shrink
	
						$(this).removeClass('opened');
						$(this).css("overflow","hidden");
						
						if(this.tagName.toLowerCase()=='div') {
							$("a",$(this)).addClass('close');
							$("a",$(this)).removeClass('open');
							$(this).addClass(closeClass);
						} else {
							$("a",$(this).prev()).addClass('close');
							$("a",$(this).prev()).removeClass('open');
							$(this).addClass(closeClass);
						}
						
					}
					else
					{
						// Expand
						
						$(this).addClass('opened');
						$(this).css("overflow","auto");
						$(this).css("overflow-x","hidden");
						$(this).css("overflow-y","auto");
						if(this.tagName.toLowerCase()=='div') {
							$(this).removeClass(closeClass);
							$("a",$(this)).removeClass('close');
							$("a",$(this)).addClass('open');
	
						} else {
	
							$(this).removeClass(closeClass);
							$(this).css("overflow","auto");
							$("a",$(this).prev()).removeClass('close');
							$("a",$(this).prev()).addClass('open');
								
						}
						
					}
					
				});
			});

		}		
}
/*** BREAK ***/

/**
  * @project talenthouse
  * @since   28.05.2009
  *
  * JS for Collaborators forms
  * 
  */



th.collaborator = {

		
/*
 * MY PROFILE ADD COLLABORATORS METHODS
 * 
 */

	remove: function( deleteUrl , target , _uid ) {
	
			var uid = _uid;
			var params = { data: {  
				'method': 'delete',
				'uid': uid + ''
			}};

			th.ajax.ajaxLoad( deleteUrl , target , true , null , params );
		},

	edit: function( deleteUrl , target , _uid ) {
				var uid = _uid;
				var params = { data: { 
					'method': 'showedit',
					'uid': uid + ''
				}};

				th.ajax.ajaxLoad( deleteUrl , target , true , null , params );
			},

	submit: function(formid)
	{
		try 
		{
			// Populate hidden field with email
			if ( $('#invite_email').val() != '')
			{
				$('#email' , $(formid)).val($('#invite_email').val());
			}
			
			if ( $('#role' , $(formid)).attr('disabled') ) 
			{
				$('#role' , $(formid)).removeAttr('disabled');
				$('#role' , $(formid)).focus();
			}
			else 
			{
				//remove hints:
				$('input', $(formid)).each(function() { 
						if ($(this).val() == $(this).attr('title') || $(this).val() == $(this).attr('bt-xtitle') ) {
								$(this).val('').removeClass('hints_blur');
							}
					});
			
				/*
				 * FORM VALIDATION
				 */
				error=false; 
				
				username = jQuery.trim($('#nickname', $(formid)).fieldValue(false)[0])

				var testresults

				// client side form validation:
				if ( jQuery.trim($('#invite_email').val()) == '' && username == '' ) 
				{
					$('#invite_email').bt(
							CLB_ERR_SELECT_OR_EMAIL,
							th.params.bt_Error_Options);
					$('#invite_email').addClass('error');
					$('#invite_email').change(function(){ $(this).btOff(); $(this).removeClass('error'); });
					$('#invite_email').focus();
					error = true;
				}
				
				// client side form validation:
				/*
				 * 
				var email = jQuery.trim($('#invite_email').val());
				var filter = /^([a-zA-Z0-9_\.\-+])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				if ( email != '' && email.test(filter) == false ) 
				{
					alert('filtr failed: ' + email);
					$('#invite_email').bt(
							CLB_ERR_INVALID_EMAIL,
							th.params.bt_Error_Options);
					$('#invite_email').addClass('error');
					$('#invite_email').change(function(){ $(this).btOff(); $(this).removeClass('error'); });
					$('#invite_email').focus();
					error = true;
				}
				*/
				
				
				// client side form validation:
				if ( jQuery.trim($('#role').val()) == '' ) {
					$('#role').bt(
							CLB_ERR_EMPTY_ROLE,
							th.params.bt_Error_Options);
					$('#role').addClass('error');
					$('#role').change(function(){ $(this).removeClass('error');  $(this).btOff(); });
					$('#role').focus();
					error = true;
				}
				// client side form validation:
				if ( jQuery.trim($('#lastname').val()) == ''  && username == '' ) {
					$('#lastname').bt(
							CLB_ERR_EMPTY_LASTNAME,
							th.params.bt_Error_Options);
					$('#lastname').addClass('error');
					$('#lastname').change(function(){ $(this).removeClass('error'); $(this).btOff(); });
					$('#lastname').focus();
					error = true;
				}
				// client side form validation:
				if ( jQuery.trim($('#firstname').val()) == ''  && username == '' ) {
					$('#firstname').bt(
							CLB_ERR_EMPTY_FIRSTNAME,
							th.params.bt_Error_Options);
					$('#firstname').addClass('error');
					$('#firstname').change(function(){ $(this).removeClass('error'); $(this).btOff(); });
					$('#firstname').focus();
					error = true;
				}
				
				if (! error )
				{
					
					th.ui.form.submitform(formid, {}, "#collab"); 
				}
			}; 
		} catch (e) 
		{
			th.log('ERROR: th.collaborator.submit: ' + e);
			

			return false;
		}
	}


};


/**
 * @project talenthouse
 * @package jQuery.fn.th_autocomplete
 * @since   28.05.2009
 *
 * Autocomplete Control for Collaborators page
 * 
 */
jQuery.fn.th_autocomplete = function(options) 
{
	var tmp = this;
	var settings = 
	{
		ul         : tmp,
		urlLookup  : [""],
		acOptions  : {
			minChars: 4,
			width: '660',
			multiple: false,
			matchCase: false,
			matchContains: false,
			autoFill: false,
			scroll: false,
			scrollHeight: 100,
			delay:300,
			cacheLength: 20,
			matchSubset: false,
			selectFirst: false,
			dataType: 'json',
			allowEmail: false,
			noHideOnBlur: true,
			noHideOnEmptyResult: true,
			formatResult: function(data, i, max){
				return data.lastname;
			},
			displayOnFocus: true,
			dataInputIds: 'input#lastname,input#firstname',
			tabToId: '#role',
			parse: function(resp) {
				if (typeof resp.artists != 'undefined')
				{
					if (resp.artists.length > 0) {
						return $.map(resp.artists,
				    		function(row) {
				                return {
					                data: row,
					                value: row.firstname + ' ' + row.lastname,
					                result: row.lastname
				                }
		                	}
						);
					}
				}
				
				return [];
			},
			attachTo: '#collab_search_results',
			formatItem: function(row, i, max) {
				// return '<a href=""><span style="background:url('+row.image+') no-repeat">&nbsp;</span>'+row.firstname+'<br/>'+row.lastname+'</a>';
				
				return '<a class="user_pic" style="background: transparent url('+row.image+') no-repeat;" href="javascript:;">'
						+ '<img alt="" src="' + th.params.bucketPath + '/images/share_pics_frame.gif"/>'
						+ '</a><a href="javascript:;">' + row.firstname + '<br/>' + row.lastname + '</a>'
						+ '<img class="do_you_mean_star" alt="" src="' + th.params.bucketPath + '/images/do_you_mean_star.gif" style="display: none;" />';
				
			},
			headerList: '<h3>Do you mean?</h3>',
			header: '<a class="close" href="javascript:;" onclick="$(\'#collab_search_results\').css(\'display\', \'none\'); return false;">' + CLB_CLOSE + '</a>',
			resultsClass: "do_you_mean",
			footer: '<form class="rounded_all" onsubmit="th.collaborator.submit(\'#frm_collab_search\'); return false;"><fieldset class="rounded_all did_you_mean_mail">'
				+ '<p>' + CLB_ENTER_EMAIL_WITHIN_25_DAYS + '</p>'
				+ '<input type="text" id="invite_email" name="invite_email" />'
				+ '<p class="cancel_save"><a class="save" href="javascript:;" onclick="th.collaborator.submit(\'#frm_collab_search\'); return false;"><span>&nbsp;</span>' + CLB_SEND_INVITE + '</a></p></fieldset>'
				+ '</form>'
				+ '<script language="text/javascript">'
				+ '		$("#invite_email").th_forceTab( "#firstname", "#role" );'
				+ '		// $("#role").th_forceTab( "#invite_email", "#lastname" );'
				+ '</script>',
			onselectfocus: function(item) {
		        	$('.do_you_mean_star').css('display', 'none');
		        	$('.do_you_mean_star', $(item)).css('display', 'block');
		        },
		    onchange: function() {
		        	$('#nickname', $('#frm_collab_search')).val('');
					$('.avatar', $('#frm_collab_search')).css('background','url('+ th.params.bucketPath + '/images/pp/50x50.jpg)');
		        },
			lookupKey: function() {
		        	var fname = $('#firstname').val();
		        	var lname = $('#lastname').val();
		        	if (fname == $('#firstname').attr('title')) {
		        		fname = '';
		        	}
		        	if (lname == $('#lastname').attr('title')) {
		        		lname = '';
		        	}
		        	
					return fname + ' ' + lname;
				},
				extraParams: {
					'firstname': function() { 
						if ($('input#firstname').val() == $('input#firstname').attr('title')) {
								return '';
							} else {
								return $('input#firstname').val();
							}
						},
					'lastname': function() { 
						if ($('input#lastname').val() == $('input#lastname').attr('title')) {
							return '';
						} else {
							return $('input#lastname').val();
						}
					}
				}
		},
		foundClass : ".acfb-data",
		inputClass : ".acfb-input"
    };
    
	
	if(options) { jQuery.extend(settings, options); }
	
	var acfb = { params  : settings }
	
	$(tmp).autocomplete(settings.urlLookup,settings.acOptions);

	$(tmp).result(function(event,data,formatted){
		
		if (typeof data == 'object')
		{
			// Push values from selected user to form fields
			$('#firstname', $('#frm_collab_search')).val(data.firstname);
			$('#lastname', $('#frm_collab_search')).val(data.lastname);
			$('#nickname', $('#frm_collab_search')).val(data.nickname);
			$('.avatar', $('#frm_collab_search')).css('background','url(' + data.image + ')');	
			
			th.collaborator.submit('#frm_collab_search'); 
		}
	});
	return acfb;
};


/*** BREAK ***/





th.addressbook = {
		
	mailToAC: {},

	init: function() {

		th.addressbook.mailToAC = 
			$("#messageComposeFormId ul").th_autocomplete_addressbook(
				{ urlLookup:"/message/addressbook/search/" }
			);

		$("#messageComposeFormId textarea#to_input").focus();

	},
	
	submit: function() {

		var comma = '';
		var to = th.addressbook.mailToAC.getData();
		if (to == 'undefined'){
			to = '';
		}
		
		if (to != '') {
        	comma = ',';
        }
		if ($('#messageComposeFormId input#tohidden').val() != '') {
            to = to + comma + $('#messageComposeFormId input#to').val();
        }
		
		//if ($('#messageComposeFormId #to').val() != '') {
        //    to = to + comma + $('#messageComposeFormId textarea#to').val();
        //}
		
		// to solve some cache issues, replace: leading commas, trailing commas, double commas
		to = to.replace(/^\,*/, "").replace(/\,*$/, "").replace(",,", ",");
		
		// remove anything that isn't a-zA-Z0-9 or space
		$('#messageComposeFormId input#tohidden').val(to);
	
        th.ui.form.submitform('#messageComposeFormId');
	}
	
}

/**
 * @project talenthouse
 * @package jQuery.fn.th_autocomplete
 * @since   28.05.2009
 *
 * Autocomplete Control for Message Inbox page
 * 
 */
jQuery.fn.th_autocomplete_addressbook = function(options) 
{
	var tmp = this;
	var settings = 
	{
		ul         : tmp,
		urlLookup  : [""],
		acOptions  : {
			minChars: 4,
			width: 210,
			multiple: true,
			matchContains: false,
			autoFill: false,
			scroll: false,
			scrollHeight: 400,
			delay:30,
			cacheLength: 10,
			matchSubset: false,
			selectFirst: true,
			hideOnSelect: true,
			allowEmail: false,
			noHideOnBlur: false,
			noHideOnEmptyResult: false,
			displayOnFocus: true,
			ulclass: 'suggestion_list', 
			tabToId: 'input#subject',
			
			// dataInputIds: '#messageComposeFormId textarea#to',
			attachTo: '#composeMsgResults',
			dataType: 'json',
			formatItem: function(row, i, max) {
                var fname = (row.firstname+' '+row.lastname).replace(/^\s+|\s+$/g,"");
                var avatar = row.image;
                var test = "<a ><span style=\"background: url("+avatar+") no-repeat scroll center center;\" class=\"rounded_all ac_span\"></span>"+fname+"<br/><span class=\"ac_span\">"+row.nickname+"</span></a>";
    		    //var v = '<table><tr><td style=\"vertical-align: top; padding: 2px;\"><img src=\"'+avatar+'\" style=\"width:30px; height: 30px;\" /></td><td style=\"vertical-align: top; padding: 0px 2px; line-height: 16px;\">'+fname+'<br/><span style=\"color: #666666;\">'+row.nickname+'</span></td></tr></table>';
				return test;
			},
			parse: function(data) {
				if (typeof data != 'object') {
					return [];
				};
				if (typeof data.totalresults == 'undefined') {
					return [];
				}
				if (data.totalresults <= 0) {
					return [];
				}
				
				return $.map(data.userobjects, function(row) {
    				return {
		                data: row,
		                value: row.nickname + '|' + row.firstname + '|' + row.lastname,
		                result: row.nickname + '|' + row.firstname + '|' + row.lastname
	                }
                });
			}
		},
		foundClass : ".acfb-data",
		inputClass : ".acfb-input"
    }
    
	if(options) { jQuery.extend(settings, options); }
	
	var acfb = 
	{
		params  : settings,
		getData : function()
		{	
			var result = '';
		    $(settings.foundClass,tmp).each(function(i)
			{
				if (i>0)result+=',';
			    result += $('span',this).html();
		    });
			return result;
		},
		clearData : function()
		{	
		    $(settings.foundClass,tmp).remove();
			$(settings.inputClass,tmp).focus();
			return tmp.acfb;
		},
		removeFind : function(o){
			$(o).unbind('click').parent().parent().parent().parent().parent().remove();
			$(settings.inputClass,tmp).focus();
			return tmp.acfb;
		}
	}
	
	$(settings.foundClass+" img.p").click(function(){
		acfb.removeFind(this);
	});
	
	$(settings.inputClass,tmp).autocomplete(settings.urlLookup,settings.acOptions);
	$(settings.inputClass,tmp).result(function(event,data,formatted){
	    var username = data.nickname;
	
        // Check if already there:
		var bFound = false;
	    $(settings.foundClass,tmp).each(function(i)
		{
		    if ($('span',this).html() == username)
		        bFound = true;
	    });
	    if (bFound) {
    		$(settings.inputClass,tmp).val('').focus();
	        return;
        }
	    
	    // Not found: Add to list:
		var f = settings.foundClass.replace(/\./,'');
		var fname = (data.firstname+' '+data.lastname).replace(/^\s+|\s+$/g,"");
        var image = data.image;
        var v = '<li class="'+f+'"><table><tr><td style=\"vertical-align: middle;\"><img src=\"'+image+'\" style=\"width: 30px; height: 30px;\" /></td><td style=\"padding: 0px 2px; vertical-align: top; line-height: 16px; width: 70px;\">'+fname+'<br/><span style=\"color: #666666;\">'+data.nickname+'</span></td><td style=\"padding: 0px 2px; vertical-align: top;\"><img class="p" src="' + th.params.bucketPath + '/images/ac_delete.gif"/></td></tr></table></li>';
		var x = $(settings.inputClass,tmp).before(v);
		$('.p',x[0].previousSibling).click(function(){
			acfb.removeFind(this);
		});
		$(settings.inputClass,tmp).val('').focus();
	});
	$(settings.inputClass,tmp).focus();
	return acfb;
}

