
Ext.define("Ext.ux.form.field.IncludeComboBox", {

	extend: "Ext.form.FieldContainer",

	mixins: {
		"field": "Ext.form.field.Field",
		"componentController": "Ext.ux.util.ComponentController"
	},

	alias: [
		"widget.includecombo",
		"widget.includecombobox"
	],

	refs: [
		{
			ref: "form",
			selector: "#typeForm"
		},
		{
			ref: "typesGroup",
			selector: "#typesGroup"
		},
		{
			ref: "typeInclude",
			selector: "#typeInclude"
		},
		{
			ref: "typeExclude",
			selector: "#typeExclude"
		},
		{
			ref: "typeAll",
			selector: "#typeAll"
		},
		{
			ref: "keysCombo",
			selector: "#keysCombo"
		}
	],

	value: "",

	layout: "anchor",

	typeConfig: null,
	listConfig: null,
	_includeComboValue: false,

	config: {
		asString: true
	},

	initComponent: function () {

		var i_cmp = this;
		var o_config = i_cmp.initialConfig;
		

		i_cmp.value = o_config.value = Ext.decode(o_config.value) || o_config.value;

		// Sanitize the configuration from deprecated
		var o_typeConfig = (function () {

			var o_type = {};
			var o_default = {
				includeLabel: {
					da: "Inkluder i",
					en: "Include in"
				},
				excludeLabel: {
					da: "Udelad fra",
					en: "Exclude from"
				},
				allLabel: {
					da: "Brug alle",
					en: "Use all"
				}
			};

			if (o_config.typeConfig) {
				if (o_config.typeConfig.includeText) {
					o_config.typeConfig.includeLabel = o_config.typeConfig.includeText;
				}
				if (o_config.typeConfig.excludeText) {
					o_config.typeConfig.excludeLabel = o_config.typeConfig.excludeText;
				}
				if (o_config.typeConfig.allText) {
					o_config.typeConfig.allLabel = o_config.typeConfig.allText;
				}
				o_type = Ext.Object.merge(o_default, o_config.typeConfig);
			}
			else {
				if (o_config.includeLabel) {
					o_type.includeLabel = o_config.includeLabel;
				}
				if (o_config.excludeLabel) {
					o_type.excludeLabel = o_config.excludeLabel;
				}
				if (o_config.allLabel) {
					o_type.allLabel = o_config.allLabel;
				}

				o_type = Ext.Object.merge(o_default, o_type);
			}

			return o_type;
		})();

		var o_listConfig = (function () {

			var o_list = {};

			if (o_config.listConfig) {
				o_list.dmd = o_config.listConfig.dmd;
				o_list.entity = o_config.listConfig.entity;
				o_list.view = o_config.listConfig.uiName;
			}
			else {
				o_list.dmd = o_config.dmd;
				o_list.entity = o_config.entity;
				o_list.view = o_config.view;
			}

			Ext.Object.merge(o_list, ip2.pick(o_config, [
				"extraParams",
				"pageSize",
				"emptyText"
			]));

			return o_list;
		})();

		Ext.apply(i_cmp, {
			items: i_cmp.createItems(o_typeConfig, o_config, o_listConfig)
		});

		i_cmp.initComponentController();

		i_cmp.callParent(arguments);

		i_cmp.initField();

		i_cmp.control({
			"typeAll": {
				change: i_cmp.onComponentChange,
				scope: i_cmp
			},
			"typeInclude": {
				change: i_cmp.onComponentChange,
				scope: i_cmp
			},
			"typeExclude": {
				change: i_cmp.onComponentChange,
				scope: i_cmp
			}
		});

		i_cmp.setValue(i_cmp.value);
		i_cmp.resetOriginalValue();

		return i_cmp;
	},

	initValue: function() {

		var i_self = this;
		var value = i_self.value;

		if (Ext.isString(value)) {
			value = Ext.decode(value, true) || value;
		}

		if (Ext.isEmpty(value)) {
			value = i_self.getValue();
		}

		i_self.value = i_self.lastValue = i_self.originalValue = value;
		i_self.resetOriginalValue();
	},

	onComponentChange: function () {

		var i_cmp = this;
		var i_all = i_cmp.getTypeAll();
		var i_combo = i_cmp.getKeysCombo();
		var s_fn = i_all.getValue() ? "hide" : "show";

		i_combo[s_fn]();

		setTimeout(function () {
			i_cmp.checkChange();
		}, 0);

		return i_cmp;
	},

	checkChange: function() {

		var i_self = this;
		if (!i_self.suspendCheckChange) {
			var newVal = i_self.getValue();
			var oldVal = i_self.lastValue;

			var s_new = JSON.stringify(newVal);
			var s_old = JSON.stringify(oldVal);

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

	getValue: function () {

		var i_cmp = this;
		var i_type = i_cmp.getTypesGroup();
		var i_combo = i_cmp.getKeysCombo();
		var s_type = i_type.getChecked()[0] ? i_type.getChecked()[0].getGroupValue() : i_type.getValue().type;

		if (s_type == "all") {
			return "";
		}
		else {

			var o_value = i_type.getValue();
			var comboValue = i_cmp.value && i_cmp.value.keys ? i_cmp.value.keys : "";

			if (i_cmp._includeComboValue) {
				comboValue = i_combo.getValue();

				if (Ext.isArray(comboValue)) {

					if (comboValue.length == 1) {
						comboValue = comboValue[0];
					}
				}

				if (comboValue) {
					o_value.keys = comboValue;
				}
			}
			else {
				o_value.keys = comboValue;
			}

			if (!o_value.keys) {
				o_value = "";
			}

			return i_cmp.getAsString() ? Ext.encode(o_value, true) || "" : o_value;
		}
	},

	setValue: function (value) {

		var i_cmp = this;
		var i_type = i_cmp.getTypesGroup();
		var i_combo = i_cmp.getKeysCombo();

		if (Ext.isString(value)) {
			value = Ext.decode(value, true) || value;
		}

		if (value && value.type) {
			i_type.setValue(value);
		}
		else {
			i_type.setValue({ type: "all" });
		}

		if (value && value.keys) {

			var a_value = Ext.Array.from(value.keys);
			var comboValue = a_value.length == 1 ? a_value[0] : a_value;

			i_combo.show();
			i_combo.setValue(comboValue);
		}
		else {
			i_combo.setValue([]);
			i_combo.hide();
		}

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

		return i_cmp;
	},

	isDirty: function () {

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

		var b_dirty = ip2.isEqual(value, originalValue);

		return !b_dirty;
	},

	disable: function() {

		var i_cmp = this;
		i_cmp.callParent(arguments);

		var i_all = i_cmp.getTypeAll();
		var i_include = i_cmp.getTypeInclude();
		var i_exclude = i_cmp.getTypeExclude();

		i_all.disable();
		i_include.disable();
		i_exclude.disable();
	},

	createItems: function(o_typeConfig, o_config, o_listConfig) {

		var i_self = this;

		var a_items = [
			{
				xtype: "form",
				itemId: "typeForm",
				border: false,
				layout: "anchor",
				items: [
					{
						xtype: "radiogroup",
						itemId: "typesGroup",
						vertical: true,
						columns: 1,
						isFormField: false,
						items: [
							{
								itemId: "typeAll",
								boxLabel: ip2.i18n(o_typeConfig.allLabel),
								name: "type",
								inputValue: "all",
								readOnly: i_self.readOnly,
								checked: (function () {
									var b_checked = false;
									if (!o_config.value) {
										b_checked = true;
									}
									return b_checked;
								})(),
								isFormField: false
							},
							{
								itemId: "typeInclude",
								boxLabel: ip2.i18n(o_typeConfig.includeLabel),
								name: "type",
								inputValue: "include",
								readOnly: i_self.readOnly,
								checked: (function () {
									var b_checked = false;
									if (o_config.value && o_config.value.type == "include") {
										b_checked = true;
									}
									return b_checked;
								})(),
								isFormField: false
							},
							{
								itemId: "typeExclude",
								boxLabel: ip2.i18n(o_typeConfig.excludeLabel),
								name: "type",
								inputValue: "exclude",
								readOnly: i_self.readOnly,
								checked: (function () {
									var b_checked = false;
									if (o_config.value && o_config.value.type == "exclude") {
										b_checked = true;
									}
									return b_checked;
								})(),
								isFormField: false
							}
						]
					},
					(function () {
						var o_comboConfig = ip2.extend({
							itemId: "keysCombo",
							name: "keys",
							isFormField: false,
							anchor: "100%",
							hidden: true,
							forceSelection: true,
							readOnly: i_self.readOnly,
							listeners: {
								change: {
									fn: function () {
										i_self.checkChange();
									}
								},
								afterrender: {
									fn: function () {
										i_self._includeComboValue = true;
									},
									single: true
								}
							},
							value: (function () {

								var value = i_self.value || {
									keys: []
								};

								return value.keys || [];
								
							})()
						}, o_listConfig);
						var i_combo = Ext.widget("entitycombobox", o_comboConfig);
						return i_combo;
					})()
				]
			}
		];

		return a_items;
	}
});
