Ext.define("Portfolio.designer.ui.domainModelEntityManager", {

	extend: "Ext.window.Window",

	alias: [
		"widget.ip2DomainModelEntityManager"
	],

	layout: {
		type: "fit"
	},

	collapsed: false,

	collapsible: true,

	closable: true,

	maximizable: true,

	buttons: [
		{
			text: ip2.i18n("ok"),
			handler: function(i_button) {

				var i_self = i_button.up("window");

				i_self.doSaveEntity(function() {
					i_self.setForceClose(true);
					i_self.fireEvent("saveModel", i_self, i_self.getEntity());
					i_self.close();
				});
			},
			listeners: {
				afterrender: {

					fn: function(i_button) {

						var i_self = i_button.up("window");

						i_button[i_self.required ? "disable" : "enable"]();
					}
				}
			}
		},
		{
			text: ip2.i18n("cancel"),
			handler: function(i_button) {

				var i_self = i_button.up("window");

				i_self.setForceClose(true);
				i_self.close();
			}
		}
	],

	listeners: {
		beforeclose: {
			fn: function(i_self) {

				var b_force = i_self.getForceClose();

				if (!b_force) {

					var b_dirty = i_self.checkDirty();

					b_force = !b_dirty;

					if (b_dirty) {
						i_self.promptSaveChanges();
					}
				}

				return b_force;
			}
		},
		beforeshow: {
			fn: function(i_window) {

				var i_self = this;
				var i_designer = i_self.getDesigner();
				var o_model = i_designer.getModel();
				var i_columnManager = i_self.getColumnManager();

				if (o_model.baseDatatypeChanged) {

					var i_grid = i_columnManager.columnGrid;
					var i_store = i_grid.getStore();

					var a_records = i_store.getRange();

					Ext.Array.each(a_records, function(i_record) {

						var s_like = i_record.get("like");

						if (s_like) {
							var baseDatatype = o_model.types.was[i_record.get("likeWas")];
							if (baseDatatype) {
								i_record.set("like", baseDatatype.name);
							}
						}
					});
				}
			}
		},
		newAffiliations: {
			fn: function() {

				var i_self = this;
				i_self.newAffiliations++;
			}
		},
		updateColumn: {
			fn: function(s_old, s_new) {

				var i_self = this;
				var i_formManager = i_self.getFormDesigner();
				var i_viewManager = i_self.getViewManager();

				i_formManager.fireEvent("updateColumn", s_old, s_new);
				i_viewManager.fireEvent("updateColumn", s_old, s_new);
			}
		},
		updateAffiliation: {
			fn: function(o_data) {

				var i_self = this;
				var i_formManager = i_self.getFormDesigner();
				i_formManager.fireEvent("updateAffiliation", i_formManager, o_data);
			}
		},
		updateRelation: {
			fn: function (i_record) {

				var i_self = this;

				var i_viewManager = i_self.getViewManager();
				var i_formManager = i_self.getFormDesigner();

				i_viewManager.fireEvent("updateRelation", i_viewManager, i_record);
				i_formManager.fireEvent("updateRelation", i_formManager, i_record);
			}
		},
		removeColumn: {
			fn: function(s_column) {

				var i_self = this;
				var i_viewManager = i_self.getViewManager();
				var i_formManager = i_self.getFormDesigner();

				if (i_viewManager) {

					i_viewManager.fireEvent("removeColumn", s_column);
				}

				if (i_formManager) {

					i_formManager.fireEvent("removeColumn", s_column)
				}
			}
		},
		removeAffiliation: {
			fn: function (s_name) {

				var i_self = this;
				var i_formManager = i_self.getFormDesigner();

				if (i_formManager) {

					i_formManager.fireEvent("removeAffiliation", s_name);
				}
			}
		},
		removeRelation: {
			fn: function(s_entity) {

				var i_self = this;

				var i_viewManager = i_self.getViewManager();
				var i_formManager = i_self.getFormDesigner();

				i_viewManager.fireEvent("removeRelation", i_viewManager, s_entity);
				i_formManager.fireEvent("removeRelation", i_formManager, s_entity);
			}
		}
	},

	config: {
		designer: null,
		portalEntityManager: null,
		affiliationManager: null,
		columnManager: null,
		viewManager: null,
		entityPropertyManager: null,
		keyManager: null,
		relationManager: null,
		relationSelector: null,
		constraintsManager: null,
		formDesigner: null,
		newColumns: 0,
		newEntity: false,
		entity: null,
		required: false,
		forceClose: false,
		changed: false,
		tabpanel: null
	},

	requires: [
		"Portfolio.designer.ui.domainModelEntityPropertyManager",
		"Portfolio.designer.ui.domainModelEntityColumnManager",
		"Portfolio.designer.ui.domainModelEntityKeyManager",
		"Portfolio.designer.ui.domainModelEntityRelationManager",
		"Portfolio.designer.ui.domainModelEntityAffiliationGrid",
		"Portfolio.designer.ui.views.grid.view.Manager",
		"Portfolio.designer.ui.views.form.view.Manager"
	],

	initComponent: function() {

		var i_self = this;
		var i_designer = i_self.getDesigner();

		i_self.changed = false;
		i_self.entityPropertyChanged = 0;
		i_self.newColumns = 0;
		i_self.newAffiliations = 0;
		i_self.newRelations = 0;

		Portfolio.app.fireEvent("beforeDetached", i_self);

		i_self.callParent();
		var o_entity = i_self.getEntity();

		// new entity
		if (!o_entity) {

			var o_settings = i_designer.settings;

			o_entity = Ext.apply({}, {
				name: "new",
				title: ip2.i18n({
					da: "Ny Entitet",
					en: "New Entity"
				}),
				columns: [],
				designer: Ext.apply({}, {
					width: 200,
					height: 150,
					x: o_settings.entities.lastX + 10,
					y: o_settings.entities.lastY + 10
				}),
				isSet: {},
				ui: {
					grids: {
						portfolio: {
							columns: []
						}
					},
					forms: {
						portfolio: {
							columns: []
						}
					}
				},
				extend: {}
			});
			i_self.setEntity(o_entity);
			i_self.setNewEntity(true);
		}

		i_self.name = o_entity.name;
		i_self.title = ip2.i18n(o_entity.title);

		i_designer.current.extend.entity = (o_entity.extend) ? o_entity.extend.entity : "";
		i_designer.current.extend.baseTable = (o_entity.extend) ? o_entity.extend.baseTable : "";

		// entity properties
		// -----------------
		var i_entityPropertyManager = Ext.widget("ip2DomainModelEntityPropertyManager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			required: i_self.required
		});

		i_self.setEntityPropertyManager(i_entityPropertyManager);

		// entity columns
		// --------------
		var i_columnManager = Ext.widget("ip2DomainModelEntityColumnManager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			columnToEdit: i_self.columnToEdit,
			required: i_self.required
		});

		i_self.setColumnManager(i_columnManager);

		// entity keys
		// -----------
		var i_keyManager = Ext.widget("ip2DomainModelEntityKeyManager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			required: i_self.required
		});

		i_self.setKeyManager(i_keyManager);

		// entity relations
		// ----------------
		var i_relationManager = Ext.widget("ip2DomainModelEntityRelationManager", {
			designer: i_designer,
			model: i_self.model || "",
			entityManager: i_self,
			entity: o_entity,
			required: i_self.required
		});

		i_self.setRelationManager(i_relationManager);

		// entity relations
		// ----------------
		var i_constraintsManager = Ext.widget("designer.ui.constraints.manager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			title: ip2.i18n({
				da: "Sql Begræsninger",
				en: "Sql Constraints"
			}),
			required: i_self.required
		});

		i_self.setConstraintsManager(i_constraintsManager);

		// entity affiliations
		// -------------------
		var i_affiliationManager = Ext.widget("ip2DomainModelEntityAffiliationGrid", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			disabled: i_self.required
		});

		i_self.setAffiliationManager(i_affiliationManager);

		// entity grid layout
		// ------------------
		var i_viewManager = Ext.widget("designer.ui.views.grid.view.manager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			required: i_self.required
		});

		i_self.setViewManager(i_viewManager);

		// entity form designer
		// --------------------
		var i_formDesigner = Ext.widget("designer.ui.views.form.view.manager", {
			designer: i_designer,
			entityManager: i_self,
			entity: o_entity,
			required: i_self.required
		});

		i_self.setFormDesigner(i_formDesigner);

		// Tabpanel with all functions
		// ---------------------------
		var i_tabpanel = Ext.widget("tabpanel", {
			defaults: {
				layout: {
					type: "fit"
				}
			},
			minTabWidth: 20,
			listeners: {
				afterrender: {
					fn: function(tabpanel) {
						if (i_self.columnToEdit) {
							i_self.setActiveTab(i_self.getColumnManager());
						}
					}
				},
				tabchange: {
					fn: function(i_tabpanel, i_tab) {

						if (!i_tab.items.items[0].entityPropertyChanged) {
							i_tab.items.items[0].entityPropertyChanged = 0;
						}

						if (i_self.entityPropertyChanged > i_tab.items.items[0].entityPropertyChanged) {
							i_tab.items.items[0].fireEvent("entityPropertyChanged");
							i_tab.items.items[0].entityPropertyChanged = i_self.entityPropertyChanged;
						}
					}
				}
			},
			items: [
				{
					title: ip2.i18n({
						da: "Egenskaber",
						en: "Properties"
					}),
					items: [
						i_entityPropertyManager
					],
					itemId: "tap-properties"
				},
				{
					title: ip2.i18n({
						da: "Kolonner",
						en: "Columns"
					}),
					items: [
						i_columnManager
					],
					itemId: "tap-columns"
				},
				{
					title: ip2.i18n({
						da: "Nøgler",
						en: "Keys"
					}),
					items: [
						i_keyManager
					],
					itemId: "tap-keys",
					listeners: {
						activate: {
							fn: function(tab) {

								var i_keyManager = i_self.getKeyManager();
								var i_columnManager = i_self.getColumnManager();

								if (i_keyManager.keySelector.isVisible()) {

									i_keyManager.keySelector.selector.bindStore(i_columnManager.columnGrid.store);

									var a_records = i_keyManager.keyGrid.getSelectionModel().getSelection();

									if (a_records.length > 0) {

										var i_record = a_records[0];

										i_self.keyManager.keySelector.setToField(i_record.get("columns"));
									}
								}
							}
						}
					}
				},
				{
					title: ip2.i18n({
						da: "Relationer",
						en: "Relations"
					}),
					items: [
						i_relationManager
					],
					itemId: "tap-relations",
					listeners: {
						activate: {
							fn: function(tab) {

								var i_manager = i_self.getRelationManager();

								if (i_manager.relationSelector && i_manager.relationSelector.isVisible()) {
									var a_records = i_manager.relationGrid.getSelectionModel().getSelection();

									if (a_records.length > 0) {
										var i_record = a_records[0];
										i_manager.relationSelector.setBetweenRelation(i_record.get("betweenEntity"), i_record.get("betweenOn"));
										i_manager.relationSelector.setAndRelation(i_record.get("andEntity"), i_record.get("andOn"));
									}
								}
							}
						}
					}
				},
					i_self.constraintsManager,
				{
					title: ip2.i18n({
						da: "Tilhørsforhold",
						en: "Affiliations"
					}),
					items: [
						i_affiliationManager
					],
					itemId: "tap-affiliations"
				},
				{
					title: ip2.i18n({
						da: "Grids",
						en: "Grids"
					}),
					items: [
						i_viewManager
					],
					itemId: "tap-views",
					listeners: {
						activate: {
							fn: function(i_panel) {

								var i_manager = i_self.getViewManager();

								if (i_manager.getNewColumns() != i_self.newColumns) {
									i_manager.fireEvent("newColumns", i_manager, i_self.newColumns);
								}

								if (i_manager.getNewRelations() != i_self.newRelations) {
									i_manager.fireEvent("newRelations", i_manager, i_self.newRelations);
								}
							}
						}
					}
				},
				{
					title: ip2.i18n({
						da: "Form",
						en: "Form"
					}),
					items: [
						i_formDesigner
					],
					itemId: "tap-form",
					listeners: {
						activate: {
							fn: function(i_panel) {

								var i_formDesigner = i_self.getFormDesigner();

								i_formDesigner.fireEvent("newColumns", i_formDesigner, i_self.newColumns);
								i_formDesigner.fireEvent("newRelations", i_formDesigner, i_self.newRelations);
								i_formDesigner.fireEvent("newAffiliations", i_formDesigner, i_self.newAffiliations);
							}
						}
					}
				}
			]
		});

		i_self.setTabpanel(i_tabpanel);

		i_self.add(i_tabpanel);

		i_self.enableBubble("saveModel");
	},

	checkDirty: function() {

		var i_self = this;
		var o_entity = i_self.getEntity() || {};
		var o_copy = Ext.clone(o_entity);

		var i_columnManager = i_self.getColumnManager();
		var i_entityPropertyManager = i_self.getEntityPropertyManager();
		var i_keyManager = i_self.getKeyManager();
		var i_affiliationManager = i_self.getAffiliationManager();
		var i_relationManager = i_self.getRelationManager();
		var i_viewManager = i_self.getViewManager();
		var i_formDesigner = i_self.getFormDesigner();
		var i_contraintManager = i_self.getConstraintsManager();

		// save entity columns
		i_columnManager.doSave(o_copy);

		// save entity properties
		i_entityPropertyManager.doSave(o_copy);

		// save keys / indexs
		i_keyManager.doSave(o_copy);

		// save entity relations
		i_relationManager.doSave(o_copy);

		// save constraints relations
		i_contraintManager.doSave(o_copy);

		// save grid layout
		i_viewManager.doSave(o_copy);

		// save form layout
		i_formDesigner.doSave(o_copy);

		i_affiliationManager.doSave(o_copy);

		var s_entity = Ext.encode(o_entity);
		var s_clone = Ext.encode(o_copy);

		return s_entity != s_clone;
	},

	updateChanged: function(value) {

		var i_self = this;
		var s_value = i_self.getTitle();
		i_self.setTitle(s_value);
	},

	promptSaveChanges: function(f_callback) {

		var i_self = this;

		f_callback = f_callback || Ext.emptyFn;

		ip2.messageBox({
			title: ip2.i18n("saveChanges"),
			message: ip2.i18n("doYouWantToChange"),
			yesText: ip2.i18n({
				da: "Ja",
				en: "Yes"
			}),
			noText: ip2.i18n({
				da: "Nej",
				en: "No"
			}),
			yesFn: function () {
				i_self.saveEntity(f_callback);
				i_self.fireEvent("saveModel", i_self, i_self.getEntity());
				i_self.close();
			},
			noFn: function() {
				i_self.setForceClose(true);
				i_self.close();
			}
		});
	},

	saveEntity: function(f_callback) {

		var i_self = this;
		f_callback = f_callback || Ext.emptyFn;
		i_self.doSaveEntity(f_callback);
	},

	doSaveEntity: function(f_callback) {

		var i_self = this;
		var o_entity = i_self.getEntity();
		var i_designer = i_self.getDesigner();
		var o_model = i_designer.model;
		var i_columnManager = i_self.getColumnManager();
		var i_entityPropertyManager = i_self.getEntityPropertyManager();
		var i_keyManager = i_self.getKeyManager();
		var i_affiliationManager = i_self.getAffiliationManager();
		var i_relationManager = i_self.getRelationManager();
		var i_viewManager = i_self.getViewManager();
		var i_formDesigner = i_self.getFormDesigner();
		var i_portalEntityManager = i_self.getPortalEntityManager();
		var i_contraintManager = i_self.getConstraintsManager();

		f_callback = f_callback || Ext.emptyFn;

		// save entity columns
		if (!i_columnManager.doSave(o_entity)) {
			i_self.setActiveTab(i_columnManager);
			return false;
		}

		// save entity properties
		if (!i_entityPropertyManager.doSave(o_entity)) {
			i_self.setActiveTab(i_entityPropertyManager);
			return false;
		}

		// save keys / indexs
		i_keyManager.doSave(o_entity);

		// save entity relations
		var a_relations = i_relationManager.doSave();

		var a_stored = o_model.relations || [];

		var a_filtered  = [];

		Ext.Array.each(a_relations, function(o_relation) {

			var o_found = Ext.Array.findBy(a_stored, function(o_stored) {
				return o_stored.between.entity == o_relation.between.entity &&
					   o_stored.and.entity == o_relation.and.entity;
			});

			if (o_found) {
				Ext.apply(o_found, o_relation);
			}
			else {
				o_found = Ext.apply({}, o_relation);

				a_stored.push(o_found);
			}
		});

		Ext.Array.each(a_stored, function(o_config) {

			var o_found = Ext.Array.findBy(a_filtered, function(o_stored) {
				return o_stored.between.entity == o_config.between.entity &&
					   o_stored.and.entity == o_config.and.entity;
			});

			if (!o_found) {
				a_filtered.push(o_config);
			}
		});


		o_model.relations = a_filtered;

		// save constraints relations
		i_contraintManager.doSave(o_entity);

		// save grid layout
		i_viewManager.doSave(o_entity);

		// save form layout
		i_formDesigner.doSave(o_entity);

		// save entity affiliation (must be saved after form layout)
		if (!i_affiliationManager.doSave(o_entity)) {
			i_self.setActiveTab(i_affiliationManager);
			return false;
		}

		var o_found = Ext.Array.findBy(o_model.entities, function(o_value) {
			return o_value.name == o_entity.name;
		});

		if (!o_found) {
			o_model.entities.push(o_entity);
		}
		else {
			Ext.apply(o_found, o_entity);
		}

		if (i_self.newEntity) {
			i_self.fireEvent("newEntity", o_entity);
		}

		if (o_entity.isSet) {
			delete o_entity.isSet;
		}

		if (i_portalEntityManager) {
			i_portalEntityManager.setChanged(o_entity.title);
		}

		if (i_designer) {
			i_designer.setChanged();
		}

		if (i_portalEntityManager && i_portalEntityManager.grid) {
			i_portalEntityManager.grid.reload(o_entity.columns);
		}


		i_self.setEntity(o_entity);

		f_callback();
	},

	setActiveTab: function(tabItem) {
		var me = this;
		var cnt = 0;
		me.tabpanel.items.each(function(item) {
			if (item.items.items[0] == tabItem) {
				me.tabpanel.setActiveTab(cnt);
				return;
			}
			cnt++;
		});
	}
  });
