Ext.define("Portfolio.registry.view.Detail", {

	extend: "Ext.window.Window",

	alias: "widget.registry.view.detail",

	collapsible: true,

	viewModel: {
		type: "registry"
	},

	controller: "registry.view.detail",

	layout: "fit",
	constrain: true,
	readOnly: false,
	record: null,
	tree: null,

	listeners: {
		beforeclose: {
			fn: "doReload"
		}
	},

	alternateClassName: [
		"Ext.registry.view.Detail"
	],

	requires: [
		"Portfolio.registry.viewmodel.Registry",
		"Portfolio.registry.controller.view.Detail",
		"Portfolio.registry.util.Service",
		"Portfolio.dynapp.ui.column.Properties",
		"Portfolio.registry.ui.property.Add"
	],

	initComponent: function() {

		var i_self = this;
		var i_viewModel = i_self.getViewModel();
		var o_options = i_self.options;
		var i_record = i_self.record;

		i_self.callParent(arguments);

		i_self.on({
			afterrender: {
				fn: function(item) {
					Ext.Ajax.request({
						url: "/portfolio/app/designer/designer.json",
						success: function(response) {

							var o_designer = {};
							eval("o_designer =" + response.responseText);

							var i_form = i_self.createLayout(i_record, o_designer);

							i_self.add(i_form);
							i_self._form = i_form;
						}
					});
				}
			}
		});

		i_viewModel.setData({
			record: i_record,
			tree: i_self.tree
		});

		return i_self;
	},

	createLayout: function(i_record, o_designer) {

		var i_self = this;

		var i_tabpanel = Ext.widget("tabpanel", {
			layout: "fit"
		});

		i_tabpanel.add(i_self.createGeneral(i_record));

		if (!i_record.isRoot()) {

			var o_meta = i_record.get("meta");

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

			if (o_meta.properties.type == "string") {
				o_meta.properties.type = "varchar";
			}

			if (o_meta.properties.plugin || o_meta.properties.properties) {
				delete o_meta.properties.plugin;
				delete o_meta.properties.properties;
			}

			i_tabpanel.add(i_self.createMeta(i_record, o_designer));
			i_tabpanel.add(i_self.createPlugin(i_record));
		}

		var i_form = Ext.widget("form", {
			layout: "fit",
			trackResetOnLoad: true,
			defaults: {
				labelWidth: 140
			},
			items: [i_tabpanel],
			buttons: i_self.createButtons()
		});

		i_tabpanel.setActiveTab(0);

		return i_form;
	},

	createGeneral: function(i_record) {

		var i_self = this;
		var a_items = [];

		a_items = a_items.concat(i_self.createDefault(i_record));
		a_items = a_items.concat(i_self.createProperties(i_record));

		var i_panel = Ext.widget("panel", {
			title: ip2.i18n({
				da: "Generel",
				en: "General"
			}),
			itemId: "panel-general",
			layout: "anchor",
			autoScroll: true,
			bodyPadding: 10,
			defaults: {
				anchor: "100%"
			},
			items: a_items
		});

		i_panel.addDocked(i_self.createToolbar(i_record));

		return i_panel;
	},

	createMeta: function(i_record, o_designer) {

		var i_self = this;
		var i_controller = i_self.getController();
		var o_meta = i_record.get("meta");
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var o_options = i_tree.options;

		o_meta.properties.name = i_record.get("key");

		var i_properties = Ext.widget("dynapp.ui.column.properties", {
			title: ip2.i18n({
				da: "Meta information",
				en: "Meta information"
			}),
			itemId: "panel-meta",
			types: o_designer.types,
			generic: o_designer.generic,
			meta: o_meta,
			options: o_options
		});

		i_properties.on({
			propertychange: {
				fn: function(source, recordId, value) {

					var i_propertyGrid = this;
					var i_record = i_viewModel.get("record");

					var i_propertyRecord = i_propertyGrid.getRecord();
					i_propertyRecord.set(recordId, value);

					i_controller.doSaveMeta();
				}
			}
		});

		if (!(
			ip2.isAccessible("app.sysreg.data.update") ||
			ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
			ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update"))
			) {

			i_properties.disable();
		}

		return i_properties;
	},

	createPlugin: function(i_record) {

		var i_self = this;
		var i_controller = i_self.getController();
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var o_meta = i_record.get("meta");
		var o_options = i_tree.options;

		var o_plugin = o_meta.plugin;

		var i_panel = Ext.widget("panel", {
			title: ip2.i18n({
				da: "Plugin",
				en: "Plugin"
			}),
			itemId: "panel-plugin",
			layout: "fit",
			listeners: {
				activate: {
					fn: function(item) {

						var i_editor = item.down("#editor-plugin");
						if (i_editor && i_editor.getEditor()) {
							if (!i_editor.isDisabled()) {
								i_editor.getEditor().focus(false, 100);
							}
						}
						else {
							i_editor.on({
								editorready: {
									fn: function(item) {
										setTimeout(function() {
											if (!i_editor.isDisabled()) {
												i_editor.getEditor().focus(false, 100);
											}
										}, 100);
									}
								},
								single: true
							});
						}
					}
				}
			},
			items: [
				{
					xtype: "acetextarea",
					hideLabel: true,
					name: "plugin",
					anchor: "100%",
					value: o_plugin.src,
					itemId: "editor-plugin",
					validator: function(value) {

						var s_return = true;
						if (value) {
							var i_regexNewLine = new RegExp("\r?\n|\r", "g");
							var i_regexTab = new RegExp("\t", "g");
							var s_sanitized = value.replace(i_regexNewLine, "");
							var s_sanitized = s_sanitized.replace(i_regexTab, "");
							var b_valid = Ext.decode(s_sanitized, true);
							if (!b_valid) {
								s_return = ip2.i18n({
									da: "Dette skal være gyldig json",
									en: "This needs to be valid json"
								});
							}
						}

						return s_return;
					},
					listeners: {
						render: {
							fn: function(item) {
								if (!(
									ip2.isAccessible("app.sysreg.data.update") ||
									ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
									ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update"))
									) {

									item.disable();
								}
							},
							single: true
						},
						change: {
							fn: function(i_field, value) {
								if (i_field.isValid()) {

									i_controller.doSaveMeta();
								}
							},
							buffer: 500
						}
					}
				}
			]
		});

		return i_panel;
	},

	createDefault: function(i_record) {

		var i_self = this;
		var a_items = [];
		if (!i_record.isRoot()) {
			var i_value = i_self.createField(i_record.data, true);
			a_items = [i_value];
		}

		return a_items;
	},

	createProperties: function(i_record) {

		var i_self = this;

		var i_fieldset = Ext.widget("fieldset", {
			layout: "anchor",
			itemId: "properties",
			title: ip2.i18n({
				da: "Egenskaber",
				en: "Properties"
			}),
			padding: 5,
			flex: 1,
			collapsible: true,
			defaults: {
				anchor: "100%",
				labelWidth: 140
			},
			items: i_self.createFields(i_record)
		});

		return [i_fieldset];
	},

	createFields: function(i_record) {

		var i_self = this;
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var i_store = i_tree.getStore();
		var i_proxy = i_store.getProxy();
		var o_store = i_proxy.dataStore;
		var o_options = i_tree.options;
		var a_fields = [];
		var a_childrend = i_record.get("children");
		Ext.Array.each(a_childrend, function(o_field) {

			var i_field;
			var o_meta = o_field.meta;
			var o_properties = o_meta.properties;
			var o_plugin = o_meta.plugin;
			var s_name = o_field.key.split(".").pop();
			var s_label = o_properties.title ? o_properties.title : s_name.charAt(0) + s_name.slice(1);

			var o_config = {
				fieldLabel: ip2.i18n(s_label),
				name: o_field.key,
				value: o_field.value,
				defaultLanguage: ip2.getUser().get("USRLNG") || "en",
				languages: wsh.getLanguages("portfolio")
			};

			o_config.fieldLabel = ip2.i18n(o_config.fieldLabel);

			var s_type = "textfield";
			var s_metatype = "varchar";

			if (o_properties.type) {
				s_metatype = o_properties.type;
			}
			switch (s_metatype){
				case "string":
				case "char":
				case "varchar":

					if (o_properties.len >= 40) {
						s_type = "textarea";
					}
					Ext.apply(o_config, {
						maxLength: o_properties.len || 30
					});
					break;
				case "integer":
				case "int":
				case "decimal":
				case "dec":
				case "float":
				case "decimal(11,2)":
				case "smallint":
				case "bigint":
				case "numeric":
					s_type = "numberfield";
					var n_precision = 0;
					if (o_properties.prec || o_properties.dec) {
						n_precision = o_properties.prec || o_properties.dec;
					}
					else {
						if (s_metatype != "int" || s_metatype != "integer") {
							n_precision = 2;
						}
					}
					Ext.apply(o_config, {
						decimalPrecision: n_precision,
						decimalSeparator: Ext.util.Format.decimalSeparator,
						maxLength: o_properties.len || 30
					});
					break;
				case "timestamp":
					s_type = "isotimestampfield";
					break;
				case "date":
					s_type = "datefield";
					Ext.apply(o_config, {
						format: "d-m-Y",
						submitFormat: "Y-m-d"
					});
					break;
				case "bool":
					s_type = "checkbox";
					Ext.apply(o_config, {
						inputValue: 1,
						uncheckedValue: 0
					});
					break;
				default :
					Ext.apply(o_config, {
						maxLength: o_properties.len || 30
					});
					break;
			}

			var o_evaled;
			var f_validator;
			if (o_plugin.src) {
				var o_evaled;
				try {
					eval("o_evaled = " + o_plugin.src);
				}
				catch (err) {
					console.log("eval error check plugin if its valid");
					o_evaled = {};
				}
				if (o_evaled.xtype) {
					if (o_evaled.xtype.indexOf("i18n") != -1) {
						var a_languages = o_config.languages;
						if (a_languages.indexOf(o_config.defaultLanguage) != 0) {
							var n_index = a_languages.indexOf(o_config.defaultLanguage);
							var s_value = a_languages.splice(n_index, 1)[0];
							a_languages.unshift(s_value);
						}
					}
					s_type = o_evaled.xtype;
				}
				if (o_evaled.validator) {
					f_validator = o_evaled.validator;
					delete o_evaled.validator;
				}
				Ext.apply(o_config, o_evaled);
			}

			o_config.readOnly = !(
									ip2.isAccessible("app.sysreg.data.update") ||
									ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
									ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update")
								);

			i_field = Ext.widget(s_type, o_config);

			if (o_evaled && f_validator) {
				i_field.getErrors = (function(f_old) {
					return function(value) {
						value = i_field.getValue();
						var a_errors = f_old.apply(this, [value]) || [];

						var s_error = f_validator.call(this, i_self._form.getForm(), value) || "";

						if (s_error) {
							a_errors.push(s_error);
						}

						return a_errors;
					};
				})(i_field.getErrors);
			}
			i_field.suspendCheckChange++;
			i_field.setValue(o_field.value);
			i_field.resetOriginalValue();
			i_field.suspendCheckChange--;

			i_field.on({
				change: {
					fn: function(i_field, value) {
						if (i_field.isValid() && value) {
							var s_key = i_field.name;
							if (i_field.getSubmitValue) {
								value = i_field.getSubmitValue();
							}
							Portfolio.registry.util.Service.setSingleValue(o_options, s_key, value, o_store, function() {});
						}
					},
					buffer: 500
				}
			});

			a_fields.push(i_field);
		});

		return a_fields;
	},

	createField: function(o_field) {

		var i_self = this;
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var i_store = i_tree.getStore();
		var i_proxy = i_store.getProxy();
		var o_store = i_proxy.dataStore;
		var o_options = i_tree.options;
		var i_field;
		var o_meta = o_field.meta;
		var o_properties = o_meta.properties;
		var o_plugin = o_meta.plugin;
		var s_name = o_field.key.split(".").pop();
		var s_label = o_properties.title ? o_properties.title : s_name.charAt(0) + s_name.slice(1);

		var o_config = {
			fieldLabel: ip2.i18n(s_label),
			name: o_field.key,
			value: o_field.value,
			defaultLanguage: ip2.getUser().get("USRLNG") || "en",
			languages: wsh.getLanguages("portfolio")
		};

		o_config.fieldLabel = ip2.i18n(o_config.fieldLabel);

		var s_type = "textfield";
		var s_metatype = "varchar";

		if (o_properties.type) {
			s_metatype = o_properties.type;
		}
		switch (s_metatype){
			case "string":
			case "char":
			case "varchar":
				if (o_properties.len >= 40) {
					s_type = "textarea";
				}
				o_config = Ext.apply(o_config, {
					maxLength: o_properties.len || 30
				});
				break;
			case "integer":
			case "int":
			case "decimal":
			case "dec":
			case "float":
			case "smallint":
			case "bigint":
			case "numeric":
				s_type = "numberfield";
				var n_precision = 0;
				if (o_properties.prec) {
					n_precision = o_properties.prec;
				}
				else {
					if (s_metatype != "int" || s_metatype != "integer") {
						n_precision = 2;
					}
				}
				Ext.apply(o_config, {
					decimalPrecision: n_precision,
					decimalSeparator: Ext.util.Format.decimalSeparator,
					maxLength: o_properties.len || 30
				});
				break;
			case "timestamp":
				s_type = "isotimestampfield";
				break;
			case "date":
				s_type = "datefield";
				Ext.apply(o_config, {
					format: "d-m-Y",
					submitFormat: "Y-m-d"
				});
				break;
			case "bool":
				s_type = "checkbox";
				Ext.apply(o_config, {
					inputValue: 1,
					uncheckedValue: 0
				});
				break;
			default :
				Ext.apply(o_config, {
					maxLength: o_properties.len || 30
				});
				break;
		}

		var o_evaled;
		var f_validator;
		if (o_plugin.src) {
			try {
				eval("o_evaled = " + o_plugin.src);
			}
			catch (err) {
				console.log("eval error check plugin if its valid");
				o_evaled = {};
			}
			if (o_evaled.xtype) {
				if (o_evaled.xtype.indexOf("i18n") != -1) {
					var a_languages = o_config.languages;
					if (a_languages.indexOf(o_config.defaultLanguage) != 0) {
						var n_index = a_languages.indexOf(o_config.defaultLanguage);
						var s_value = a_languages.splice(n_index, 1)[0];
						a_languages.unshift(s_value);
					}
				}
				s_type = o_evaled.xtype;
			}
			if (o_evaled.validator) {
				f_validator = o_evaled.validator;
				delete o_evaled.validator;
			}
			Ext.apply(o_config, o_evaled);
		}

		o_config.readOnly = !(
			ip2.isAccessible("app.sysreg.data.update") ||
			ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
			ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update")
		);

		i_field = Ext.widget(s_type, o_config);

		if (o_evaled && f_validator) {
			i_field.getErrors = (function(f_old) {
				return function(value) {
					value = i_field.getValue();
					var a_errors = f_old.apply(this, [value]) || [];

					var s_error = f_validator.call(this, i_self._form.getForm(), value) || "";

					if (s_error) {
						a_errors.push(s_error);
					}

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

		i_field.suspendCheckChange++;
		i_field.setValue(o_field.value);
		i_field.resetOriginalValue();
		i_field.suspendCheckChange--;

		i_field.on({
			change: {
				fn: function(i_field, value) {
					if (i_field.isValid() && value) {
						var s_key = i_field.name;
						if (i_field.getSubmitValue) {
							value = i_field.getSubmitValue();
						}
						Portfolio.registry.util.Service.setSingleValue(o_options, s_key, value, o_store, function() {});
					}
				}
			}
		});

		return i_field;
	},

	createButtons: function() {

		var i_self = this;
		var i_controller = i_self.getController();
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var i_record = i_self.record;

		var a_buttons = [
			{
				xtype: "button",
				text: ip2.i18n({
					da: "Luk",
					en: "Close"
				}),
				itemId: "btn-close",
				handler: function() {
					i_self.close();
				}
			}
		];

		return a_buttons;
	},

	getFieldValue: function() {

		var i_self = this;
		var i_viewModel = i_self.getViewModel();
		var i_record = i_viewModel.get("record");
		var i_form = i_self._form.getForm();
		var i_field = i_form.findField(i_record.get("key"));

		return i_field ? i_field.getValue() : "";
	},

	createToolbar: function(i_record) {

		var i_self = this;
		var i_viewModel = i_self.getViewModel();
		var i_tree = i_viewModel.get("tree");
		var o_options = i_tree.options;

		var a_items = [];

		if ((
				ip2.isAccessible("app.sysreg.data.update") ||
				ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
				ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update")
			)) {

			a_items.push({
				xtype: "button",
				text: ip2.i18n({
					da: "Tilføj",
					en: "Add"
				}),
				disabled: !(ip2.isAccessible("app.sysreg.data.update") ||
							ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".update") ||
							ip2.isAccessible("app.sysreg.data.schema." + o_options.library + ".table " + o_options.file + ".update")
				),
				iconCls: "pf-add",
				handler: "onPropertyAdd"
			});
		}

		var i_toolbar = Ext.widget("toolbar", {
			dock: "top",
			items: a_items
		});

		return i_toolbar;
	},

	getMeta: function() {

		var i_self = this;

		var i_panel_plugin = i_self.down("#panel-plugin");

		var i_properties = i_self.down("#panel-meta");

		var i_plugin;

		if (i_panel_plugin) {
			i_plugin = i_panel_plugin.down("#editor-plugin");
		}

		var o_properties = {};
		var o_plugin = {
			src: ""
		};

		if (i_properties) {
			var i_record = i_properties.getRecord();
			o_properties = i_record.data;
		}

		if (i_plugin) {
			o_plugin.src = i_plugin.getValue();
		}

		var o_meta = {
			properties: o_properties,
			plugin: o_plugin
		};

		return o_meta;
	},

	updateValueField: function(i_record) {

		var i_self = this;
		if (!i_self.isDestroyed) {
			var i_panel = i_self.down("#panel-general");
			if (i_panel) {
				var a_result = i_panel.query("[name=" + i_record.get("key") + "]");
				if (a_result.length > 0) {
					i_panel.remove(a_result[0], true);
					var i_newField = i_self.createField(i_record.data, true);
					i_panel.insert(0, i_newField);
				}
			}
		}
	},

	updateProperties: function(o_value) {

		var i_self = this;
		var i_record = i_self.record;
		var a_children = i_record.get("children");
		a_children.push(o_value);

		var i_fieldset = i_self.down("#properties");

		if (i_fieldset) {
			i_fieldset.add(i_self.createField(o_value));
		}
	}
});
