Ext.define("Portfolio.designer.ui.domainModelEntityRelationManager", {
	extend: "Ext.panel.Panel",
	alias: ["widget.ip2DomainModelEntityRelationManager"],
	border: 0,
	height: 410,
	layout: {
		type: "border"
	},
	config: {
		model: null,
		designer: null,
		entity: null,
		relationGrid: null,
		relationSelector: null,
		entityManager: null,
		required: false
	},

	requires: [
		"Portfolio.designer.ui.domainModelEntityRelationSelector",
		"Portfolio.designer.ui.domainModelEntityRelationGrid"
	],

	initComponent: function() {

		var i_self = this;

		i_self.callParent();

		i_self.add(i_self.createItems());

		i_self.on({
			entityPropertyChanged: {
				fn: function() {

					var i_entityManager = i_self.getEntityManager();
					var i_relationGrid = i_self.getRelationGrid();

					var o_entity = Ext.apply({}, {
						title: i_entityManager.entityPropertyManager.getForm().findField("title").getValue(),
						name: i_entityManager.entityPropertyManager.getForm().findField("name").getValue()
					});

					var a_columns = i_relationGrid.getView().getGridColumns();

					Ext.Array.each(a_columns, function(i_column) {
						var i_editor;
						if (i_column.field && i_column.field.xtype == "ip2DomainModelEntityComboBox") {

							// field already rendered
							i_editor = i_column.field;
							var a_entities = i_editor.entities || [];

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

							if (o_found) {
								Ext.apply(o_found, o_entity);
							}

							i_editor.loadData(a_entities);
						}
						else if (i_column.editor && i_column.editor.xtype == "ip2DomainModelEntityComboBox") {
							i_editor = i_column.editor;

							var a_entities = i_editor.entities || [];

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

							if (o_found) {
								Ext.apply(o_found, o_entity);
							}
						}
					});
				}
			}
		});

		i_self.enableBubble("updateRelation");
		i_self.enableBubble("removeRelation");
	},

	createItems: function() {

		var i_self = this;
		var i_designer = i_self.getDesigner();
		var o_entity = i_self.getEntity();
		var o_model = i_self.getModel();
		var i_entityManager = i_self.getEntityManager();
		var a_items = [];

		var i_relationSelector = Ext.create("Portfolio.designer.ui.domainModelEntityRelationSelector", {
			designer: i_designer,
			entity: o_entity,
			store: i_entityManager.columnManager.columnGrid.store,
			hidden: true,
			flex: 1,
			region: "south",
			required: i_self.getRequired(),
			betweenListChange: function(list) {

				var a_fields = [];

				Ext.Array.each(list, function(s_field) {

					a_fields.push({
						name: s_field
					});
				});

				// update grid column "key fields"
				var i_grid = i_self.getRelationGrid();
				var a_records = i_grid.getSelectionModel().getSelection();

				Ext.Array.each(a_records, function(i_record) {
					i_record.set("betweenOn", a_fields);
					i_record.commit();
				});
			},
			andListChange: function(list) {

				var a_fields = [];

				Ext.Array.each(list, function(s_field) {

					a_fields.push({
						name: s_field
					});
				});

				// update grid column "key fields"
				var i_grid = i_self.getRelationGrid();

				var i_selected = i_grid.getSelectionModel().getSelection() [0];

				i_selected.set("andOn", a_fields);
				i_selected.commit();

				if (i_selected.get("betweenEntity") && i_selected.get("andEntity") && i_selected.get("cardinality")) {

					var a_betweenOn = i_selected.get("betweenOn") || [];
					var a_andOn = i_selected.get("andOn") || [];

					if (a_betweenOn.length > 0 && a_andOn.length > 0) {
						i_self.fireEvent("updateRelation", i_selected);
					}
				}
			}
		});

		var i_relationGrid = Ext.create("Portfolio.designer.ui.domainModelEntityRelationGrid", {
			designer: i_designer,
			entityManager: i_entityManager,
			entity: o_entity,
			selector: i_relationSelector,
			model: o_model || "",
			flex: 1,
			region: "center",
			required: i_self.getRequired()
		});

		i_self.setRelationSelector(i_relationSelector);
		i_self.setRelationGrid(i_relationGrid);

		a_items.push(i_relationSelector);
		a_items.push(i_relationGrid);

		return a_items;
	},

	getParentRelation: function() {

		var i_self = this;
		var o_entity = i_self.getEntity();
		var a_result = [];
		var i_relationGrid = i_self.getRelationGrid();
		var i_store = i_relationGrid.getStore();
		var a_records = i_store.getRange();

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

			var o_relation = Ext.apply({}, {
				was: "",
				between: {
					entity: "",
					occurrence: "",
					on: ""
				},
				and: {
					entity: "",
					occurrence: "",
					on: ""
				}
			});

			Ext.Object.each(i_record.data, function(s_key) {

				var value = i_record.get(s_key);

				switch (s_key) {
					case "betweenEntity":
						o_relation.between.entity = value;
					break;
					case "betweenOn":
						if (i_record.get("betweenOccur") != "many" || i_record.get("andOccur") != "many") {
							o_relation.between.on = i_self.buildColumnObj(value);
						}
					break;
					case "betweenOccur":
						o_relation.between.occurrence = value;
					break;
					case "andEntity":
						o_relation.and.entity = value;
					break;
					case "andOn":
						if (i_record.get("betweenOccur") != "many" || i_record.get("andOccur") != "many") {
							o_relation.and.on = i_self.buildColumnObj(value);
						}
					break;
					case "andOccur":
						o_relation.and.occurrence = value;
					break;
					case "betweenEntityWas":
					case "andEntityWas":
						if (value.length > 0) {
							o_relation.was = value;
						}
					break;
					case "columns":
						if (!Ext.isEmpty(value)) {
							o_relation[s_key] = value;
						}
					break;
					case "drop":
					case "cardinality":
					break;
					default:
						o_relation[s_key] = value;
					break;
				}
			});

			Ext.apply(o_relation, i_record.getData());

			if (i_record.get("betweenEntity") == o_entity.name) {
				o_relation.entityName = i_record.get("andEntity");
			}
			else if (i_record.get("andEntity") == o_entity.name) {
				o_relation.entityName = i_record.get("betweenEntity");
			}

			a_result.push(o_relation);
		});

		return a_result;
	},

	doSave: function(o_entity) {

		var i_self = this;

		// add relation object in entire entity object
		var i_relationGrid = i_self.getRelationGrid();
		var i_store = i_relationGrid.getStore();
		var a_records = i_store.getRange();
		var a_result = [];

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

			var o_relation = Ext.apply({}, {
				was: "",
				between: {
					entity: "",
					occurrence: "",
					on: ""
				},
				and: {
					entity: "",
					occurrence: "",
					on: ""
				}
			});

			var o_data = i_record.getData();

			Ext.Object.each(o_data, function(s_key, value) {

				switch (s_key) {
					case "betweenEntity":
						o_relation.between.entity = value;
					break;
					case "betweenOn":
						if (i_record.get("betweenOccur") != "many" || i_record.get("andOccur") != "many") {
							o_relation.between.on = i_self.buildColumnObj(value);
						}
					break;
					case "betweenOccur":
						o_relation.between.occurrence = value;
					break;
					case "andEntity":
						o_relation.and.entity = value;
					break;
					case "andOn":
						if (i_record.get("betweenOccur") != "many" || i_record.get("andOccur") != "many") {
							o_relation.and.on = i_self.buildColumnObj(value);
						}
					break;
					case "andOccur":
						o_relation.and.occurrence = value;
					break;
					case "betweenEntityWas":
					case "andEntityWas":
						if (value.length > 0) {
							o_relation.was = value;
						}
					break;
					case "columns":
						if (!Ext.isEmpty(value)) {
							o_relation[s_key] = value;
						}
					break;
					case "drop":
					case "cardinality":
					break;
					default:
						o_relation[s_key] = value;
					break;
				}
			});

			if (o_relation) {
				var o_temp = Ext.Array.findBy(a_result, function (o_config) {
					return o_config.between.entity == o_relation.between.entity && o_config.and.entity == o_relation.and.entity;
				});

				if (!o_temp) {
					a_result.push(o_relation);
				}
			}
		});

		return a_result;
	},

	buildColumnObj: function(data) {

		var a_columns = [];

		if (Ext.isArray(data)) {
			Ext.Array.each(data, function(o_value) {
				var o_column = {
					name: o_value.name
				};
				a_columns.push(o_column);
			});
		}

		return a_columns;
	}
});
