﻿function fb_RootElementAtForm(elemId)
{
	var elem = document.getElementById(elemId);
	if (elem)
	{
		var parent = elem;
		while (parent && parent.tagName != "FORM" && parent.tagName != "BODY")
			parent = parent.parentNode;
		if (parent)
			parent.appendChild(elem);
	}
}

/******************************************************************************
 * Enums
 ******************************************************************************/
var fb_EditorModes = new Object();
fb_EditorModes.NotSet = 0;
fb_EditorModes.Resize = 1;
fb_EditorModes.Crop = 2;
fb_EditorModes.CropMove = 3;

var fb_KeyCodes = new Object();
fb_KeyCodes.Shift = 16;

/******************************************************************************
 * Globals
 ******************************************************************************/
var fb_ToolbarButtons = new Array();
var fb_CurrMode = fb_EditorModes.NotSet;
var fb_ImageToEdit;
var fb_ImageToEditLeft = 0;
var fb_ImageToEditTop = 0;
var fb_InitImageWidth = 450;
var fb_KeyHeld = null;
var fb_CropAspectRatio = new Object();
var fb_IsCropAspectRatioSetByShift = false;
var fb_MinResultWidth;
var fb_MinResultHeight;
var fb_MaxResizeWidth = 0;

var fb_CropXField;
var fb_CropYField;
var fb_CropWidthField;
var fb_CropHeightField;
var fb_ResizeWidthField;

var fb_OffsetX = 0;
var fb_OffsetY = 0;
var fb_IEOffsetX = 0;
var fb_IEOffsetY = 0;
var fb_ScrollLeftOffset = 0;
var fb_ScrollTopOffset = 0;

var fb_UseIEBehavior = (navigator.appVersion.indexOf("MSIE") >= 0);

var fb_FixedCropWidth = 0;
var fb_FixedCropHeight = 0;

/******************************************************************************
 * Global Functions
 ******************************************************************************/
function fb_InitImageEditor(imageToEditId, minResultWidth, minResultHeight,
	cropAspectRatioWidth, cropAspectRatioHeight, cropXFieldId, cropYFieldId,
	cropWidthFieldId, cropHeightFieldId, resizeWidthFieldId, maxResizeWidth,
	offsetX, offsetY, ieOffsetX, ieOffsetY, fixedCropWidth, fixedCropHeight)
{
	fb_OffsetX = parseInt(offsetX);
	fb_OffsetY = parseInt(offsetY);
	fb_IEOffsetX = parseInt(ieOffsetX);
	fb_IEOffsetY = parseInt(ieOffsetY);
	
	fb_FixedCropWidth = parseInt(fixedCropWidth);
	fb_FixedCropHeight = parseInt(fixedCropHeight);

	fb_ImageToEdit = document.getElementById(imageToEditId);
	fb_ImageToEdit.onmousedown = fb_ImageToEditMousedown;
	fb_ImageToEdit.onload = fb_ShowFixedCropBox; // This fires when the image is rotated and re-loads
	
	fb_MinResultWidth = minResultWidth;
	fb_MinResultHeight = minResultHeight;
	fb_MaxResizeWidth = maxResizeWidth;
	
	fb_CropAspectRatio.x = cropAspectRatioWidth;
	fb_CropAspectRatio.y = cropAspectRatioHeight;
	
	fb_CropXField = document.getElementById(cropXFieldId);
	fb_CropYField = document.getElementById(cropYFieldId);
	fb_CropWidthField = document.getElementById(cropWidthFieldId);
	fb_CropHeightField = document.getElementById(cropHeightFieldId);
	fb_ResizeWidthField = document.getElementById(resizeWidthFieldId);
	
	var resizeWidth = fb_ResizeWidthField.getAttribute("value");
	if (resizeWidth > 0)
		fb_InitImageWidth = parseInt(resizeWidth);
	
	fb_SetImageSize(fb_InitImageWidth);
	
	var imgCoords = fb_GetElementScreenCoordinates(fb_ImageToEdit);
	fb_ImageToEditLeft = imgCoords.x;
	fb_ImageToEditTop = imgCoords.y;
	
	fb_GetImageScrollOffsets();
	
	fb_InitToolbar();
	fb_InitCropBox();
	
	fb_ShowFixedCropBox();
}

function fb_ShowFixedCropBox()
{
	if (fb_FixedCropWidth > 0 && fb_FixedCropHeight > 0)
	{
		// Mimic starting a crop
		fb_GetImageScrollOffsets();
		fb_EnsureCropBox();
		fb_CropBox.style.display = '';
		
		// Center the crop box
		fb_CurrCropX = Math.floor((fb_ImageToEdit.offsetWidth - fb_FixedCropWidth) / 2);
		fb_CurrCropY = Math.floor((fb_ImageToEdit.offsetHeight - fb_FixedCropHeight) / 2);
		if (fb_CurrCropX < 0) fb_CurrCropX = 0;
		if (fb_CurrCropY < 0) fb_CurrCropY = 0;
		
		// Make sure crop box doesn't extend outside of the image
		if (fb_CurrCropX + fb_FixedCropWidth + 2 > fb_ImageToEdit.offsetWidth)
		{
			fb_CurrCropX = 0;
			fb_InitImageWidth = fb_FixedCropWidth + 2; // 2 for border
			fb_SetImageSize(fb_InitImageWidth);
		}
		if (fb_CurrCropY + fb_FixedCropHeight + 2 > fb_ImageToEdit.offsetHeight)
		{
			fb_CurrCropY = 0;
			fb_InitImageWidth = fb_ImageToEdit.offsetWidth * (fb_FixedCropHeight + 2) / fb_ImageToEdit.offsetHeight; // 2 for border
			fb_SetImageSize(fb_InitImageWidth);
		}
		
		// Set the dimensions and position of the crop box
		fb_CropBox.style.width = fb_FixedCropWidth + "px";
		fb_CropBox.style.height = fb_FixedCropHeight + "px";
		fb_CropBox.style.left = fb_CurrCropX + "px";
		fb_CropBox.style.top = fb_CurrCropY + "px";
		
		// Mimic finishing a crop
		fb_CropBox.style.cursor = "move";
		fb_CropBox.onmousedown = fb_BeginCropMove;
		fb_PersistCropValues();
		
		fb_CropBoxVisible = true;
		fb_CropMovePrevMode = fb_CurrMode;
		
		// Reset crop boundaries to reflect new image size
		fb_CropXMin = 0;
		fb_CropXMax = fb_CropXMin + fb_ImageToEdit.offsetWidth;
		fb_CropYMin = 0;
		fb_CropYMax = fb_CropYMin + fb_ImageToEdit.offsetHeight;
	}
}

function fb_ResetImageEditor()
{
	fb_ClearCropBox();
	fb_SetImageSize(fb_InitImageWidth);
}

function fb_GetEventScreenCoordinates(evt)
{
	var result = new Object();
	if (evt.pageX || evt.pageY) {
		result.x = evt.pageX;
		result.y = evt.pageY;
	}
	else if (evt.clientX || evt.clientY)
	{
		result.x = evt.clientX + document.body.scrollLeft;
		result.y = evt.clientY + document.body.scrollTop;
	}
	return result;
}

function fb_CancelEventPropagation(evt, preventDefault)
{
	evt.cancelBubble = true;
	if (evt.stopPropagation)
		evt.stopPropagation();
	if (preventDefault && evt.preventDefault)
		evt.preventDefault();
	return !preventDefault;
}

function fb_GetOffsetX()
{
	if (fb_UseIEBehavior)
		return fb_IEOffsetX;
	else
		return fb_OffsetX;
}

function fb_GetOffsetY()
{
	if (fb_UseIEBehavior)
		return fb_IEOffsetY;
	else
		return fb_OffsetY;
}

function fb_GetElementScreenCoordinates(elem)
{
	var result = new Object();
	result.x = elem.offsetLeft;
	result.y = elem.offsetTop;
	if (elem.offsetParent)
	{
		while (elem = elem.offsetParent)
		{
			result.x += elem.offsetLeft;
			result.y += elem.offsetTop;
		}
	}
	return result;
}

function fb_GetImageScrollOffsets()
{
	fb_ScrollLeftOffset = 0;
	fb_ScrollTopOffset = 0;
	var currParent = fb_ImageToEdit.offsetParent.offsetParent;
	while (currParent)
	{
		fb_ScrollLeftOffset += currParent.scrollLeft;
		fb_ScrollTopOffset += currParent.scrollTop;
		currParent = currParent.offsetParent;
	}
}

/******************************************************************************
 * fb_ImageToEdit Event Handlers
 ******************************************************************************/
function fb_ImageToEditMousedown(evt)
{
	if (!evt && window.event)
		evt = window.event;
	
	switch (fb_CurrMode)
	{
		case fb_EditorModes.Resize :
			fb_BeginResizeImage(evt);
			break;
		case fb_EditorModes.Crop :
			fb_BeginCropImage(evt);
			break;
	}
	
	return fb_CancelEventPropagation(evt, true);
}

/******************************************************************************
 * Toolbar Functions
 ******************************************************************************/
function fb_InitToolbar()
{
	fb_WireupToolbar();

	for (var i = 0; i < fb_ToolbarButtons.length; i++)
	{
		if (fb_GetToolbarCommandName(fb_ToolbarButtons[i]) == "Resize")
		{
			fb_SetActiveTool(fb_ToolbarButtons[i]);
			break;
		}
	}
}

function fb_WireupToolbar()
{
	var tbar = document.getElementById('ToolBar');
	var nodes = tbar.getElementsByTagName("LI");
	for (var i = 0; i < nodes.length; i++)
	{
		var currChild = nodes[i];
		if (!currChild.getAttribute("id"))
		{
			var imgElem = currChild.getElementsByTagName("IMG")[0];
			if (imgElem)
			{
				imgElem.onmouseover = new Function("fb_ToolbarImageMouseover(this);");
				imgElem.onmouseout = new Function("fb_ToolbarImageMouseout(this);");
			}
			else
			{
				currChild.onmouseover = new Function("fb_ToolbarButtonMouseover(this);");
				currChild.onmouseout = new Function("fb_ToolbarButtonMouseout(this);");
			}
			currChild.onclick = new Function("fb_SetActiveTool(this);");
			fb_ToolbarButtons[fb_ToolbarButtons.length] = currChild;
		}
	}
}

function fb_GetToolbarCommandName(buttonElement)
{
	return buttonElement.getAttribute("title");
}

function fb_ToolbarButtonMouseover(buttonElement)
{
	if (!buttonElement.className)
		buttonElement.className = "ToolbarButtonHover";
}

function fb_ToolbarButtonMouseout(buttonElement)
{
	if (buttonElement.className == "ToolbarButtonHover")
		buttonElement.className = null;
}

function fb_ToolbarImageMouseover(imgElement)
{
	var buttonElement = imgElement.parentNode;
	if (!buttonElement.className)
		buttonElement.className = "ToolbarButtonHover";
}

function fb_ToolbarImageMouseout(imgElement)
{
	var buttonElement = imgElement.parentNode;
	if (buttonElement.className == "ToolbarButtonHover")
		buttonElement.className = null;
}

function fb_SetResizeActiveTool()
{
	var elem = null;
	for (var i = 0; i < fb_ToolbarButtons.length; i++)
	{
		if (fb_GetToolbarCommandName(fb_ToolbarButtons[i]) == "Resize")
		{
			elem = fb_ToolbarButtons[i];
			break;
		}
	}
	if (elem)
		fb_SetActiveTool(elem);
}

function fb_SetActiveTool(buttonElement)
{	
	switch (fb_GetToolbarCommandName(buttonElement))
	{
		case "Reset" :
			buttonElement.className = "ToolbarButtonDown";
			fb_ResetImageEditor();
			buttonElement.className = null;
			break;
		case "Resize" :
			fb_ClearSelectedToolbarButton();
			buttonElement.className = "ToolbarButtonDown";
			fb_CurrMode = fb_EditorModes.Resize;
			fb_ImageToEdit.style.cursor = "se-resize";
			break;
		case "Crop" :
			fb_ClearSelectedToolbarButton();
			buttonElement.className = "ToolbarButtonDown";
			fb_CurrMode = fb_EditorModes.Crop;
			fb_ImageToEdit.style.cursor = "";
			break;
		default :
			fb_ClearSelectedToolbarButton();
			fb_CurrMode = fb_EditorModes.NotSet;
			fb_ImageToEdit.style.cursor = "";			
			break;
	}
}

function fb_ClearSelectedToolbarButton()
{
	for (var i = 0; i < fb_ToolbarButtons.length; i++)
		fb_ToolbarButtons[i].className = null;
}

function fb_SetToolbarDimensionDisplay(width, height)
{
	var widthLabel = document.getElementById('widthLabel');
	widthLabel.innerHTML = width + "px";
	
	var heightLabel = document.getElementById('heightLabel');
	heightLabel.innerHTML = height + "px";
}

/******************************************************************************
 * Resize Functions
 ******************************************************************************/
var fb_InitResizeCoords;
var fb_InResize = false;
var fb_InitResizeWidth;

function fb_BeginResizeImage(evt)
{
	fb_InitResizeCoords = fb_GetEventScreenCoordinates(evt);
	fb_InResize = true;
	fb_InitResizeWidth = fb_ImageToEdit.offsetWidth;
	//fb_ClearCropBox();
}

function fb_FinishResizeImage(evt)
{
	fb_InResize = false;
	
	if (fb_CropBox && fb_CropBoxVisible)
	{
		// Save changed crop values
		fb_PersistCropValues();
		
		// Reset crop boundaries to reflect new image size
		fb_CropXMin = 0;
		fb_CropXMax = fb_CropXMin + fb_ImageToEdit.offsetWidth;
		fb_CropYMin = 0;
		fb_CropYMax = fb_CropYMin + fb_ImageToEdit.offsetHeight;
	}
}

function fb_PerformIncrementalResize(evt)
{
	if (fb_InResize)
	{
		var currCoords = fb_GetEventScreenCoordinates(evt);
		fb_SetImageSize(fb_InitResizeWidth + (currCoords.x - fb_InitResizeCoords.x));
	}
}

function fb_SetImageSize(width)
{
	var max = fb_MaxResizeWidth;
	var min = fb_MinResultWidth;
	
	if (fb_CropBox && fb_CropBoxVisible)
	{
		if (min < fb_CropBox.offsetWidth)
			min = fb_CropBox.offsetWidth; // Ensures that the image can't be resized smaller than the crop box
			
		var testWidth = fb_CropBox.offsetHeight * fb_ImageToEdit.offsetWidth / fb_ImageToEdit.offsetHeight;
		if (min < testWidth)
			min = testWidth;
	}
	
	if (max > 0 && width > max)
		width = max;
	
	if (width >= min)
		fb_ImageToEdit.style.width = width + "px";
	else
		fb_ImageToEdit.style.width = min + "px";
	fb_ImageToEdit.style.height = "";
	
	if (!fb_CropBox || !fb_CropBoxVisible)
		fb_SetToolbarDimensionDisplay(fb_ImageToEdit.offsetWidth, fb_ImageToEdit.offsetHeight);
	
	if (fb_ResizeWidthField)
		fb_ResizeWidthField.setAttribute("value", fb_ImageToEdit.offsetWidth);
	
	// Make sure crop box is not outside of image dimensions	
	if (fb_CropBox && fb_CropBoxVisible)
	{
		var deltaX = fb_ImageToEdit.offsetWidth - fb_CropBox.offsetWidth - fb_CurrCropX;
		var deltaY = fb_ImageToEdit.offsetHeight - fb_CropBox.offsetHeight - fb_CurrCropY;
		if (deltaX < 0 || deltaY < 0)
		{
			var left = fb_CurrCropX + ((deltaX < 0) ? deltaX : 0);
			var top = fb_CurrCropY + ((deltaY < 0) ? deltaY : 0);
			
			if (left < fb_CropXMin)
				left = fb_CropXMin;
			else if (left + fb_CropBox.offsetWidth > fb_CropXMax)
				left = fb_CropXMax - fb_CropBox.offsetWidth;

			if (top < fb_CropYMin)
				top = fb_CropYMin;
			else if (top + fb_CropBox.offsetHeight > fb_CropYMax)
				top = fb_CropYMax - fb_CropBox.offsetHeight;

			fb_CurrCropX = left;
			fb_CurrCropY = top;
			fb_CropBox.style.left = left + "px";
			fb_CropBox.style.top = top + "px";
		}
	}
}

/******************************************************************************
 * Crop Functions
 ******************************************************************************/
var fb_CropBox = null;
var fb_CropBoxVisible = false;
var fb_InCrop = false;
var fb_InitCropCoords;
var fb_CropBoxBorderOffset = 2;
var fb_CropXMin;
var fb_CropXMax;
var fb_CropYMin;
var fb_CropYMax;
var fb_CurrCropX;
var fb_CurrCropY;

function fb_EnsureCropBox()
{
	if (fb_CropBox == null)
	{
		fb_CropBox = document.createElement('div');
		fb_CropBox.className = 'CropBox';
		fb_ImageToEdit.offsetParent.appendChild(fb_CropBox);
	}
} 

function fb_BeginCropImage(evt)
{
	fb_GetImageScrollOffsets();
	fb_EnsureCropBox();
	fb_InitCropCoords = fb_GetEventScreenCoordinates(evt);
	fb_InitCropCoords.x = fb_InitCropCoords.x - fb_ImageToEditLeft + fb_GetOffsetX() + fb_ScrollLeftOffset;
	fb_InitCropCoords.y = fb_InitCropCoords.y - fb_ImageToEditTop + fb_GetOffsetY() + fb_ScrollTopOffset;
	
	fb_CurrCropX = fb_InitCropCoords.x;
	fb_CurrCropY = fb_InitCropCoords.y;

	fb_CropBox.style.left = fb_InitCropCoords.x + "px";
	fb_CropBox.style.top = fb_InitCropCoords.y + "px";
	fb_CropBox.style.width = "1px";
	fb_CropBox.style.height = "1px";
	fb_CropBox.style.cursor = '';
	fb_CropBox.style.display = '';
	fb_CropBox.onmousedown = null;
	fb_InCrop = true;
	fb_CropBoxVisible = true;
	
	fb_CropXMin = 0;
	fb_CropXMax = fb_CropXMin + fb_ImageToEdit.offsetWidth;
	fb_CropYMin = 0;
	fb_CropYMax = fb_CropYMin + fb_ImageToEdit.offsetHeight;
}

function fb_FinishCropImage(evt)
{
	fb_InCrop = false;
	if (fb_CropBox.offsetWidth <= 4 || fb_CropBox.offsetHeight <= 4)
		fb_ClearCropBox();
	else
	{
		fb_CropBox.style.cursor = "move";
		fb_CropBox.onmousedown = fb_BeginCropMove;
		fb_PersistCropValues();
	}
}

function fb_PersistCropValues()
{
	if (fb_CropXField)
		fb_CropXField.setAttribute("value", fb_CurrCropX);
	if (fb_CropYField)
		fb_CropYField.setAttribute("value", fb_CurrCropY);
	if (fb_CropWidthField)
		fb_CropWidthField.setAttribute("value", fb_CropBox.offsetWidth - fb_CropBoxBorderOffset);
	if (fb_CropHeightField)
		fb_CropHeightField.setAttribute("value", fb_CropBox.offsetHeight - fb_CropBoxBorderOffset);
}

function fb_PerformIncrementalCrop(evt)
{
	if (fb_InCrop)
	{	
		var currCoords = fb_GetEventScreenCoordinates(evt);
		currCoords.x = currCoords.x - fb_ImageToEditLeft + fb_GetOffsetX() + fb_ScrollLeftOffset;
		currCoords.y = currCoords.y - fb_ImageToEditTop + fb_GetOffsetY() + fb_ScrollTopOffset;
		
		var deltaX = currCoords.x - fb_InitCropCoords.x;
		var deltaY = currCoords.y - fb_InitCropCoords.y;
		var width = Math.abs(deltaX);
		var height = Math.abs(deltaY);
		var left = fb_InitCropCoords.x;
		var top = fb_InitCropCoords.y;
		
		if (deltaX < 0)
			left = currCoords.x;
		if (deltaY < 0)
			top = currCoords.y;
		
		fb_CurrCropX = left;
		fb_CurrCropY = top;
		
		if (fb_CropAspectRatio.x && fb_CropAspectRatio.y)
		{
			if (deltaX >= 0 && deltaY >= 0)
			{
				if (left + width > fb_CropXMax - fb_CropBoxBorderOffset)
					width = fb_CropXMax - left - fb_CropBoxBorderOffset;
				height = fb_CropAspectRatio.y * width / fb_CropAspectRatio.x;
				if (top + height > fb_CropYMax - fb_CropBoxBorderOffset)
				{
					height = fb_CropYMax - top - fb_CropBoxBorderOffset;
					width = fb_CropAspectRatio.x * height / fb_CropAspectRatio.y;
				}
				width = Math.floor(width);
				height = Math.floor(height);
				
				fb_CropBox.style.left = left + "px";
				fb_CropBox.style.width = width + "px";
				fb_CropBox.style.top = top + "px";
				fb_CropBox.style.height = height + "px";
				fb_SetToolbarDimensionDisplay(width, height);
			}
		}
		else
		{	
			if (currCoords.x >= fb_CropXMin && currCoords.x <= fb_CropXMax - fb_CropBoxBorderOffset)	
			{
				fb_CropBox.style.left = left + "px";
				fb_CropBox.style.width = width + "px";
			}
			else
				width = fb_CropBox.offsetWidth;
			
			if (currCoords.y >= fb_CropYMin && currCoords.y <= fb_CropYMax - fb_CropBoxBorderOffset)
			{
				fb_CropBox.style.top = top + "px";
				fb_CropBox.style.height = height + "px";
			}
			else
				height = fb_CropBox.offsetHeight;
			fb_SetToolbarDimensionDisplay(width, height);
		}
	}
}

function fb_ClearCropBox()
{
	if (fb_CropBox)
		fb_CropBox.style.display = 'none';
	
	if (fb_CropXField)
		fb_CropXField.setAttribute("value", "0");
	if (fb_CropYField)
		fb_CropYField.setAttribute("value", "0");
	if (fb_CropWidthField)
		fb_CropWidthField.setAttribute("value", "0");
	if (fb_CropHeightField)
		fb_CropHeightField.setAttribute("value", "0");
		
	fb_CropBoxVisible = false;
}

function fb_InitCropBox()
{
	var left = fb_CropXField.getAttribute("value");
	var top = fb_CropYField.getAttribute("value");
	var width = fb_CropWidthField.getAttribute("value");
	var height = fb_CropHeightField.getAttribute("value");
	
	if (left && top && width && width != "0" && height && height != "0")
	{
		left = parseInt(left);
		top = parseInt(top);
		width = parseInt(width);
		height = parseInt(height);
		
		fb_CurrCropX = left;
		fb_CurrCropY = top;
		
		fb_EnsureCropBox();
		
		fb_CropXMin = 0;
		fb_CropXMax = fb_CropXMin + fb_ImageToEdit.offsetWidth;
		fb_CropYMin = 0;
		fb_CropYMax = fb_CropYMin + fb_ImageToEdit.offsetHeight;
		
		fb_CropBox.style.left = left + "px";
		fb_CropBox.style.top = top + "px";
		fb_CropBox.style.width = width + "px";
		fb_CropBox.style.height = height + "px";
		fb_CropBox.style.display = '';
		fb_CropBox.style.cursor = "move";
		fb_CropBox.onmousedown = fb_BeginCropMove;
		
		fb_SetToolbarDimensionDisplay(width, height);
	}
}

/******************************************************************************
 * Crop Move Functions
 ******************************************************************************/
var fb_InitCropMoveCoords = null;
var fb_InitCropMovePosition = null;
var fb_InCropMove = false;
var fb_CropMovePrevMode = null;
 
function fb_BeginCropMove(evt)
{
	if (!evt && window.event)
		evt = window.event;
	
	fb_CropMovePrevMode = fb_CurrMode;
	fb_CurrMode = fb_EditorModes.CropMove;
	
	fb_InitCropMoveCoords = fb_GetEventScreenCoordinates(evt);
	fb_InitCropMoveCoords.x -= fb_ImageToEditLeft;
	fb_InitCropMoveCoords.y -= fb_ImageToEditTop;
	
	fb_InitCropMovePosition = new Object();
	fb_InitCropMovePosition.x = fb_CurrCropX;
	fb_InitCropMovePosition.y = fb_CurrCropY;
	
	fb_InCropMove = true;
}

function fb_FinishCropMove(evt)
{
	fb_CurrMode = fb_CropMovePrevMode;
	fb_InCropMove = false;
	fb_PersistCropValues();
}

function fb_PerformIncrementalCropMove(evt)
{
	if (fb_InCropMove)
	{
		var currCoords = fb_GetEventScreenCoordinates(evt);
		currCoords.x -= fb_ImageToEditLeft;
		currCoords.y -= fb_ImageToEditTop;
		
		var deltaX = currCoords.x - fb_InitCropMoveCoords.x;
		var deltaY = currCoords.y - fb_InitCropMoveCoords.y;
		
		var left = fb_InitCropMovePosition.x + deltaX;
		var top = fb_InitCropMovePosition.y + deltaY;
		
		if (left < fb_CropXMin)
			left = fb_CropXMin;
		else if (left + fb_CropBox.offsetWidth > fb_CropXMax)
			left = fb_CropXMax - fb_CropBox.offsetWidth;
			
		if (top < fb_CropYMin)
			top = fb_CropYMin;
		else if (top + fb_CropBox.offsetHeight > fb_CropYMax)
			top = fb_CropYMax - fb_CropBox.offsetHeight;
		
		fb_CurrCropX = left;
		fb_CurrCropY = top;
		fb_CropBox.style.left = left + "px";
		fb_CropBox.style.top = top + "px";
	}
}

/******************************************************************************
 * Document Event Handlers
 ******************************************************************************/
 function fb_ImageEditorMouseMove(evt)
 {
	if (!evt && window.event)
		evt = window.event;
	
	switch (fb_CurrMode)
	{
		case fb_EditorModes.Resize :
			fb_PerformIncrementalResize(evt);
			break;
		case fb_EditorModes.Crop :
			fb_PerformIncrementalCrop(evt);
			break;
		case fb_EditorModes.CropMove :
			fb_PerformIncrementalCropMove(evt);
			break;
	}
	
	if (fb_UseIEBehavior)
		return fb_CancelEventPropagation(evt, true);
	else
		return true;
 }
 document.onmousemove = fb_ImageEditorMouseMove;
 
 function fb_ImageEditorMouseUp(evt)
{
	if (!evt && window.event)
		evt = window.event;
	
	switch (fb_CurrMode)
	{
		case fb_EditorModes.Resize :
			fb_FinishResizeImage(evt);
			break;
		case fb_EditorModes.Crop :
			fb_FinishCropImage(evt);
			break;
		case fb_EditorModes.CropMove :
			fb_FinishCropMove(evt);
			break;
	}
	
	return fb_CancelEventPropagation(evt, true);
}
document.onmouseup = fb_ImageEditorMouseUp;

function fb_ImageEditorKeyDown(evt)
{
	if (!evt && window.event)
		evt = window.event;
		
	fb_KeyHeld = (evt.keyCode) ? evt.keyCode : ((evt.which) ? evt.which : null);
	
	if (fb_KeyHeld == fb_KeyCodes.Shift && !fb_CropAspectRatio.x && !fb_CropAspectRatio.y)
	{
		fb_IsCropAspectRatioSetByShift = true;
		fb_CropAspectRatio.x = 1;
		fb_CropAspectRatio.y = 1;
	}
}
document.onkeydown = fb_ImageEditorKeyDown;

function fb_ImageEditorKeyUp(evt)
{
	if (fb_IsCropAspectRatioSetByShift)
	{
		fb_IsCropAspectRatioSetByShift = false;
		fb_CropAspectRatio.x = 0;
		fb_CropAspectRatio.y = 0;
	}
	fb_KeyHeld = null;
}
document.onkeyup = fb_ImageEditorKeyUp;

var fb_IsLoaded = false;
function fb_RegisterOnLoadHandler(handler)
{   
	if (fb_IsLoaded)
		handler();
	else
	{
		var oldFunction = window.onload;
		if (typeof oldFunction != 'function')
		{
			window.onload = handler;
		}
		else
		{
			window.onload = function()
			{
				oldFunction();
				handler();
			};
		}
	}
}
fb_RegisterOnLoadHandler(function() { fb_IsLoaded = true; });
