/**
 * Open a dialog to edit custom form fields.
 * 
 * The `.customformUiCustomform()` method opens a dialog when the element is clicked. The dialog can be used to edit new custom form fields.
 * The element has to contain two data attributes, data-formfieldid (representing the ID for the form field type, e.g. textarea, select ..) and data-objectid (representing the ID of the existing form field).
 * 
 * ### Examples
 * Edit a existing custom form field
 * 
 * JavaScript:
 * 
 *     
 *     de_epages('.editCustomField').customformUiCustomform({
 *         width: 800,
 *         height: 400,
 *         languageId: 1,
 *         languages: {'2' : 'English', '1' : 'Deutsch'},
 *         afterSaveDialog: function(widget, data){
 *             console.debug(widget, data);
 *         }
 *     });
 * 
 * HTML:
 * 
 *     <a href="#" class="editCustomField" data-formfieldid="5094" data-objectid="16211">Feldname</a>
 * 
 * 
 * @class jQuery.ui.customformUiCustomform
 * @extends jQuery.widget
 * 
 * @uses ep
 * @uses jQuery.dict
 * @uses jQuery.fn.scrollTo
 * @uses ep.dict
 * @uses jQuery.tmpl
 * @uses jQuery.metaparse
 * @uses jQuery.ui.widget
 * @uses ep.ui.dialog
 * @uses ep.ui.validate
 * @uses ep.validate
 * @since 6.15.0
 */

/**
 * @cfg {Integer} [width] An integer representing the width of the dialog.
 */

/**
 * @cfg {Integer} [height] An integer representing the height of the dialog.
 */

/**
 * @cfg {Integer} [languageId] An integer respresenting the ID of the currently active language.
 */

/**
 * @cfg {Object} [languages] A object representing the languages (id-name pairs, e.g. {'2' : 'English', '1' : 'Deutsch'}).
 */

/**
 * @cfg {Object} [afterSaveDialog] Callback function which is called after the new form field values were successfully saved.
 */

/**
 * See `jQuery.ui.customformUiCustomform` for details.
 * 
 * @param {Object} [options] A map of additional options pass to the method.
 * @param {Integer} [width] An integer representing the width of the dialog.
 * @param {Integer} [height] An integer representing the height of the dialog.
 * @param {Integer} [languageId] An integer respresenting the ID of the currently active language.
 * @param {Object} [languages] A object representing the languages (id-name pairs, e.g. {'2' : 'English', '1' : 'Deutsch'}).
 * @param {Object} [afterSaveDialog] Callback function which is called after the new form field values were successfully saved.
 * 
 * @method customformUiCustomform
 * @member jQuery
 * 
 * @since 6.15.0
 */

/*
 * @copyright		© Copyright 2006-2012, epages GmbH, All Rights Reserved.
 *
 * @module			de_epages.customform.ui.customform
 *
 * @revision		$Revision: 1.9 $
 */

define("de_epages/customform/ui/customform", [
	"jquery",
	"ep",
	"de_epages",
	"$dict!../dictionary",
	"$tmpl!./customform-edit",
	"$tmpl!./customform-newoption",

	"jquery/metaparse",
	"jquery/fn/scrollto",
	"jquery/ui/widget",
	"ep/validate",
	"ep/ui/dialog",
	"ep/ui/validate"
], function ($, ep, de_epages, customformDict, tmplCustomformEdit, tmplCustomformNewoption){

	/*
	 * @dictionary		ep.dict
	 *
	 * @translation		{Type}
	 *								{MandatoryStar}
	 *								{yes}
	 *								{no}
	 *								{Apply}
	 *								{Cancel}
	 *
	 * @dictionary		de_epages.customform.dictionary
	 *
	 * @translation		{FieldName}
	 *								{MandatoryForUsers}
	 *								{AdditionalFormFieldText}
	 *								{EditFormField}
	 *								{HeaderRadioOptions}
	 *								{HeaderSelectOptions}
	 *								{AddFormFieldOption}
	 *								{NewOption}
	 */

	var translationsDialog = {
			tType: customformDict.translate('Type'),
			tYes: customformDict.translate('yes'),
			tNo: customformDict.translate('no'),
			tAdd: customformDict.translate('Apply'),
			tCancel: customformDict.translate('Cancel'),
			tTitle: customformDict.translate('EditFormField'),
			tFieldName: customformDict.translate('FieldName'),
			tMandatoryStar: customformDict.translate('MandatoryStar'),
			tMandatoryForUsers: customformDict.translate('MandatoryForUsers'),
			tAdditionalFormFieldText: customformDict.translate('AdditionalFormFieldText'),
			tHeaderRadioOptions: customformDict.translate('HeaderRadioOptions'),
			tHeaderSelectOptions: customformDict.translate('HeaderSelectOptions'),
			tAddFormFieldOption: customformDict.translate('AddFormFieldOption'),
			tNewOption: customformDict.translate('NewOption')
		};

	$.widget( 'ui.customformUiCustomform', {
		//	_newOptionCounter: undefined,
		//	ObjectID: undefined,

		// default options
		options: {
			ViewAction: 'JSONGetFieldData',
			dialogContentId: 'editDialogContent',
			isPreview: false,
			languages: {},
			languageId: 1,
			width: 800,
			height: 400
		},

		_create: function() {
			var	self = this,
				elem = self.element,
				o = self.options;

			// get the object ID
			self.ObjectID = elem.data('objectid');
			// get the form field ID
			self.FormFieldID = elem.data('formfieldid');

			// get the mandatory checkbox
			if(!o.isPreview){
				self._mandatoryField = $("input[value="+self.ObjectID+"][name=IsMandatoryObjectID]");
			}

			// handle click to open dialog to edit form field
			elem.on('click', function(event){
				// remove already existing dialog
				if($('#' + o.dialogContentId).length){
					$('#' + o.dialogContentId).remove();
				}

				self.dialogContentHolder = ep('<div id="' + o.dialogContentId + '" />');
				self.dialogContentHolder.appendTo('body');

				// create dialog to edit form field
				self.dialog = self.dialogContentHolder.uiDialog({
					title: translationsDialog.tTitle + ": ",
					modal: true,
					width: o.width,
					height: o.height,
					position: ['center', $('window').scrollTop()+30],
					form: {
						action: '?',
						method: 'post',
						options: {
							ajax: function(send){
								send({
									dataType: 'json',
									data: {
										ChangeAction: "JSONAlterField",
										ObjectID: self.ObjectID,
										ChangeObjectID: self.ObjectID,
										FormFieldID: self.FormFieldID,
										FieldClassID: self.FormFieldID
									}
								})
								.done(function(data, status, jqXHR){
									// uncomment next line for debug use
									//console.log("done:", data);

									// widget was called from preview
									if(o.isPreview){
										// execute callback
										if(typeof o.afterSaveDialog == "function"){
											o.afterSaveDialog(self, data);
										}
									}else{
										// set mandatory checkbox if necessary
										if(data.IsMandatory !== self._isMandatory){
											self._mandatoryField.attr('checked', !self._isMandatory);
										}

										// set field name if necessary
										var rewriteFieldName = data.FieldName ? data.FieldName : data.Alias;
										if(self._fieldName != rewriteFieldName){
											$('#alterLink_' + self.ObjectID).html(rewriteFieldName);
										}
									}

									self.dialogContentHolder.uiDialog('close');
								});
							}
						}
					},
					open: function(){
						// get data from server
						self._getFieldData();
					},
					buttons: [{
						type: "submit",
						text: translationsDialog.tAdd
					}, {
						text: translationsDialog.tCancel,
						click: function(){
							ep(this).uiDialog('close');
						}
					}]
				});

				// handle form errors for FieldNames (at least one field is requested)
				self.form = self.dialog.uiDialog('option', 'form')
					.on('submit', function( event ){
						if(self.Alias != "CaptionFormField"){
							var elem = $(this),
								first,
								isInvalid = true;

							elem
								.find('input[name=FieldName]')
								.each(function(i){
									var input = ep(this);

									// remember first input
									if(i == 0){
										first = input;
									}
									// if a not empty input was found -> mark as valid and leave each
									if(input.val() != ""){
										isInvalid = false;
										return false;
									}
								});

							if(isInvalid){
								first
									.uiValidate({required:true})
									.trigger('focus')
									.trigger('validate');

								event.preventDefault();
							}else{
								first
									.uiValidate({required:false})
									.trigger('validate');
							}
						}
					});

			});
		},

		_getFieldData: function(){
			var	self = this,
				elem = self.element,
				o = self.options;

			ep.ajax({
				dataType: 'json',
				data: {
					ViewAction: o.ViewAction,
					ObjectID	: self.ObjectID
				}
			})
			.done(function(data){
				self.Alias = data.Alias;
				// mandatory on start up
				self._isMandatory = parseInt(data.IsMandatory);

				if(!o.isPreview){
					// check if mandatory value from document is the same as the requested one
					self._isMandatory = (self._mandatoryField.is(':checked')==!!self._isMandatory)? self._isMandatory : [1, 0][self._isMandatory];
				}
				data.IsMandatory = self._isMandatory;

				// get the fieldname for the custom form field (for default language)
				$.each(data.LocalizedTexts, function(key, value){
					if(o.languageId == value.LanguageID){
						self._fieldName = value.FieldName;
						return false;
					}
				});

				// save original data
				self.currentData = data;
				// process request data
				self._processFieldData(data);

			})
			.fail(function(xhr,status,error){
				// ToDo: something more
				// console.warn(error);
			});
		},

		_processFieldData: function(){
			var	self = this,
				elem = self.element,
				o = self.options;

			if(self.dialog===undefined){
				self.dialog = self.dialogContentHolder.uiDialog();
			}

			// extend currentData with additional attributes as default language id, type name and language object (key == languageId)
			$.extend(self.currentData, {
				languageId: o.languageId,
				alias: self.currentData.NameOrAlias[o.languageId],
				languages: o.languages
			});

			// complete dialog title with field name
			var fieldname = elem.closest('dl').data('fieldname');
			fieldname = fieldname===undefined ? elem.text() : fieldname;
			self.dialog.uiDialog('option', 'title', self.dialog.uiDialog('option', 'title') + " " + fieldname);

			// append necessary template to dialog
			tmplCustomformEdit($.extend(self.currentData, translationsDialog)).appendTo(self.dialogContentHolder);
			// resolve metaparse parts in dialog
			ep('#' + o.dialogContentId + ' *').metaparse();

			// if custom form field needs handling for options
			if(self.currentData.HasOptions){
				// initialize counter for new options
				self._newOptionCounter = 0;
				// get DOM element which holds all options (new options get the class "epCustomFormAddNewOption")
				self.optionsHolder = self.dialog.find('.epCustomFormOptions');

				// delete options
				self.optionsHolder.find('a[data-deleteoptionid]').on('click', function(evt){
					var _this = $(this),
						form = $(this).closest('form');
						hidden = $('<input type="hidden" name="DeleteOptionID" value="'+_this.data('deleteoptionid')+'" />');

					// fade out parent table row
					_this.closest('li').fadeOut();
					// add hidden input containing delete information (send and deleted when "Save" is pressed)
					hidden.appendTo(form);

					// prevent default action for preview
					if(o.isPreview){
						evt.preventDefault();
					}
				});

				// delete new added options
				self.optionsHolder.on('click', 'a.deleteNewOptionLink', function(evt){
					var _this = $(this);

					// fade out parent table row
					_this.closest('li').slideUp(500, function(){
						$(this).remove();
					});

					// prevent default action for preview
					if(o.isPreview){
						evt.preventDefault();
					}
				});

				// get DOM element to add a new option and set an event handler
				self.newOptionLink = self.dialog.find('#addNewOptionLink');
				self.newOptionLink.on('click', function(evt){
					self._handleNewOption();
				});
			}
		},

		_handleNewOption: function(){
			var	self = this,
				elem = self.element,
				o = self.options;

			// increment new option counter
			self._newOptionCounter++;

			// append template for new option to dialog
			tmplCustomformNewoption(self.currentData, {count: self._newOptionCounter}).appendTo(self.optionsHolder);

			var lastOptionElement = self.optionsHolder.children(':last');
			// fade new option element in
			lastOptionElement.fadeIn(500, function(){
				// resolve metaparse parts in template
				ep(lastOptionElement.find('input')).metaparse();
				// move next animation to another thread
				window.setTimeout(function(){
					// scroll down to last option element
					self.optionsHolder.scrollTo(lastOptionElement, 800);
				}, 1);
			});
		}
	});

	return de_epages;

});