define(['fileuploader', 'jquery-jcrop', 'jquery-form', '../../node_modules/jquery-jcrop/css/jquery.Jcrop.css'], function (qq, Jcrop, jqForm) {

var g_ICData = null; // holds some data during uploading and cropping process that needs to be accessible to callbacks
var g_tmpProgressBar = null; // the progress bar element for the modal, for more efficient updating
var g_fileuploader = null; // fileuploader, used for drag and drop.

var docPicker = new DocumentPicker();
var mainElementId = '';

// this object is returned from the module
var ICComponent = {};

ICComponent.initAll = function() {
	// there may be more than 1 Image Crop component on a page, we need to handle all of them.
	$('.ICContainer').each(function(idx, elem){
        ICComponent.init(elem);
	});
};

ICComponent.init = function(elem) {
    // get the user-set id for this instance of the component
    var component_id = elem.id.match('^ImageCropComponent_(.+)$')[1];
    mainElementId = 'ImageCropComponent_' + component_id;

    var choose = $('#IC_link_' + component_id);
    choose.off('click');
    choose.on('click', function(){
        ICGetAndShowModal(component_id);
        return false;
    });

    var change = $('#IC_changeLink_' + component_id);
    change.off('click');
    change.on('click', function(){
        ICGetAndShowModal(component_id);
        return false;
    });
};


function ICGetAndShowModal(component_id)
{
	var modal_id = 'ICModal';
	var modal_selector = '#' + modal_id;

	// check if modal has already been downloaded/created.
	if ($(modal_selector + '_container').length != 0)
	{
		// modal already exists
		ICInit(modal_id, component_id);
		var modal_elem = $(modal_selector);
		modal_elem.modal('show');
	}
	else
	{
		// get the modal html from the server and initialize it
		var url = '/intranet/common/image_dialog_ajax.php?action=getmodal&id=' + component_id;
		$(document.body).append('<div id="' + modal_id + '_container"></div>');

		$(modal_selector + '_container').load(url, function(response, status, xhr){
			if (status === 'success') {
				ICFirstTimeInit(); // set bindings
				ICInit(modal_selector, component_id); // initializes modal AND data
				$(modal_selector).modal('show');
			} else {
				console.error(lmsg('common.file_upload.could_not_get_modal'));
			}
		});
	}

	$('#' + mainElementId).trigger('CropToolModalOpen');
}


function ICToggleView(selector) {
	$("[id^=ICModalView]").hide(); //hide all
	$(selector).show();
}

function ICClearErrors() {
	$("#ICUploadError").hide().text(''); //clear messages
}

function ICShowErrors(err_msg) {
	// show the correct error message depending on which has been returned.
	$('#ICUploadError').text(err_msg).show();
}

function ICUpdateCoords(c) {
	g_ICData.pos_x = c.x;
	g_ICData.pos_y = c.y;
	g_ICData.pos_w = c.w;
	g_ICData.pos_h = c.h;
}

function ICCropSave() {

	$("#ICCropSave").prop('disabled', true);

	$.ajax({
		type: "POST",
		url: "/intranet/common/image_dialog_ajax.php?action=do_crop",
		data: {	code: g_ICData.img_tmp_name,
				x: g_ICData.pos_x,
				y: g_ICData.pos_y,
				w: g_ICData.pos_w,
				h: g_ICData.pos_h,
				lockAspectRatio : g_ICData.lockAspectRatio,
				unlockAspectRatioAllowed : g_ICData.unlockAspectRatioAllowed,
				aspectRatio : g_ICData.aspectRatio,
				minWidth : g_ICData.minWidth,
				minHeight : g_ICData.minHeight,
				csrf_token: document.csrf_token
			}
	})
		.done(function (response) {

			$("#ICCropSave").prop('disabled', false);

			//if no response after crop action
			if (typeof response !== 'object') {
				ICShowErrors(lmsg('common.image_crop.server_error_or_image_too_big'));
				$('#ICModalView3').hide();
				$('#ICModalView1').show();
				return false;
			}

			//if error after crop action
			if (response.error === true) {
				ICShowErrors(response.error_msg);
				$('#ICModalView3').hide();
				$('#ICModalView1').show();
				return false;
			}

			$("#jcropWrapper").empty();

			ICFinishCrop(response);

			$('#ICModal').modal('hide');

		})
		.fail(function( jqXHR, textStatus, errorThrown) {
			$("#ICCropSave").prop('disabled', false);
			ICToggleView("#ICModalView1");
			ICShowErrors(lmsg('common.image_crop.server_error_or_image_too_big'));
			return false;
		});
}

function ICInit(modal_id, component_id) {

	ICClearErrors();
	$("#ICImageFile").val(''); //clear file element

	var params = window['ICParams_' + component_id]; // get parameters for component instance using this modal

	// create/recreate the data we will need
	g_ICData = null;
	g_ICData = {
		img_tmp_name       : null,
		js_callback        : params['callback'],
		id_suffix          : component_id,
		minWidth           : params['minWidth'],
		minHeight          : params['minHeight'],
		aspectRatio        : params['aspectRatio'],
		lockAspectRatio    : params['lockAspectRatio'],
		unlockAspectRatioAllowed : params['unlockAspectRatioAllowed'],
		fieldName          : params['fieldName'],
		pos_x              : 0,
		pos_y              : 0,
		pos_w              : 0,
		pos_h              : 0
	};

	$('#ICMinWidth').val(params['minWidth']);
	$('#ICMinHeight').val(params['minHeight']);

	var minSizeMessageElem = $('#ICMinSizeMessage');

	minWidth = params['minWidth'];
	minHeight = params['minHeight'];

	if (minWidth > 0 && !minHeight){
		minSizeMessageElem.text(lmsg('common.file_upload.minimum_width_message', minWidth));
	}
	else if (!minWidth && minHeight > 0){
		minSizeMessageElem.text(lmsg('common.file_upload.minimum_height_message', minHeight));
	}
	else if(minWidth > 0 && minHeight > 0) {
		minSizeMessageElem.text(lmsg('common.file_upload.minimum_size_message', minWidth, minHeight));
	} else
	{
		// no minimum width/height restrictions
		minSizeMessageElem.text('');
	}


	$("#ICCropSave").hide(); //hide save button

	ICInitFileUploader();

	ICToggleView("#ICModalView1");

    $('#ICInnerFileSelectLink').click(function (event) {
        event.preventDefault();
        docPicker.callInnerDocument(component_id);
    })
}

function ICFinishCrop(response)
{
	// data to pass to the callback supplied
	g_ICData.img_tmp_name = response.hash;
	var callback_data = {
		unique_id: g_ICData.id_suffix,
		img_tmp_name: g_ICData.img_tmp_name,
		img_real_name : g_ICData.img_real_name,
		img_tmp_url: response.url
	};

	// do callback & pass data here
	if(g_ICData.js_callback)
		g_ICData.js_callback(callback_data);

	// display the newly cropped image as part of component. Add random number so cached version of image won't be used by browser.
	var img_url = response.url; //'/intranet/common/image_dialog_ajax.php?action=get&type=tmp&code=' + g_ICData.img_tmp_name + '&rand=' + Math.random();

	//append image to correct place in form
	var icImage = $("#IC_image_" + g_ICData.id_suffix);
	$('#' + g_ICData.fieldName + '_special_id').val(g_ICData.img_tmp_name);

	$('.js-current-image', icImage).css('background-image', 'url("' + img_url + '")');
	$("#IC_link_" + g_ICData.id_suffix).hide();
	icImage.show();

	$('#' + mainElementId).trigger('CropToolModalClose');
}

function ICFirstTimeInit() {


	// Set bindings

	//if user select a picture
	$('#ICImageFile').change(function () {
		$("#ICImageUploadForm").submit(); //submit form
		return false;
	});

	//once form is submitted post it over ajax
	$('#ICImageUploadForm').submit(function () {
		var jqueryFormOptions = {
			beforeSubmit: beforeSubmit,
			uploadProgress: onProgress,
			success: afterSuccess,
			resetForm: true,
			data: {
				id_suffix          : g_ICData.id_suffix,
				minWidth           : g_ICData.minWidth,
				minHeight          : g_ICData.minHeight,
				aspectRatio        : g_ICData.aspectRatio,
				lockAspectRatio    : g_ICData.lockAspectRatio,
				unlockAspectRatioAllowed : g_ICData.unlockAspectRatioAllowed
			}
		};
		$(this).ajaxSubmit(jqueryFormOptions);
		return false;
	});

	//save & crop button pressed
	$("#ICCropSave").click(function () {
		ICCropSave();
		return false;
	});

	// return to image selection
	$('#ICCropBack').on('click', function() {
		ICInitFileUploader();
		ICToggleView("#ICModalView1");
		ICClearErrors();
		return false;
	});

	$('#ICCloseCropDialog').on('click', function()
	{
		$('#' + mainElementId).trigger('CropToolModalClose');
	});
}

function ICShowImageCropTool(response) //code, filename, skip_crop)
{
	//set image details
	g_ICData.img_tmp_name = response.hash; //temporary image name
	g_ICData.img_real_name = response.name; //native image name
	//img_size = response.size; //image size

	if (response.skip_crop)
	{
		ICFinishCrop(response);
		$('#ICModal').modal('hide');
		return;
	}

	// get width of Image Crop modal to obtain width of image preview
	var ICModalWidth = $('#ICModalView2 .modal-body').width();

	//get uploaded file and pass it to img element
	var img_url = response.url; //'/intranet/common/image_dialog_ajax.php?action=get&type=tmp&code=' + g_ICData.img_tmp_name;
	//construct new image element

	createImageCrop(img_url, g_ICData.lockAspectRatio, ICModalWidth);

	$("#ICAspectRatioToggleOff").click(function(e){
		e.preventDefault();
		var off_obj = $('#ICAspectRatioToggleOff');
		off_obj.tooltip('dispose');
		createImageCrop(img_url, false, ICModalWidth)
	});
	$("#ICAspectRatioToggleOn").click(function(e){
		e.preventDefault();
		var on_obj = $('#ICAspectRatioToggleOn');
		on_obj.tooltip('dispose');
		createImageCrop(img_url, true, ICModalWidth)
	});

	if (g_ICData.unlockAspectRatioAllowed)
	{
		if (g_ICData.lockAspectRatio)
		{
			$("#ICAspectRatioToggleOff").show();
		}
		else
		{
			$("#ICAspectRatioToggleOn").show();
		}
	}
}

function createImageCrop(img_url, is_locked, modalWidth)
{
	// get width of Image Crop modal to obtain width of image preview
	var ICModalWidth = $('#ICModalView2 .modal-body').width();
	var image = $('<img/>');

	//add image attributes and hide it (we dont need to show it!)
	image.attr('src', img_url).attr('id', 'ICImageCrop').hide();

	//append to modal body
	$("#jcropWrapper").empty().append(image);

	//wait until image loaded!
	image.load(function () {
		var imgWidth = image[0].naturalWidth;
		var imgHeight = image[0].naturalHeight;
		image.width = imgWidth;
		image.height = imgHeight;

		var jCropParams = {
			boxWidth     : modalWidth,//image preview max width
			boxHeight    : 400,   //image preview max height
			bgFade       : true,
			bgColor      : 'white',
			bgOpacity    : .4,
			setSelect    : [0, 0, 200, 200], // default preselect position
			keySupport   : false,
			onSelect     : ICUpdateCoords,
			onChange     : ICUpdateCoords
		};

		if (g_ICData.minWidth > 0 && g_ICData.minHeight > 0)
		{
			jCropParams.minSize   = [g_ICData.minWidth, g_ICData.minHeight];
			jCropParams.setSelect = [0, 0, g_ICData.minWidth, g_ICData.minHeight];
		} else
		{
			// full size if no minimum width or height is specified
			jCropParams.setSelect = [0, 0, imgWidth, imgHeight];
		}

		if (g_ICData.lockAspectRatio == 1 && is_locked == true && g_ICData.aspectRatio > 0)
		{
			jCropParams.aspectRatio = g_ICData.aspectRatio;
		}

		// set and center select box initially to maximum size for image
		if (g_ICData.aspectRatio > 0)
		{
			if (imgWidth > imgHeight)
			{
				var initialWidth = g_ICData.aspectRatio * imgHeight;
				var imgXpos = (imgWidth - initialWidth) / 2;
				jCropParams.setSelect = [imgXpos, 0, initialWidth, imgHeight];
			}
			else
			{
				var initialHeight = imgWidth / g_ICData.aspectRatio;
				var imgYpos = (imgHeight - initialHeight) / 2;
				jCropParams.setSelect = [0, imgYpos, imgWidth, initialHeight];
			}
		}

		//apply Jcrop to image : http://deepliquid.com/content/Jcrop.html
		image.Jcrop(jCropParams);

		window.cropimage = image;
		ICToggleView("#ICModalView3");
		//show Crop & Save button
		$("#ICCropSave").show();

		if (g_ICData.unlockAspectRatioAllowed)
		{
			if (is_locked)
			{
				$("#ICAspectRatioToggleOff").show();
				$("#ICAspectRatioToggleOn").hide();
			}
			else
			{
				$("#ICAspectRatioToggleOn").show();
				$("#ICAspectRatioToggleOff").hide();
			}
		}
	});
}


/************  Upload callbacks for Jquery Form - http://malsup.com/jquery/form/ ********************/


//do some VI changes before uploading
function beforeSubmit() {

	g_tmpProgressBar = $('#ICProgressBar'), // to update progress bar width
	g_tmpProgressBar.width("0%"); //set progress bar to 0%
	ICToggleView("#ICModalView2");
}

//update progress during upload process
function onProgress(event, position, total, percentComplete) {
	g_tmpProgressBar.width(percentComplete + '%'); //update progressbar percent complete
}

//after succesful upload
function afterSuccess(response, statusText, xhr, $form) {

	// Get version of IE, this variable is not set in other browsers. See:
	// https://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx
	var msie = document.documentMode;
	if (msie == 9)
	{
		// response is an already parsed JSON obj, except for IE 9 which doesn't understand
		// application/json content types. We instead return text/html and parse it manually
		response = jQuery.parseJSON(response);
	}

	docPicker.clearInnerFileUpload();

	//if error
	if (response.status == 'error') {
		ICInit($('#ICModal'), g_ICData.id_suffix);
		ICShowErrors(response.error);
		return false;
	}

	ICShowImageCropTool(response);
}

/******************* File Uploader (Drag n Drop) ************************/


function ICInitFileUploader()
{
	g_fileuploader = null;
	var fileUploaderSettings = {
		element: document.getElementById('file-uploader'),
		action: '/intranet/common/image_dialog_ajax.php?action=upload',
		debug: false,
		multiple: false,
		params: {
			'minWidth': g_ICData.minWidth,
			'minHeight': g_ICData.minHeight
		},

		showMessage: function(message){
			return;
		},

		onSubmit: function(id, filename){
			g_tmpProgressBar = $('#ICProgressBar'); // to update progress bar width
			g_tmpProgressBar.width("0%"); //set progress bar to 0%
			ICToggleView('#ICModalView2');
		},

		onComplete: function(id, fileName, response){
			if (!response.success){
				ICInit($('#ICModal'), g_ICData.id_suffix);
				if (response.error_message && response.error_message.length > 0){
					ICShowErrors(response.error_message);
				}
				else
				{
					ICShowErrors(lmsg('common.file_upload.not_an_image'));
				}

				return false;
			}

			ICShowImageCropTool(response);
			$('#file-uploader').html(''); // clear the fileuploader element

		},

		onProgress: function(id, fileName, loaded, total){
			g_tmpProgressBar.width(((loaded/total)*100) + '%'); //update progressbar percent complete

		}

	};
	// if (typeof _this.options.sizeLimit!== "undefined")
	// 	fileUploaderSettings['sizeLimit'] = _this.options.sizeLimit;
	// if (typeof _this.options.cancelOnInvalidFile!== "undefined")
	// 	fileUploaderSettings['cancelOnInvalidFile'] = _this.options.cancelOnInvalidFile;

	g_fileuploader = new qq.FileUploader(fileUploaderSettings);
	// hide the button that fileuploader adds to the drag and drop area
	$('#file-uploader .qq-upload-button').first().hide();
}

/**********  Inner file upload class **********************/

function DocumentPicker()
{
	var newWindow;
}

DocumentPicker.prototype.callFolderTreePopup = function (selector_name, show_marker_selectors)
{
	var marker_selector_parameter = (show_marker_selectors ? 1 : 0);

	this.newWindow = window.open('/intranet/common/folderstree_popup.php?selector_name='+selector_name+'&callback=fileUploadDocumentSelected' +
		'&document_select=1&marker_select=' + marker_selector_parameter + '&folder_select=0&class_select=0', 'tree',
		'dependent=yes,width=500,height=430,screenX=200,screenY=300,titlebar=yes, scrollbars=yes,status=yes,resizable=yes');
	window.document_picker_obj = this;
	return false;
};

// Function called from popup window with folderstree_popup.php
DocumentPicker.prototype.document_selected_callback = function (object_id, object_aggregation, object_name, dest_name)
{
	this.clearStandardFileUpload(dest_name);

	jQuery('#ICSpecialID').val(object_id).change();
	jQuery('#ICRealname').val(object_name).change();
	jQuery('#ICImageFile').change(); // trigger form submission

	return true;
};

DocumentPicker.prototype.callInnerDocument = function(dest_name)
{
	this.clearStandardFileUpload(dest_name);
	this.clearInnerFileUpload(dest_name);
	return this.callFolderTreePopup(dest_name);
};

DocumentPicker.prototype.clearStandardFileUpload = function(dest_name)
{
	jQuery('#ICImageFile').val('');
};

DocumentPicker.prototype.clearInnerFileUpload = function(dest_name)
{
	jQuery('#ICSpecialID').val('');
	jQuery('#ICRealname').val('');
};

return ICComponent;
});
