Ext.define("Ext.ux.form.field.i18n.Text", {

	extend: "Ext.form.FieldContainer",

	mixins: {
		field: "Ext.form.field.Field"
	},

	alias: [
		"widget.i18ntextfield"
	],

	layout: "anchor",

	/* @config
	 *
	 */
	defaultLanguage: "",
	languages: null,

	iconClassName: "AIL-flags",
	iconFieldStyle: "background-position-x: 4px; padding-left: 28px;",
	iconFieldCls: "AIL-icon AIL-icon-18 icon-flag_",
	preventI18nTrigger: false,

	/* @property outputTypes
	 * Constant map with allowed output types.
	 */

	outputTypes: {
		VARCHAR: "varcharfield",
		JSON: "jsonfield"
	},

	forceJSON: false,

	/* @property outputType
	 * Keep track of how to deliver the value:
	 * Output types are defined in this.outputTypes
	 */
	outputType: null,

	/* @property _defaults
	 * Default config values used to create caretaker components
	 */
	_defaults: null,

	/* @property _varcharComponent
	 * The component to caretake VARCHAR mode
	 */
	_varcharComponent: null,
	/* @property _objectComponent
	 * The component to caretake JSON & STRINGED mode
	 */
	_objectComponent: null,
	/* @property _activeComponent
	 * The component currently active based on outputType
	 */
	_activeComponent: null,
	_currentState: 1,

	_storedObjectValue: null,

	asString: false,

	requires: [
		"Ext.ux.form.field.i18n.Combo",
		"Ext.ux.form.field.i18n.Varchar"
	],

	initComponent: function () {

		var i_self = this;

		i_self._plugins = i_self.plugins;

		delete i_self.plugins;

		var o_config = i_self.initialConfig;

		Ext.apply(i_self, {
			defaultLanguage: i_self.defaultLanguage || wsh.i18n.getPrimary() || "da",
			languages: i_self.languages || wsh.getLanguages() || ["da"]
		});

		i_self.callParent(arguments);

		i_self.initDefaultConfig();

		i_self.initField();

		i_self.setActiveComponent();
		i_self._touched = true;

		return i_self;
	},

	renderer: function(value) {

		return ip2.i18n(value);
	},

	initDefaultConfig: function () {

		var i_self = this;

		var o_defaults = ip2.pick(i_self, [
			"value",
			"defaultLanguage",
			"languages",
			"iconCssFile",
			"iconClassName",
			"iconFieldStyle",
			"iconFieldCls",
			"vtype", "vtypeText",
			"maxLength", "enforceMaxLength",
			"preventMark"
		]);

		i_self._defaults = Ext.apply(o_defaults, {
			anchor: "100%",
			hidden: true,
			isFormField: false,
			preventI18nTrigger: i_self.preventI18nTrigger
		});
	},

	initValue: function () {

		var i_self = this;

		var value = i_self.value;
		var n_type = i_self.getOutputType(value);

		i_self.outputType = n_type;
		i_self.setCurrentState(n_type);

		i_self.mixins.field.initValue.call(i_self);
	},

	setActiveComponent: function (n_type, value) {

		n_type = n_type || this.outputType;

		var i_self = this;
		var o_type = i_self.outputTypes;
		var o_config = {
			itemId: n_type
		};

		value = value || i_self.getValue();

		var i_active = i_self.getActiveComponent();
		var n_currentState = i_self.getCurrentState();

		switch (n_type) {
		case o_type.VARCHAR:

			// If we were other than VARCHAR (object), then set store value
			if (n_currentState == o_type.JSON) {

				if (i_self.asString) {
					var o_temp = Ext.decode(value, true) || null;
					if (o_temp) {
						value = o_temp;
					}
				}

				if (value && Ext.isObject(value)) {
					var o_value = value;
					value = o_value[i_self.defaultLanguage];
					i_self.setStoredObject(o_value);
				}
			}

			i_self._activeComponent = i_active = i_self.getOrCreateVarcharComponent();

			if (i_self._objectComponent) {
				i_self._objectComponent.hide();
			}

			i_self._activeComponent.show();

			i_active.setValue(value);
		break;

		default:

			i_self._activeComponent = i_active = i_self.getOrCreateObjectComponent({
				itemId: "jsonfield"
			});

			if (i_self._varcharComponent) {
				i_self._varcharComponent.hide();
			}
			i_self._activeComponent.show();

			var o_storedObject = i_self.getStoredObject();
			if (o_storedObject) {
				if (!Ext.isObject(value)) {
					o_storedObject[i_self.defaultLanguage] = value;
					i_active.setValue(o_storedObject);
				}
			}
			else {
				i_active.setValue(value);
			}
			n_type = o_type.JSON;

		break;
		}

		i_self.setCurrentState(n_type);

		i_self.checkChange();
		i_self.validate();

		return i_active;
	},

	getActiveComponent: function () {

		var i_self = this;

		return i_self._activeComponent;
	},

	getErrors: function(value) {
		var i_self = this;
		var i_active = i_self.getActiveComponent();
		return i_active.getErrors();
	},

	getOrCreateVarcharComponent: function (o_config) {

		o_config = o_config || {};

		var i_self = this;
		var i_component = i_self._varcharComponent;

		if (!i_component) {

			var o_defaults = i_self._defaults;
			var o_component = Ext.Object.merge(o_defaults, {
				xtype: "i18nvarchar",
				defaultLanguage: i_self.defaultLanguage,
				itemId: i_self.outputTypes.VARCHAR,
				plugins: i_self._plugins || [],
				readOnly: i_self.readOnly || false,
				iconClassName: i_self.iconClassName,
				iconFieldStyle: i_self.iconFieldStyle,
				iconFieldCls: i_self.iconFieldCls
			}, o_config);

			o_component.margin = 0;

			i_self._varcharComponent = i_component = i_self.add(o_component);

			i_component.on({
				i18ntrigger: {
					fn: function () {
						i_self.onTriggerClick();
					}
				},
				change: {
					fn: function () {
						i_self.checkChange();
					}
				},
				validitychange: {
					fn: function(item, b_valid) {
						i_self.validate();
					}
				},
				focus: {
					fn: function() {
						i_self.fireEvent("focus", i_self);
					}
				},
				blur: {
					fn: function() {
						i_self.fireEvent("blur", i_self);
					}
				}
			});

			i_component.getErrors = (function(f_old) {
				return function(value) {
					value = i_component.getValue();
					var a_errors = f_old.apply(i_component, [value]) || [];

					return a_errors;
				};
			})(i_component.getErrors);
		}

		return i_component;
	},

	getOrCreateObjectComponent: function (o_config) {

		o_config = o_config || {};

		var i_self = this;
		var i_component = i_self._objectComponent;

		if (!i_component) {

			var o_defaults = i_self._defaults;

			var o_component = Ext.Object.merge(o_defaults, {
				xtype: "i18ncombo",
				itemId: i_self.outputTypes.JSON,
				defaultLanguage: i_self.defaultLanguage,
				plugins: i_self._plugins || [],
				readOnly: i_self.readOnly || false,
				iconFieldStyle: i_self.iconFieldStyle,
				iconFieldCls: i_self.iconFieldCls,
				iconClassName: i_self.iconClassName,
				listeners: {
					i18ntriggercombo: {
						fn: function () {
							i_component.collapse();
							i_self.onTriggerClick();
						}
					},
					change: {
						fn: function () {
							i_self.checkChange();
						}
					},
					validitychange: {
						fn: function(item, b_valid) {
							i_self.validate();
						}
					},
					focus: {
						fn: function() {
							i_self.fireEvent("focus", i_self);
						}
					},
					blur: {
						fn: function() {
							i_self.fireEvent("blur", i_self);
						}
					}
				}
			}, o_config);

			i_self._objectComponent = i_component = i_self.add(o_component);

			i_component.getErrors = (function(f_old) {
				return function(value) {
					value = i_component.getValue();
					var a_errors = f_old.apply(i_component, [value]) || [];

					return a_errors;
				};
			})(i_component.getErrors);
		}

		return i_component;
	},

	checkChange: function () {

		var i_self = this;

		var newVal = i_self.getValue();
		var oldVal = i_self.lastValue;

		if (!i_self.suspendCheckChange) {

			newVal = Ext.decode(newVal, true) || newVal;
			oldVal = Ext.decode(oldVal, true) || oldVal;

			var s_new = newVal;
			var s_old = oldVal;

			if (Ext.isObject(newVal)) {
				s_new = Ext.encode(newVal);
			}

			if (Ext.isObject(oldVal)) {
				s_old = Ext.encode(oldVal);
			}

			if (s_new != s_old) {
				i_self.lastValue = newVal;
				i_self.fireEvent("change", i_self, newVal, oldVal);
				i_self.onChange(newVal, oldVal);
			}
		}
	},

	focus: function(b_selectText, n_delay, f_callback, scope) {

		var i_self = this;
		var i_active = i_self.getActiveComponent();
		if (i_active) {
			i_active.focus(b_selectText, n_delay, f_callback, scope);
		}
	},

	isDirty: function() {

		var i_self = this;
		var value = i_self.getValue();
		var originalValue = i_self.originalValue;

		if (Ext.isObject(value)) {
			value = Ext.encode(value);
		}

		if (Ext.isObject(originalValue)) {
			originalValue = Ext.encode(originalValue);
		}

		return value != originalValue;
	},

	onTriggerClick: function () {

		var i_self = this;
		i_self.isChanging = true;
		var o_types = i_self.outputTypes;
		var n_currentState = i_self.getCurrentState();
		var n_newState = n_currentState;

		if (n_currentState == o_types.VARCHAR) {
			n_newState = o_types.JSON;
		}
		else {
			n_newState = o_types.VARCHAR;
		}

		// If we have not yet altered value, present a warning screen for this
		if (!i_self._touched) {
			i_self.presentWarning(n_newState, function() {
				i_self.setActiveComponent(n_newState);
				i_self._touched = true;
			});
		}
		else {
			i_self.setActiveComponent(n_newState);
		}

		return i_self;
	},

	setDisabled: function(value) {

		var i_self = this;
		var i_active = i_self.getActiveComponent();
		if (i_active) {
			i_active.setDisabled(value);
		}
	},

	presentWarning: function (n_state, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var i_self = this;

		ip2.messageBox({
			title: ip2.i18n({
				da: "Ændring af feltets type",
				en: "Field type change detected"
			}),
			message: ip2.i18n({
				da: "Du er ved at ændre feltets type",
				en: "You are changing the type of the field"
			}),
			yesText: ip2.i18n({ da: "OK", en: "OK" }),
			noText: ip2.i18n({ da: "Afbryd", en: "Cancel" }),
			yesFn: f_callback
		});
	},

	getOutputType: function (value) {

		var i_self = this;
		var n_type;

		if (Ext.isString(value)) {
			n_type = i_self.outputTypes.VARCHAR;
		}
		else {
			n_type = i_self.outputTypes.JSON;
		}

		return n_type;
	},

	getCurrentState: function () {

		return this._currentState;
	},

	setCurrentState: function (n_state) {
		this._currentState = n_state;
		return this;
	},

	getValue: function () {

		var i_self = this;
		var i_active = i_self.getActiveComponent();

		if (i_active) {
			i_self.value = i_active.getValue();
		}

		var value = i_self.mixins.field.getValue.call(i_self);

		if (i_self.asString) {
			value = Ext.isObject(value) ? Ext.encode(value) : value;
		}

		return value;
	},

	setValue: function (value) {

		var i_self = this;
		if (Ext.isString(value)) {
			value = Ext.decode(value, true) || value;
		}
		var n_type = i_self.getOutputType(value);
		var i_active;

		if (i_self.outputType != n_type) {
			i_self.outputType = n_type;
			i_active = i_self.setActiveComponent(n_type, value);
		}
		else {
			i_active = i_self.getActiveComponent();
			if (i_active) {
				i_active.setValue(value);
			}
			else {
				i_active = i_self.setActiveComponent(n_type, value);
			}
		}

		i_self.mixins.field.setValue.call(i_self, value);

		return i_self;
	},

	setStoredObject: function (value) {

		var i_self = this;
		var i_active = i_self.getActiveComponent();
		var o_value = Ext.apply({}, value);
		delete o_value[i_self.defaultLanguage];
		i_self._storedObjectValue = o_value;
	},

	getStoredObject: function () {

		return this._storedObjectValue;
	},

	disable: function() {

		var i_self = this;
		i_self.setDisabled(true);
	},

	enable: function() {

		var i_self = this;
		i_self.setDisabled(false);
	}
});
