//Create a new plugin class
					tinymce.create('tinymce.plugins.CWTextStylePlugin', {
					    init : function(ed, url) {
							
							// Add a node change handler, selects the button in the UI when a image is selected
							ed.onNodeChange.add(function(ed, cm, n) {
                                if(tinyMCE.activeEditor.controlManager.get('cwtextstyleslist')) {
								    tinyMCE.activeEditor.controlManager.get('cwtextstyleslist').selectByIndex(-1);
                                }
								//cm.setActive('cwtextstyle', n.nodeName == 'IMG');
							});
						},
						createControl : function(n, cm) {
							if(n == 'cwtextstyle') {
								return cm.createListBox('cwtextstyleslist', {
				                     title : 'Tekst stijl',
				                     onselect : function(v) {
										if(tinyMCE.activeEditor.selection && tinyMCE.activeEditor.selection.getContent()) {
											var selection = tinyMCE.activeEditor.selection.getContent();

											rwTinyMceInsertRawHtml(tinyMCE.activeEditor.id, '<span class="cwtextstyle '+v+'"><span class="cwtextstylestart">['+v+']</span>'+selection+'<span class="cwtextstyleend">[/'+v+']</span></span>');
											
											tinyMCE.activeEditor.controlManager.get('cwtextstyleslist').selectByIndex(-1);
											
										}
				                     }
				                });
							} else {
								return null;
							}
						}
					});
					
					// Register plugin with a short name
					tinymce.PluginManager.add('cwtextstyle', tinymce.plugins.CWTextStylePlugin);

var imagePDFSelectedImageId;
var contentSourceEditedItem;
var visualMode = false;
var suspendTextChecks = false;

/**
* This function is executed once a image is picked in the content source browser.
*/
function imagePDFContentSourceSelectedHandler(selectedItem) {

	var imagePDFInputHidden = bb.document.getElementById(imagePDFSelectedBlockId);
	var imagePDFInputIdHidden = bb.document.getElementById(imagePDFSelectedBlockId+'!contentid');
	var imagePDFInputMimeTypeHidden = bb.document.getElementById(imagePDFSelectedBlockId+'!mimeType');
	var imagePDFInputPreviewHidden = bb.document.getElementById(imagePDFSelectedBlockId+'!preview');
	
	var selectedImage = bb.document.getElementById('selectedImage_'+imagePDFSelectedBlockId);
	var selectedImageWarnings = bb.document.getElementById('selectedImage_'+imagePDFSelectedBlockId+'_warnings');
	var buttonRemoveImage = bb.document.getElementById('buttonRemoveImage_'+imagePDFSelectedBlockId);

	imagePDFInputHidden.viewNode.value = selectedItem.content;
	imagePDFInputIdHidden.viewNode.value = selectedItem.id;
	imagePDFInputMimeTypeHidden.viewNode.value = selectedItem.mimeType;
	imagePDFInputPreviewHidden.viewNode.value = selectedItem.preview;
	
	selectedImage.viewNode.src = selectedItem.preview+'/width/200/height/200';
	selectedImage.viewNode.style.display = 'block';
	
	imagePDFInputHidden.viewNode.value = selectedItem.content;
	imagePDFInputIdHidden.viewNode.value = selectedItem.id;
	imagePDFInputMimeTypeHidden.viewNode.value = selectedItem.mimeType;
	imagePDFInputPreviewHidden.viewNode.value = selectedItem.preview;
	
	selectedImage.viewNode.style.display = 'block';

	Ext.get(selectedImage.viewNode).on('load', function(){
		imagePDFInitCropping(imagePDFSelectedBlockId, contentSourceDesiredWidth, contentSourceDesiredHeight, true);
	}, selectedImage.viewNode, {single: true});
	
	selectedImage.viewNode.src = selectedItem.preview+'/width/150/height/200';
	
	for(i in selectedItem.warnings) {
        if(typeof selectedItem.warnings[i] == 'function') continue;

		var divWarning = bb.document.createElement('div');
		divWarning.viewNode.innerHTML = '<img style="margin-bottom: -3px" src="/images/icons/error.png" width="13" height="13"/> '+selectedItem.warnings[i];
		divWarning.setAttribute('class', 'warning');
		
		selectedImageWarnings.appendChild(divWarning);
	}
	
	if(buttonRemoveImage) {
		buttonRemoveImage.setAttribute('visibility', 'visible');
	}
	
	//inputChanged(imagePDFInputHidden.getAttribute('id'));
}

// array of values of the inputs
var inputValues = new Array();

// timeouts after which the fireEvent(..., change) is called
var inputChangedTimeout = new Array();

// the number of blocks that are currently being tested (used by waitForInputChangedReady)
var countBlockBusyTesting = 0;

// input id of the block currently being text checked
var currentlyTestingBlockInputId = '';

var testTextBlockHttpRequest = null;

// array of text inputs to check
var textInputs = new Array();

function trimContent(value) {

	if(value == undefined) return '';
	
    value = value.replace(/^\s+/,'');
    value = value.replace(/\s+$/,'');
	
	var euroUnicode = 8364;
	var euro = String.fromCharCode(euroUnicode)		
	
	value = value.replace(euro, '');
	
	if(value.match(/^<br>$/i)) {
		value = '';
	}

	if(value.match(/^<br>$/i)) {
		value = '';
	}
	
	if(value == '<br mce_bogus="1"/>') {
		value = '';
	}
	
	return value;
}

/**
*  Register a text field. After registration it is checked with a certain interval for input changed.
*/
function registerTextField(input) {

	var value = input.getProperty('value');
	
	if(!value || value == undefined) {
		window.setTimeout(function(){registerTextField(input)}, 50);
	} else {
		
		if(value == '___EMPTY___') {
			input.setProperty('value', '');
			value = '';
		}
		
		inputValues[input.getAttribute('id')] = value;

		textInputs.push(input.getAttribute('id'));
	}
}

/**
* For every input, see if the content is changed since the last check.
*/ 
function checkTextInputChanged() {

	for(inputIdx=0; inputIdx < textInputs.length; inputIdx++) {
	
        if(suspendTextChecks) continue;

		var input = bb.document.getElementById(textInputs[inputIdx]);
		
		if(!input) {
			textInputs.splice(inputIdx, 1);
			inputIdx--;
			break;
		}
		
		if(input.getAttribute('id').indexOf('|') == -1) {
			continue;
		}
		
		// the first time, put the initial data in the array
		if(inputValues[input.getAttribute('id')] == null) {
			inputValues[input.getAttribute('id')] = input.getProperty('value');
		}
		
		// if content changed
		if(input.getProperty('value') != inputValues[input.getAttribute('id')]) {
			
			bb.document.getElementById(input.getAttribute('id')+'_iconOK').viewNode.style.display = 'none';
			bb.document.getElementById(input.getAttribute('id')+'_iconWarning').viewNode.style.display = 'none';
			bb.document.getElementById(input.getAttribute('id')+'_iconProcessing').viewNode.style.display = 'none';
		
			// clear a possible timeout.
			if(inputChangedTimeout[input.getAttribute('id')]) {
			
				window.clearTimeout(inputChangedTimeout[input.getAttribute('id')]);
				inputChangedTimeout[input.getAttribute('id')] = 0;
			}

			// set a timeout after which the fireEvent(...., 'change') must be called for the input.
			inputChangedTimeout[input.getAttribute('id')] = window.setTimeout("inputChanged('"+input.getAttribute('id')+"')", 1500);
		}

		inputValues[input.getAttribute('id')] = input.getProperty('value');
	}
}

/**
* Check the content of the input.
*/
function inputChanged(inputId, fieldName, noUpdateSiblings) {
	
	if(inputId.indexOf('!') != -1) {
		return;
	}
	
	if(!fieldName) {
		fieldName = inputId;
	}

	var input = bb.document.getElementById(inputId);
	
	if(!noUpdateSiblings) {
	
		// now put the content into fields with the same name within a subtemplates section
		var xPathGetParentSubtemplate = "ancestor::div[@class='block-subtemplates'][1]";
		var xPathGetSiblings = "descendant::*[@name = '"+input.getAttribute('name')+"' and @id!='"+inputId+"']";
		
		var subTemplateNameSiblings = bb.evaluateSmart("["+xPathGetParentSubtemplate+'/'+xPathGetSiblings+"]", input);
		
		for(subTemplateNameSiblingsIdx=0; subTemplateNameSiblingsIdx < subTemplateNameSiblings.length; subTemplateNameSiblingsIdx++) {
	
			var siblingInput = subTemplateNameSiblings[subTemplateNameSiblingsIdx];
			
			siblingInput.setProperty('value', input.getProperty('value'));
			inputValues[siblingInputId] = input.getProperty('value');
			
			inputChanged(siblingInputId, siblingInputId, true);
		}
	}

	// set the POST data
	if(input.getAttribute('type') == 'checkbox' && !input.getProperty('checked')) {
		var postData = '';
	}
	else {
		var postData = input.getProperty('value');
	}

 	// get the label and reset the (red) color
	var fieldLabel = bb.document.getElementById(inputId+'_label');
	
	if(fieldLabel && trimContent(input.getProperty('value')) != '') {
		fieldLabel.viewNode.style.color == '';
	}
	
	// if the input is a text box, do a text check
	//if(input.getAttribute('type') == 'text' || input.getProperty('tagName') == 'textarea' || input.getProperty('tagName') == 'rw:tinymce' ) {

		inputChangedTimeout[inputId] = 0;
			
		if(input.getAttribute('type') == 'text' || input.getProperty('tagName') == 'textarea' || input.getProperty('tagName') == 'rw:tinymce' ) {
			// repeat this 4 lines here, because of direct calls to inputChanged
			inputValues[input.getAttribute('id')] = input.getProperty('value');
			bb.document.getElementById(inputId+'_iconOK').viewNode.style.display = 'none';
			bb.document.getElementById(inputId+'_iconWarning').viewNode.style.display = 'none';
			bb.document.getElementById(inputId+'_iconProcessing').viewNode.style.display = (trimContent(input.getProperty('value')) != '' ? 'inline' : 'none');
		}

		countBlockBusyTesting++;
		
		testTextBlock(inputId, fieldName, postData);
	/*}
	// otherwise only save the content
	else {
		
		bb.command.load('/print/contents/saveblock/id/'+input.getAttribute('id')+'/name/'+fieldName, 'POST', postData);
		
		if(visualMode) {
			validatePage(bb.evaluateSmart('ancestor::b:tab', input, input));
		}
	}*/
	
}

/**
 * Test a text block
 * 
 * @param input
 * @param fieldName
 * @param postData
 * @param inputId
 * @return
 */
function testTextBlock(inputId, fieldName, postData) {
	
	var fieldNameSplit = fieldName.split('|');
	var flashPreview = getFlashMovieObject('visual-preview-swf-'+fieldNameSplit[0]);
	var flashVariablePrefix = 'block_'+fieldName.replace(/\|/g, '__').replace(/-/g, '_');
	var flashVariable = flashVariablePrefix+'_isloading'
	flashPreview.SetVariable('/:'+flashVariable, 'true');
	
	// if the block if currently being tested, abort the testing
	if(currentlyTestingBlockInputId == inputId) {
		testTextBlockHttpRequest.abort();
		currentlyTestingBlockInputId = '';
		countBlockBusyTesting--;
	}
	
	if(currentlyTestingBlockInputId != '') {
		window.setTimeout(function(){testTextBlock(inputId, fieldName, postData)}, 50);
	}
	else {
		currentlyTestingBlockInputId = inputId;
		var fnReady = function(){countBlockBusyTesting--;currentlyTestingBlockInputId='';testTextBlockHttpRequest=null};
		
		var inputHiddenId = bb.document.getElementById(inputId+'!contentid');
		var inputHiddenMimeType = bb.document.getElementById(inputId+'!mimeType');
		var inputHiddenPreview = bb.document.getElementById(inputId+'!preview');
		var inputHiddenBlockstroke = bb.document.getElementById(inputId+'!blockstroke');
		var inputCropLLX = bb.document.getElementById(inputId+'!cropllx');
		var inputCropLLY = bb.document.getElementById(inputId+'!croplly');
		var inputCropURX = bb.document.getElementById(inputId+'!cropurx');
		var inputCropURY = bb.document.getElementById(inputId+'!cropury');
		
		var inputIcons = bb.document.getElementById(inputId+'_icons');
		
		var loadTarget = null;
		
		if(inputIcons) {
			loadTarget = bb.evaluateSmart('b:xml|b:balloon', inputIcons, inputIcons);
		}
		
		if(!loadTarget) {
			loadTarget = inputHiddenId ? inputHiddenId : inputHiddenBlockstroke;
			loadMode = 'appendChild';
		} else {
			loadMode = 'replace';
		}
		
		testTextBlockHttpRequest = bb.command.load('/print/contents/testtextblock/id/'+inputId+'/name/'+fieldName+(inputHiddenId ? '/contentid/'+inputHiddenId.viewNode.value : '')+(inputHiddenMimeType ? '/mimeType/'+Base64.encode(inputHiddenMimeType.viewNode.value) : '')+(inputHiddenPreview ? '/preview/'+Base64.encode(inputHiddenPreview.viewNode.value) : '')+(inputHiddenBlockstroke ? '/blockstroke/'+(inputHiddenBlockstroke.viewNode.checked ? 'y' : 'n') : '')+'/flashvarprefix/'+flashVariablePrefix+(inputCropLLX ? '/cropllx/'+inputCropLLX.viewNode.value+'/croplly/'+inputCropLLY.viewNode.value+'/cropurx/'+inputCropURX.viewNode.value+'/cropury/'+inputCropURY.viewNode.value : ''), 'POST', postData, null, loadTarget, loadMode, fnReady);
	}
}


/**
* Update the status of the 
*/
function updateTextStatus(blockId, warningMessage, lastmark) {

    suspendTextChecks = true;

	var block = bb.document.getElementById(blockId);
	
	if(block) {
		if(bb.document.getElementById(blockId+'_iconProcessing')) {
			bb.document.getElementById(blockId+'_iconProcessing').viewNode.style.display = 'none';
			bb.document.getElementById(blockId+'_iconOK').viewNode.style.display = (warningMessage == '' && trimContent(block.getProperty('value')) != '' ? 'inline' : 'none');
			bb.document.getElementById(blockId+'_iconWarning').viewNode.title = warningMessage;
			bb.document.getElementById(blockId+'_iconWarning').viewNode.style.display = (warningMessage == '' ? 'none' : 'inline');
		}
	
		if(visualMode) {
			validatePage(bb.evaluateSmart('ancestor::b:window', block, block));
		}

        if(lastmark) {

            if(block.getProperty('tagName') == 'rw:tinymce') {
            
                var tinyEditor = tinyMCE.get(blockId);

                var content = tinyEditor.getContent();

                var filledContent = content.substring(0, Number(lastmark)+1);
                var notFilledContent = content.substring(Number(lastmark)+1);

                tinyEditor.setContent(filledContent+'<span id="_startsel"/>&nbsp;</span>'+notFilledContent+'<span id="_endsel">&nbsp;</span>');

                var bookmark = tinyEditor.selection.getBookmark();

                var startSel = tinyEditor.getDoc().getElementById('_startsel');
                var endSel = tinyEditor.getDoc().getElementById('_endsel');

                var rng = tinyEditor.selection.getRng();

                if(bb.browser.ie) {
                    
                    rng.moveToElementText(startSel);
                    var rngStart = rng.duplicate();
                    rng.moveToElementText(endSel);
                    var rngEnd = rng.duplicate();

                    rng.setEndPoint('StartToEnd', rngEnd);
                    rng.setEndPoint('EndToStart', rngStart);
                    rng.select();
                    rng.scrollIntoView();

                } else {
                    rng.setStart(startSel, 0);
                    rng.setEnd(endSel, 0);
                }

                startSel.parentNode.removeChild(startSel);
                endSel.parentNode.removeChild(endSel);
                inputValues[blockId] = tinyEditor.getContent();
            } else if(block.getAttribute('type') != 'hidden') {
            
                if(bb.browser.ie) {
                    var acRange = block.viewNode.createTextRange();
                    acRange.moveStart("character", Number(lastmark));
                    acRange.moveEnd("character", block.viewNode.value.length);
                    acRange.select();
                    acRange.scrollIntoView();

                } else {
                    block.viewNode.selectionStart = Number(lastmark);
                    block.viewNode.selectionEnd = block.viewNode.value.length;
                    block.viewNode.scrollTop = 999;
                    block.viewNode.scrollLeft = 999;
                }
            }
        }
	}

    suspendTextChecks = false;
}

/**
* Wait until all input changed timeouts have exceeded, and all text blocks are tested 
* before executing the function (onReadyFunction). Optionally show a loading message.
*/
function waitForInputChangedReady(onReadyFunction, objLoadingMessage, maxWait) {

	var stopWaiting = false;
	
	if(maxWait) {
		maxWait -= 30;
		if(maxWait <= 0) stopWaiting = true;
	}
	
	if(!stopWaiting) {
		for(inputChangedTimeoutIdx in inputChangedTimeout) {
            if(typeof inputChangedTimeout[inputChangedTimeoutIdx] == 'function') continue;
		
			if(inputChangedTimeout[inputChangedTimeoutIdx] || countBlockBusyTesting > 0) {
				if(objLoadingMessage) {
					objLoadingMessage.show();
				}
				window.setTimeout(function(){waitForInputChangedReady(onReadyFunction, objLoadingMessage, maxWait)}, 30);
				return;
			}
		}
	}
	
	if(objLoadingMessage) {
		objLoadingMessage.hide();
	}
	
	window.setTimeout(onReadyFunction, 10);
}

/**
* Go to finish controller
*/
function gotoFinish() {

	bb.command.load('/print/contents/finish', 'POST', '', null, bb.document.getElementById('container'), 'appendChild');
}

/**
* Validates a form in the print module
*/
function validatePrintForm(form, highlightInvalid) {

	//trimRichTextEditors();
	
	var formElements = form.getProperty('elements');
	var tinyMces = bb.evaluate('descendant::rw:tinymce', form.modelNode, form.modelNode);

	var allElements = new Array();
	
	for(i in tinyMces) {
        if(typeof tinyMces[i] == 'function') continue;
		var tinyMce = bb.getControllerFromModel(tinyMces[i]);
		allElements.push(tinyMce);
	}

	for(i in formElements) {
        if(typeof formElements[i] == 'function') continue;
		allElements.push(formElements[i]);
	}
	
	var formIsValid = true;
	var formWarning = false;
	
	for(formEleIdx in allElements) {
        if(typeof allElements[formEleIdx] == 'function') continue;

		var fieldIsValid = validateFormField(form, allElements[formEleIdx], highlightInvalid, true);
		
		formIsValid = formIsValid && fieldIsValid;
	}
	
	if(formIsValid && formWarning) {
		return 'warning';
	}
	else {
		return formIsValid;
	}
}


function validateFormField(form, formEle, highlightInvalid, checkRadioSiblings) {

	if(!formEle.getAttribute('bf:required') || formEle.getAttribute('bf:required') == 'false') {
		return true;
	}

	var fieldLabel = bb.document.getElementById(formEle.getAttribute('id')+'_label');
	
	var iconWarning = bb.document.getElementById(formEle.getAttribute('id')+'_iconWarning');

	if(iconWarning && iconWarning.viewNode.style.display != 'none') {
		formWarning = true;
	}

	var blockSubtemplate = bb.evaluateSmart("ancestor::div[@class='block_subtemplate']", formEle);
	
	var euroUnicode = 8364;
	var euro = String.fromCharCode(euroUnicode)		

	var valid = true;
	
	if(!blockSubtemplate || blockSubtemplate.viewNode.style.display != 'none') {
	
		valid = false;
	
		var value = formEle.getProperty('value');
		
		value = trimContent(value);
		
		if(formEle.getAttribute('type') == 'radio') {
		
			if(formEle.getProperty('checked')) {
				valid = true;
			}
			else if(checkRadioSiblings) {
			
				var subEles = form.getProperty('elements');
			
				for(formEleIdx in subEles) {
			        if(typeof subEles[formEleIdx] == 'function') continue;

					var subEle = subEles[formEleIdx];
				
					if(subEle.getAttribute('name') == formEle.getAttribute('name')) {
						valid = valid || validateFormField(form, subEle, highlightInvalid, false);
					}
				}
			}
		}
		else {
	
			if(formEle.getAttribute('bf:dataType') == 'currency') {
				
			 	valid = value.match(/\d{1,}([.,](\d{2}|[-]))?$/);
			}
			else {
				
				valid = (value != '');
			}
		}
		
		if(!valid || value == euro) {
		
			valid = false;

			if(fieldLabel && highlightInvalid) {
				fieldLabel.viewNode.style.color = 'red';
			}
			
		}
		else {
		
			if(fieldLabel && highlightInvalid) {
				fieldLabel.viewNode.style.color = '';
			}
		}
	}
	
	return valid;
}

CropResizer = Ext.extend(Ext.Resizable, {

	___init: function() {

		var xy = [this.el.getX(), this.el.getY()];
	
		this.onMouseDown(this.north, {
			stopEvent: function(){
			},
			getXY: function(){
				return xy;
			}
		});
		
		this.onMouseUp({
			stopEvent: function(){
			}, 
			getXY: function(){
				return xy;
			}
		});
		
	}
	
});

var cropResizers = [];

/**
 * Initialize the crop area
 */
function imagePDFInitCropping(id, width, height, resetSize) {
	
	var image = document.getElementById('selectedImage_'+id);
	
	if(!image || image.offsetWidth == 0 || (image.readyState && image.readyState != 'complete')) {
		window.setTimeout(function(){imagePDFInitCropping(id, width, height)}, 50);
		return;
	}

	var cropAreaBoundaries = document.getElementById('cropAreaBoundaries_'+id);
	var cropArea = document.getElementById('cropArea_'+id);

    if(!cropArea) {
        if(resetSize) {
            inputChanged(id);
        }
        return;
    }

	var cropAreaEl = Ext.get('cropArea_'+id);
    var zoomControls = Ext.get('zoomControls_'+id);
	//var cropAreaVisible = document.getElementById('cropAreaVisible_'+id);

	// calculate the amount of pixels per unit
	var pixelsPerUnit;
	
	if(width >= height) {
		pixelsPerUnit = image.offsetWidth / width;
	}
	else {
		pixelsPerUnit = image.offsetHeight / height;
	}
	
	// determine the width & height of the croparea
	var cropAreaWidth = Math.round(pixelsPerUnit * width);
	var cropAreaHeight = Math.round(pixelsPerUnit * height);
	
	// calculate the current width/height, height/width ratios
	var heightWidthRatio = height / width;
	var widthHeightRatio = width / height;

	// now reduce the width & height of the crop area if they exceed the image width & height
	if(cropAreaWidth > image.offsetWidth) {
		cropAreaWidth = image.offsetWidth;
		cropAreaHeight = heightWidthRatio * cropAreaWidth;
	}

	if(cropAreaHeight > image.offsetHeight) {
		cropAreaHeight = image.offsetHeight;
		cropAreaWidth = widthHeightRatio * cropAreaHeight;
	}

	var box = document.getElementById('boxSelectedImage_'+id);
	var boxEl = Ext.get('boxSelectedImage_'+id);

	box.style.width = (image.offsetWidth+cropAreaWidth)+'px';

    if(image.offsetHeight+cropAreaHeight > 180) {
	    box.style.height = (image.offsetHeight+cropAreaHeight)+'px';
    } else {
        box.style.height = (180+10)+'px';
    }

	image.style.left = (cropAreaWidth/2)+'px';
	image.style.top = (cropAreaHeight/2)+'px';

	// set initial dimensions of crop area
	if(document.getElementById(id+'!cropurx').value && !resetSize) {
		
		cropArea.style.left = ((cropAreaWidth/2) + ((image.offsetWidth / 100) * document.getElementById(id+'!cropllx').value))+'px';
		cropArea.style.top = ((cropAreaHeight/2) + image.offsetHeight - ((image.offsetHeight / 100) * document.getElementById(id+'!cropury').value))+'px';
		cropArea.style.right = ((cropAreaWidth/2) + image.offsetWidth - ((image.offsetWidth / 100) * document.getElementById(id+'!cropurx').value))+'px';
		cropArea.style.bottom = ((cropAreaHeight/2) + ((image.offsetHeight / 100) * document.getElementById(id+'!croplly').value))+'px';

        cropAreaWidth = (image.offsetWidth / 100) * (document.getElementById(id+'!cropurx').value - document.getElementById(id+'!cropllx').value);
        cropAreaHeight = (image.offsetHeight / 100) * (document.getElementById(id+'!cropury').value - document.getElementById(id+'!croplly').value);

	} else {
		
		var cropAreaLeft = image.offsetWidth / 2;
	    var cropAreaTop = image.offsetHeight / 2;
	    
		cropArea.style.left = cropAreaLeft+'px';
		cropArea.style.top = cropAreaTop+'px';
	}
	
	var fnInitCropResizer = function(width, height) {

		if(cropResizers[id]) {
			cropResizers[id].destroy();
			cropResizers[id] = null;
		}

		cropResizers[id] = new CropResizer(cropArea, {
	        handles: 'all',
	        width: width,
	        height: height,
	        draggable: true,
	        minWidth: width/20,
	        minHeight: height/20,
	        maxWidth: box.offsetWidth,
	        maxHeight: box.offsetHeight,
	        preserveRatio: true,
	        dynamic: true,
	        constrainTo: 'boxSelectedImage_'+id,
	        pinned: true
	    });
	    
		cropResizers[id].___init();
	    
	    cropResizers[id].dd.endDrag = function(){applyCropping(id)};
	    cropResizers[id].on('resize', function(){applyCropping(id)});
	};
	fnInitCropResizer(cropAreaWidth, cropAreaHeight);
    
    if(resetSize) {
    	applyCropping(id);
    }
    
    var zoomControlChangeTimeout = 0;
    var zoomControlReinitCropperTimeout = 0;
    var zoomControlsTimeouts = [];
    var zoomControlsIntervals = [];
    var zoomControlsUsingSlider = false;
    var zoomControlsUsingSliderInterval = 0;
    var zoomControlsSlider = null;
    
    zoomControls.removeAllListeners();
    
    zoomControls.on('mousedown', function(e,t,o) {
    	
    	if(t.className) {
    		
    		if(zoomControlsTimeouts[t.className]) {
    			window.clearTimeout(zoomControlsTimeouts[t.className]);
    			zoomControlsTimeouts[t.className] = 0;
    		}
    		if(zoomControlsIntervals[t.className]) {
    			window.clearInterval(zoomControlsIntervals[t.className]);
    			zoomControlsIntervals[t.className] = 0;
    		}
    		
    		zoomControlsTimeouts[t.className] = window.setTimeout(function() {
    			
    			zoomControlsTimeouts[t.className] = 0;
    			
    			zoomControlsIntervals[t.className] = window.setInterval(function(){
    				fnZoomControlClick(e,t,o);
    			}, 40);
    			
    		}, 400);
    	}
    });
    
    zoomControls.on('mouseup', function(e,t,o) {

    	if(zoomControlsTimeouts[t.className]) {
			window.clearTimeout(zoomControlsTimeouts[t.className]);
			zoomControlsTimeouts[t.className] = 0;
		}
		if(zoomControlsIntervals[t.className]) {
			window.clearInterval(zoomControlsIntervals[t.className]);
			zoomControlsIntervals[t.className] = 0;
		}
		
    	if(zoomControlsUsingSlider) {
    		zoomControlsUsingSlider = false;
    		zoomControlsSlider.setTop(87);
    		
    		window.clearInterval(zoomControlsUsingSliderInterval);
    		
			zoomControlChangeTimeout = window.setTimeout(function(){
				
				fnInitCropResizer(cropAreaEl.getWidth(), cropAreaEl.getHeight());
				zoomControlChangeTimeout = 0;
				applyCropping(id);
				
			}, 1000);
    	}
    	
    });
    
    zoomControls.on('mousemove', function(e,t,o) {
    	
    	if(zoomControlsUsingSlider) {
    		
    		var y = Math.max(e.getPageY()-zoomControls.getY(), 53);
    		var y = Math.min(y, 124);
    		
    		zoomControlsSlider.setTop(y);
    		
    		if(zoomControlsUsingSliderInterval) {
    			window.clearInterval(zoomControlsUsingSliderInterval);
    		}
    		
    		y = y - 53;
    		
    		zoomControlsUsingSliderInterval = window.setInterval(function() {
    			if(y < 44) {
    				fnZoomInOut('in', (44 / y) ^ 3);
    			} else {
    				//y = y - 43;
    				fnZoomInOut('out', (44 / y) ^ 3);
    			}
    		}, 50);
    	}
    });
    
    var fnZoomInOut = function(inOut, speed) {
    	
		var y = cropAreaEl.getTop(true);
		var x = cropAreaEl.getLeft(true);
    	
    	if(!speed) speed = 1;
    	
		if(
				(cropAreaEl.getWidth() >= 10 && cropAreaEl.getHeight() >= 10 && inOut == 'out')
				||
				(cropAreaEl.getLeft(true) >= 1 
						&& 
				cropAreaEl.getTop(true) >= 1 
						&&
				cropAreaEl.getLeft(true)+cropAreaEl.getWidth() < boxEl.getWidth()
						&&
				cropAreaEl.getTop(true)+cropAreaEl.getHeight() < boxEl.getHeight()
						&&
				inOut == 'in')
			) {
			
				var direction = inOut == 'out' ? speed : speed*-1;
				
				if(cropAreaEl.getWidth() > cropAreaEl.getHeight()) {
					cropAreaEl.setLeft((x+direction)+'px');
					cropAreaEl.setWidth((cropAreaEl.getWidth()-direction*2)+'px');
					var newHeight = cropAreaEl.getWidth() / widthHeightRatio;
					cropAreaEl.setTop((y+(cropAreaEl.getHeight()-newHeight)/(direction*2))+'px');
					cropAreaEl.setHeight(newHeight+'px');
				} else {
					cropAreaEl.setTop((y+direction)+'px');
					cropAreaEl.setHeight((cropAreaEl.getHeight()-direction*2)+'px');
					var newWidth = cropAreaEl.getHeight() / heightWidthRatio;
					cropAreaEl.setLeft((x+(cropAreaEl.getWidth()-newWidth)/(direction*2))+'px');
					cropAreaEl.setWidth(newWidth+'px');
				}
			}    	
    };
    
    var fnZoomControlClick = function(e,t,o) {
    	
    	if(zoomControlChangeTimeout) {
    		window.clearTimeout(zoomControlChangeTimeout);
    	}
    	
		var y = cropAreaEl.getTop(true);
		var x = cropAreaEl.getLeft(true);
		
		switch(t.className) {
		
			case 'up':
				if(y>=2) {
					cropAreaEl.setTop((y-2)+'px');
				}
				break;
			case 'down':
				if(y+cropAreaEl.getHeight()<=boxEl.getHeight()-2) {
					cropAreaEl.setTop((y+2)+'px');
				}
				break;
			case 'left':
				if(x>=2) {
					cropAreaEl.setLeft((x-2)+'px');
				}
				break;
			case 'right':
				if(x+cropAreaEl.getWidth()<=boxEl.getWidth()-2) {
					cropAreaEl.setLeft((x+2)+'px');
				}
				break;
			case 'zoomin':
			case 'zoomout':
				fnZoomInOut(t.className == 'zoomout' ? 'out' : 'in', 1);
				break;
			case 'zoomslider':
				zoomControlsUsingSlider = true
				zoomControlsSlider = Ext.get(t).parent();
				if(!bb.browser.ie) {
					e.preventDefault();
				}
				break;
		}
		
		if(t.className != 'zoomslider') {
			
			zoomControlChangeTimeout = window.setTimeout(function(){
				
				fnInitCropResizer(cropAreaEl.getWidth(), cropAreaEl.getHeight());
				zoomControlChangeTimeout = 0;
				applyCropping(id);
				
			}, 1000);
		}
    	
    };
    
    zoomControls.on('mousedown', fnZoomControlClick);
    
    zoomControls.dom.style.display = 'block';
}

function applyCropping(id){
	
	var image = document.getElementById('selectedImage_'+id);
	var cropAreaEl = Ext.get('cropArea_'+id);
	
	var cropAreaLeft = cropAreaEl.getLeft(true)-image.offsetLeft;
	var cropAreaTop = cropAreaEl.getTop(true)-image.offsetTop;
	
	document.getElementById(id+'!cropllx').value = (cropAreaLeft / image.offsetWidth) * 100;
	document.getElementById(id+'!croplly').value = ((image.offsetHeight-cropAreaTop-cropAreaEl.getHeight()) / image.offsetHeight) * 100;
	document.getElementById(id+'!cropurx').value = ((cropAreaLeft+cropAreaEl.getWidth()) / image.offsetWidth) * 100;
	document.getElementById(id+'!cropury').value = ((image.offsetHeight-cropAreaTop) / image.offsetHeight) * 100;
	
	inputChanged(id);
};

