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

	extend: "Ext.tree.Panel",

	alias: [
		"widget.ip2DomainModelEntityFormDesignerTreeGrid"
	],

	useArrows: true,
	
	rootVisible: false,
	
	multiSelect: false,
	
	singleExpand: false,

	bufferedRenderer: true,

	config: {
		uiName: "portfolio",
		entity: null,
		entityManager: null,
		keys: {},
		designer: null,
		formCollections: null,
		currentForm: null
	},

	requires: [
		"Portfolio.designer.model.domainModelEntityFormDesignerTreeDataModel",
		"Portfolio.designer.controller.domainModelEntityFormDesignerTreeGrid"
	],

	controller: "designer.controller.domainModelEntityFormDesignerTreeGrid",

	viewConfig: {
		plugins: {
			ptype: "treeviewdragdrop",
			dragGroup: "form"
		}
	},

	initComponent: function() {

		var i_self = this;

		var a_TreeColumns = [
			{
				xtype: "treecolumn",
				text: ip2.i18n("name"),
				flex: 2,
				sortable: true,
				dataIndex: "properties",
				renderer: function(value) {
					var s_value = value.name;
					return ip2.i18n(s_value, value.name);
				}
			},
			{
				text: ip2.i18n("title"),
				flex: 1,
				sortable: true,
				dataIndex: "title",
				renderer: function(value, i_cell, i_record) {

					var o_properties = i_record.get("properties") || {};

					var s_value = o_properties.title;
					return ip2.i18n(s_value, value);
				}
			}
		];

		var s_uiName = i_self.getUiName();
		var o_entity = i_self.getEntity();

		// build json for tree store
		if (!o_entity.ui) {
			o_entity.ui = {};
		}

		if (!o_entity.ui.forms) {
			o_entity.ui.forms = {};
		}

		if (!o_entity.ui.forms[s_uiName]) {
			o_entity.ui.forms[s_uiName] = {
				items: {
					columns: []
				}
			};
		}

		if (o_entity.ui.forms.common) {
			o_entity.ui.forms.portfolio = Ext.Object.merge({}, o_entity.ui.forms.common, o_entity.ui.forms.portfolio);
			delete o_entity.ui.forms.common;
		}

		var o_entityRoot = {
			itemId: "entityRoot",
			expanded: true,
			allowDrop: false,
			allowDrag: false,
			properties: {
				nodeType: "entityRoot",
				name: {
					da: "Entitet",
					en: "Entity"
				}
			},
			children: [
				i_self.getEntityNode()
			]
		};

		var o_relationRoot = {
			itemId: "relation-root",
			expanded: false,
			allowDrop: false,
			allowDrag: false,
			properties: {
				nodeType: "relation-root",
				name: {
					da: "Relationer",
					en: "Relations"
				}
			},
			children: [
				{
					itemId: "relation-grids-root",
					expanded: false,
					allowDrop: false,
					allowDrag: false,
					properties: {
						nodeType: "relation-grids-root",
						name: {
							da: "Grids",
							en: "Grids"
						}
					},
					children: []
				},
				{
				itemId: "relation-fields-root",
				expanded: false,
				allowDrop: false,
				allowDrag: false,
				properties: {
					nodeType: "relation-fields-root",
					name: {
						da: "Felter",
						en: "Fields"
					}
				},
				children: []
			}
			]
		};

		var o_affiliationRoot = {
			itemId: "affiliation-root",
			expanded: false,
			allowDrop: false,
			allowDrag: false,
			properties: {
				nodeType: "affiliation-root",
				name: {
					da: "Tilhørsforhold",
					en: "Affiliations"
				}
			},
			children: []
		};

		// build columns and add first column
		var a_nodes = [];

		var o_relation_root = {
			itemId: "relation-root",
			leaf: false,
			expanded: false,
			allowDrop: true,
			allowDrag: false,
			properties: {
				nodeType: "relation-rooty",
				name: {
					da: "Relation",
					en: "Relation"
				}
			},
			children: []
		};

		a_nodes.push(o_relation_root);

		var o_affiliation_root = {
			itemId: "affiliation-root",
			leaf: false,
			expanded: false,
			allowDrop: true,
			allowDrag: false,
			properties: {
				nodeType: "affiliation-root",
				name: {
					da: "Tilhørsforhold",
					en: "Affiliations"
				}
			},
			children: []
		};

		a_nodes.push(o_affiliation_root);

		var o_view = o_entity.ui.forms[s_uiName];


		if (Ext.isObject(o_view.relation)) {

			var a_values = [];

			Ext.Object.each(o_view.relation, function(s_key, o_value) {

				a_values.push(o_value);
			});

			o_view.relation = a_values;
		}

		Ext.Array.each(o_view.relation, function(o_value) {

			var s_value = "relation-grid-" + o_value.entity + "-" + o_value.view;

			var o_config = Ext.apply({}, {
				itemId: s_value,
				leaf: true,
				allowDrop: false,
				allowDrag: true,
				sequence: o_value.sequence || -1,
				properties: {
					name: o_value.entity + " - " + o_value.view,
					nodeType: "relation-grid",
					title: o_value.title || "grid",
					view: o_value.view,
					index: o_value.index || 0,
					entityClass: o_value.entity,
					window: o_value.window || {}
				},
				children: []
			});

			o_relation_root.children.push(o_config);

			i_self.updateColumnsArray("add", s_value);
		});

		Ext.Array.each(o_view.affiliations, function(o_value) {

			var o_config = {
				itemId: "affiliation-" + o_value.name,
				iconCls: "ip2-designer-affiliation",
				leaf: true,
				allowDrop: false,
				allowDrag: true,
				sequence: o_value.sequence || -1,
				properties: {
					name: o_value.name,
					url: o_value.url,
					nodeType: "affiliation-item",
					index: o_value.index || 0,
					title: o_value.title
				},
				children: []
			};

			o_affiliation_root.children.push(o_config);

			i_self.updateColumnsArray("add", "affiliation-" + o_value.name);
		});

		var i_store = Ext.create("Ext.data.TreeStore", {
			model: "Portfolio.designer.model.domainModelEntityFormDesignerTreeDataModel",
			folderSort: false,
			root: {
				expanded: true,
				allowDrop: false,
				allowDrag: false,
				children: [
					o_entityRoot,
					o_relationRoot,
					o_affiliationRoot
				]
			}
		});

		Ext.apply(i_self, {
			store: i_store,
			columns: a_TreeColumns
		});

		i_self.callParent();

		i_self.on({
			afterrender: {
				fn: function(i_treepanel) {

					var i_store = i_treepanel.getStore();
					var a_records = i_store.getRange(0);

					Ext.Array.each(a_records, function(i_record) {
						i_record.commit();
					});
				},
				buffer: 10
			},
			itemcontextmenu: {
				fn: function(i_view, i_record, i_item, n_index, i_event) {

					var o_properties = i_record.get("properties");

					var o_parentProperties = i_record.parentNode.get("properties") || {
						nodeType: "root"
					};

					i_view.getSelectionModel().select(n_index);
					i_event.stopEvent();

					if (i_self.required) {
						return false;
					}
					var a_coords = i_event.getXY();

					var a_items = [];

					if (o_properties.nodeType == "field" && o_properties.hostiable &&
						o_parentProperties.entityClass != o_properties.entityClass) {

						a_items.push({
							xtype: "menuitem",
							text: ip2.i18n({
								da: "Tilføj property felt",
								en: "Add property field"
							}),
							itemId: "add-property-field",
							iconCls: "pf-add",
							handler: function () {

								var i_controller = i_self.getController();

								i_controller.onCreatePropertyField(i_record, o_entity);
							}
						});
					}

					if (a_items.length > 0) {
						var i_menu = Ext.widget("menu", {
							items: a_items
						});

						i_menu.showAt([a_coords[0], a_coords[1]]);
					}
				}
			},
			newColumns: {
				fn: function() {
					//i_self.getEntityFields();
				}
			},
			newAffiliations: {
				fn: function() {
					i_self.getAffiliationNodes();
				}
			},
			newRelations: {
				fn: function() {
					i_self.doRelationUpdate();
				}
			},
			updateAffiliation: {
				fn: function(i_tree, o_data) {

					var i_root = i_tree.getRootNode();
					var i_node = i_root.findChild("itemId", "affiliation-" + o_data.name, true);

					if (i_node) {
						var o_properties = i_node.get("properties");
						Ext.apply(o_properties, o_data);
						i_node.set("properties", o_properties);
						i_node.commit();
					}
				}
			},
			updateRelation: {
				fn: function (i_treepanel, i_record) {

					i_self.doRelationUpdate();
				}
			},
			updateColumn: {
				fn: function (s_old, s_new) {

					var i_self = this;
					var i_root = i_self.getRootNode();

					var i_node = i_root.findChild("itemId", s_old, true);

					if (i_node) {

						var o_properties = i_node.get("properties");

						Ext.apply(o_properties, {
							name: s_new
						});

						i_node.set({
							itemId: s_new,
							properties: o_properties
						});

						i_node.commit();

						i_self.updateColumnsArray("remove", s_old);
						i_self.updateColumnsArray("add", s_new);

					}
				}
			},
			removeColumn: {
				fn: function (s_column) {

					var i_self = this;
					i_self.removeColumn(s_column);
				}
			},
			removeRelation: {
				fn: function(i_treepanel, s_entity) {

					var i_self = this;

					i_self.removeRelation(s_entity);

					return true;
				}
			},
			removeAffiliation: {
				fn: function(i_treepanel, s_name) {

					var i_self = this;

					i_self.removeAffiliation(s_name);

					return true;
				}
			},
			entityChange: {
				fn: function(i_tree, o_values) {

					var i_root = i_tree.getRootNode();
					var i_entityNode = i_root.findChild("isEntityNode", true, true);
					var s_entity = "";

					if (i_entityNode) {

						var o_properties = i_entityNode.get("properties");

						s_entity = o_properties.entityClass;

						o_properties = Ext.apply(o_properties, {
							title: o_values.title
						});

						i_entityNode.set("properties", o_properties);
						i_entityNode.commit();
					}
				}
			},
			syncTrees: {
				fn: function(o_config) {

					var i_self = this;

					var a_fields = o_config.fields;
					var a_grids = o_config.grids;
					var a_widgets = o_config.widgets;
					var a_affiliations = o_config.affiliations;

					Ext.Array.each(a_fields, function(o_field) {
						if (o_field.relation) {
							i_self.updateColumnsArray("remove", "relation-field-" + o_field.name);
						}
						else {
							i_self.updateColumnsArray("remove", o_field.name);
						}
					});

					Ext.Array.each(a_grids, function (o_grid) {
						i_self.updateColumnsArray("remove", "relation-grid-" + o_grid.entityClass + "-" + o_grid.view);
					});

					Ext.Array.each(a_widgets, function (o_widget) {
						i_self.updateColumnsArray("remove", o_widget.itemId);
					});

					Ext.Array.each(a_affiliations, function (o_field) {
						i_self.updateColumnsArray("remove", o_field.name);
					});

					if (!o_config.pd) {
						i_self.getEntityFields();
						i_self.doRelationUpdate();
						i_self.getAffiliationNodes();
					}
					else {

						var i_root = i_self.getRootNode();
						var i_entityRoot = i_root.findChild("itemId", "entity-" + o_entity.name, true);

						var i_entityManager = i_self.getEntityManager();
						var i_grid = i_entityManager.columnManager.columnGrid;
						
						var i_store = i_grid.getStore();
						var a_records = i_store.getData().getRange();

						var i_record = Ext.Array.findBy(a_records, function(i_record) {
							return i_record.get("pd");
						});
						
						var i_pdNode = i_entityRoot.findChild("itemId", i_record.get("name"), true);

						var a_children = i_pdNode.childNodes;

						Ext.Array.each(a_children, function(i_node) {

							var o_properties = i_node.get("properties") || {};
							i_self.updateColumnsArray("remove", o_properties.name);

						});
						
						var s_fcid = i_self.getCurrentForm();
						
						var a_definition = Portfolio.pd.util.Cache.load(i_record.get("pd"));

						var o_data = {
							fcid: s_fcid
						};

						var o_form = Portfolio.pd.util.Handler.createFormCollection(o_data, a_definition, true);
						var a_temp = [];

						Ext.Object.each(o_form, function(s_key, o_def) {

							var o_result;

							if (!i_self.columnAlreadyExists(o_def.name)) {

								if (o_def.type == "collection" || o_def.type == "group") {
									o_result = Portfolio.pd.util.Handler.createCollection(o_def, a_definition, {});
								}
								else {
									o_result = Portfolio.pd.util.Handler.createProperty(o_def, a_definition, {});
								}

								i_self.updateColumnsArray("add", o_result.name);

								var s_nodetype = "pd-field";

								if (o_def.type == "collection" || o_def.type == "group") {
									s_nodetype = o_def.apperence == "group" ? "pd-group" : "pd-field";
								}

								a_temp.push({
									itemId: o_result.name,
									iconCls: o_result.type == "property" ? "pf-element" : "pf-elements",
									leaf: true,
									allowDrop: false,
									allowDrag: true,
									properties: Ext.apply({
										nodeType: s_nodetype,
										name: o_result.name,
										title: o_result.label || o_result.name,
										field: i_entityRoot.itemId
									}, o_result)
								});

							}
						});

						i_pdNode.collapse();
						i_pdNode.removeAll(false);
						i_pdNode.appendChild(a_temp);
						i_pdNode.expand();

					}
				}
			},
			syncup: {
				fn: function(i_tree, o_layoutKeys) {

					i_self.doSync(o_layoutKeys);
				}
			},
			collectionchange: {
				fn: function(newForm, oldForm) {

					newForm = newForm || oldForm;

					var o_entity = i_self.getEntity();

					var i_root = i_self.getRootNode();
					var i_entityRoot = i_root.findChild("itemId", "entity-" + o_entity.name, true);

					var i_entityManager = i_self.getEntityManager();
					var i_grid = i_entityManager.columnManager.columnGrid;
					
					var i_store = i_grid.getStore();
					var a_records = i_store.getData().getRange();

					var i_record = Ext.Array.findBy(a_records, function(i_record) {
						return i_record.get("pd");
					});
					
					var i_pdNode = i_entityRoot.findChild("itemId", i_record.get("name"), true);

					if (!i_pdNode) {

						ip2.messageBox({
							title: "Error",
							message: ip2.i18n({
								da: "Den given node {name} må ikke være anvendt i UI",
								en: "The given node {name} must not be used in the UI" 
							}).replace("{name}", i_record.get("name"))
						});
					}
					else {
						var a_children = i_pdNode.childNodes;

						Ext.Array.each(a_children, function(i_node) {

							var o_properties = i_node.get("properties") || {};
							i_self.updateColumnsArray("remove", o_properties.name);

						});

							
						var a_definition = Portfolio.pd.util.Cache.load(i_record.get("pd"));

						var o_data = {
							fcid: newForm
						};

						var o_config = Portfolio.pd.util.Handler.createFormCollection(o_data, a_definition, true);
						var a_temp = [];

						Ext.Object.each(o_config, function(s_key, o_def) {

							var o_result;

							if (!i_self.columnAlreadyExists(o_def.name)) {

								if (o_def.type == "collection" || o_def.type == "group") {
									o_result = Portfolio.pd.util.Handler.createCollection(o_def, a_definition, {});
								}
								else {
									o_result = Portfolio.pd.util.Handler.createProperty(o_def, a_definition, {});
								}

								i_self.updateColumnsArray("add", o_result.name);

								var s_nodetype = "pd-field";

								if (o_def.type == "collection" || o_def.type == "group") {
									s_nodetype = o_def.apperence == "group" ? "pd-group" : "pd-field";
								}

								a_temp.push({
									itemId: o_result.name,
									iconCls: o_result.type == "property" ? "pf-element" : "pf-elements",
									leaf: true,
									allowDrop: false,
									allowDrag: true,
									properties: Ext.apply({
										nodeType: s_nodetype,
										name: o_result.name,
										title: o_result.label || o_result.name,
										field: i_entityRoot.itemId
									}, o_result)
								});

							}
						});

						i_pdNode.collapse();
						i_pdNode.removeAll(false);
						i_pdNode.appendChild(a_temp);
						i_pdNode.expand();
					}

					i_self.setCurrentForm(newForm);
				}
			}
		});

		i_self.getEntityFields();
		i_self.doRelationUpdate();
		i_self.getAffiliationNodes();
	},

	createLayoutMenu: function(i_record, s_region) {

		var i_self = this;

		var i_menuitem = Ext.widget("menuitem", {
			text: ip2.i18n({
				da: "Tilføj",
				en: "Add"
			}),
			iconCls: "pf-add",
			menu: {
				items: i_self.createLayoutMenuItems(i_record, s_region)
			}
		});

		return i_menuitem;
	},

	createLayoutMenuItems: function(i_record, s_region) {

		var i_self = this;

		var a_items = [
			{
				xtype: "menuitem",
				text: "Border",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("border", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			},
			{
				xtype: "menuitem",
				text: "Fit",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("fit", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			},
			{
				xtype: "menuitem",
				text: "Anchor",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("anchor", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			},
			{
				xtype: "menuitem",
				text: "H Box",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("hbox", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			},
			{
				xtype: "menuitem",
				text: "V Box",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("vbox", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			},
			{
				xtype: "menuitem",
				text: "Tabpanel",
				handler: function(i_button) {
					var o_config = i_self.createLayoutNode("tabpanel", s_region);
					var i_layout = i_record.appendChild(o_config);
					i_layout.commit();
					i_record.expand();
				}
			}
		];
		return a_items;
	},

	createBorderMenu: function(i_record) {

		var i_self = this;

		var a_children = i_record.childNodes;

		var a_items = [];

		var a_regions = ["center", "west", "east", "north", "south"];

		Ext.Array.each(a_regions, function(s_region) {

			var b_found = false;

			Ext.Array.each(a_children, function(i_child) {
				var o_properties = i_child.get("properties");

				if (o_properties.region == s_region) {
					b_found = true;
					return false;
				}
			});
			if (!b_found) {

				var i_return = i_self.createLayoutMenu(i_record, s_region);

				var i_item = Ext.widget("menuitem", {
					text: s_region,
					menu: {
						items: i_return.menu.items.getRange()
					}
				});
				a_items.push(i_item);
			}
		});

		var i_menuitem = Ext.widget("menuitem", {
			text: ip2.i18n({
				da: "Tilføj",
				en: "Add"
			}),
			iconCls: "pf-add",
			menu: {
				items: a_items
			}
		});
		return i_menuitem;
	},

	createLayoutNode: function(s_type, s_region, o_inital) {

		var i_self = this;

		if (o_inital && !Ext.isObject(o_inital)) {
			return {
				itemId: "layout-item-" + o_inital,
				text: o_inital,
				leaf: true,
				allowDrag: false,
				allowDrop: false,
				properties: {
					type: o_inital,
					name: o_inital,
					nodeType: "layoutItem"
				},
				children: []
			};
		}

		o_inital = o_inital || {};

		var o_properties = Ext.applyIf(o_inital, {
			type: s_type,
			name: s_type,
			split: true,
			flex: 1,
			collapsible: false,
			collapsed: false,
			title: "",
			border: false,
			bodyPadding: 0,
			width: 0,
			height: 0,
			minWidth: 0,
			maxWidth: 0,
			minHeight: 0,
			maxHeight: 0,
			defaults: undefined,
			nodeType: "uiLayout"
		});

		s_type = o_properties.type;
		s_region = o_properties.region || s_region;

		var a_children = o_properties.items || [];

		var a_result = [];

		Ext.Array.each(a_children, function(o_child) {
			var o_layout = i_self.createLayoutNode(null, null, o_child);
			a_result.push(o_layout);
		});

		var o_config = {
			text: s_type,
			leaf: false,
			expanded: false,
			allowDrag: true,
			allowDrop: false,
			properties: o_properties,
			children: [{
				text: "items",
				allowDrag: false,
				allowDrop: s_type != "border" ? true : false,
				properties: {
					name: "items",
					title: "items",
					nodeType: "collection"
				},
				children: a_result
			}]
		};

		if (s_type == "anchor") {
			o_config.properties.autoScroll = true;
		}

		if (s_region) {
			o_config.properties.region = s_region;
			o_config.properties.name = s_type + " ( <strong>" + s_region + "</strong> )";
		}

		return o_config;
	},

	getEntityFields: function () {

		var i_self = this;
		var o_entity = i_self.getEntity();
		var i_entityManager = i_self.getEntityManager();
		var i_grid = i_entityManager.columnManager.columnGrid;
		var i_store = i_grid.getStore();
		var i_root = i_self.getRootNode();
		var a_range = i_store.getRange();
		var i_entityNode = i_root.findChild("itemId", "entity-" + o_entity.name, true);
		  

		if (i_entityNode) {
			Ext.Array.each(a_range, function (i_record) {

				if (!i_self.columnAlreadyExists(i_record.get("name"))) {
					  i_self.updateColumnsArray("add", i_record.get("name"));

					  var o_field = {
						itemId: i_record.get("name"),
						iconCls: "ip2-designer-field",
						leaf: true,
						allowDrop: false,
						allowDrag: true,
						properties: {
							nodeType: "field",
							name: i_record.get("name"),
							title: (i_record.get("title")) ? i_record.get("title") : i_record.get("name"),
							entityClass: o_entity.name
						}
					};

					i_entityNode.appendChild(o_field);
				}
			});
		}
	},

	getEntityNode: function() {

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

		var o_config = {
			itemId: "entity-" + o_entity.name,
			iconCls: "ip2-designer-entity",
			loaded: true,
			leaf: false,
			allowDrag: false,
			allowDrop: true,
			isEntityNode: true,
			properties: {
				nodeType: "entity",
				name: o_entity.name,
				title: o_entity.title,
				entityClass: o_entity.name
			},
			children: []
		};

		return o_config;
	},

	createRelationGrids: function() {

		var i_self = this;
		var i_designer = i_self.getDesigner();
		var o_model = i_designer.model;
		var i_entityManager = i_self.getEntityManager();
		var i_relationManager = i_entityManager.getRelationManager();
		var i_store = i_self.getStore();
		var i_model = i_store.getModel();
		var o_entity = i_self.getEntity();

		var a_relations = i_relationManager.getParentRelation();

		var i_root = i_self.getRootNode();

		var i_relationRoot = i_root.findChild("itemId", "relation-root", true);

		var i_gridRoot = i_root.findChild("itemId", "relation-grids-root", true);

		var a_entities = o_model.required;

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

			var o_properties = o_relation.properties || {};

			var o_relationEntity = Ext.Array.findBy(a_entities, function(o_value) {
				return o_value.name == o_relation.entityName;
			});

			if (o_relationEntity) {

				var b_found = i_self.columnAlreadyExists("relation-root-grid-" + o_relationEntity.name);

				var i_child = i_root.findChild("itemId", "relation-root-grid-" + o_relationEntity.name, true);

				var s_title = o_properties.title ? o_properties.title : o_relationEntity.title;

				if (!b_found) {
					if (
							(o_relation.between.entity == o_entity.name && o_relation.between.occurrence == "one") ||
							(o_relation.and.entity == o_entity.name && o_relation.and.occurrence == "one")
						) {

						var s_occurence = "";

						if (o_relation.between.entity == o_entity.name) {
							s_occurence = o_relation.and.occurrence;
						}
						else {
							s_occurence = o_relation.between.occurrence;
						}

						if (s_occurence == "many") {

							var s_name = o_properties.as ? o_properties.as : o_relationEntity.name;

							var i_record = i_model.create({
								itemId: "relation-root-grid-" + o_relationEntity.name,
								iconCls: "ip2-designer-parentRelation",
								leaf: true,
								allowDrop: true,
								allowDrag: false,
								properties: {
									name: s_name,
									nodeType: "relation-root-grid",
									title: ip2.i18n(s_title),
									entityClass: o_relationEntity.name
								},
								children: []
							});

							i_self.updateColumnsArray("add", "relation-root-grid-" + o_relationEntity.name);

							Ext.Object.each(o_relationEntity.ui.grids, function(s_view) {

								if (!i_self.columnAlreadyExists("relation-grid-" + o_relationEntity.name + "-" + s_view)) {

									var o_window = o_relation.window || {};

									var o_size = Portfolio.util.Handler.getWindowSize();

									if (Ext.isBoolean(o_window) && o_window) {
										o_window = {
											width: o_size.width * 0.9,
											height: o_size.height * 0.9
										};
									}

									var i_child = i_model.create({
										itemId: "relation-grid-" + o_relationEntity.name + "-" + s_view,
										leaf: true,
										allowDrop: false,
										allowDrag: true,
										properties: {
											name: s_name + " - " + s_view,
											nodeType: "relation-grid",
											title: "view",
											view: s_view,
											cid: o_relation.cid,
											index: o_relation.index || 0,
											entityClass: o_relationEntity.name,
											window: o_window
										}
									});

									i_record.appendChild(i_child);

									i_self.updateColumnsArray("add", "relation-grid-" + o_relationEntity.name + "-" + s_view);
								}
							});

							i_gridRoot.appendChild(i_record);
						}
					}
				}
				else {
					if (i_child) {
						if (
								(o_relation.between.entity == o_entity.name && o_relation.between.occurrence == "one") ||
								(o_relation.and.entity == o_entity.name && o_relation.and.occurrence == "one")
							) {
							var s_occurence = "";

							if (o_relation.between.entity == o_entity.name) {
								s_occurence = o_relation.and.occurrence;
							}
							else {
								s_occurence = o_relation.between.occurrence;
							}

							if (s_occurence == "many") {

								Ext.Object.each(o_relationEntity.ui.grids, function (s_view) {

									if (!i_self.columnAlreadyExists("relation-grid-" + o_relationEntity.name + "-" + s_view)) {

										var o_window = o_relation.window || {};

										var o_size = Portfolio.util.Handler.getWindowSize();

										if (Ext.isBoolean(o_window) && o_window) {
											o_window = {
												width: o_size.width * 0.9,
												height: o_size.height * 0.9
											};
										}

										var i_gridView = i_model.create({
											itemId: "relation-grid-" + o_relationEntity.name + "-" + s_view,
											leaf: true,
											allowDrop: false,
											allowDrag: true,
											properties: {
												name: o_relationEntity.name + " - " + s_view,
												nodeType: "relation-grid",
												title: o_relation.title || "view",
												view: s_view,
												cid: o_relation.cid,
												index: o_relation.index || 0,
												entityClass: o_relationEntity.name,
												window: o_window
											}
										});

										i_child.appendChild(i_gridView);

										i_self.updateColumnsArray("add", "relation-grid-" + o_relationEntity.name + "-" + s_view);
									}
								});
							}
						}
					}
				}
			}
		});

		i_relationRoot.collapse();
		i_relationRoot.expand();

		i_gridRoot.collapse();
		i_gridRoot.expand();
	},

	createRelationFields: function() {

		var i_self = this;
		var i_designer = i_self.getDesigner();
		var o_model = i_designer.model;
		var i_entityManager = i_self.getEntityManager();
		var i_relationManager = i_entityManager.getRelationManager();
		var i_store = i_self.getStore();
		var i_model = i_store.getModel();
		var o_entity = i_self.getEntity();

		var a_relations = i_relationManager.getParentRelation();

		var i_root = i_self.getRootNode();

		var i_relationRoot = i_root.findChild("itemId", "relation-root", true);

		var i_fieldRoot = i_root.findChild("itemId", "relation-fields-root", true);

		var a_entities = o_model.required;

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

			var o_properties = o_relation.properties || {};

			var o_relationEntity = Ext.Array.findBy(a_entities, function(o_value) {
				return o_value.name == o_relation.entityName;
			});

			if (o_relationEntity) {

				var s_name = o_properties.as ? o_properties.as : o_relationEntity.name;

				var b_found = i_self.columnAlreadyExists("relation-field-" + s_name);

				var i_child = i_root.findChild("itemId", "relation-field-" + s_name, true);

				var s_title = o_properties.title ? o_properties.title : o_relationEntity.title;

				if (!b_found) {
					if (
							(o_relation.between.entity == o_entity.name && o_relation.between.occurrence == "many") ||
							(o_relation.and.entity == o_entity.name && o_relation.and.occurrence == "many")
						) {

						var s_occurence = "";

						if (o_relation.between.entity == o_entity.name) {
							s_occurence = o_relation.and.occurrence;
						}
						else {
							s_occurence = o_relation.between.occurrence;
						}

						if (s_occurence == "one") {

							var i_record = i_model.create({
								itemId: "relation-field-" + s_name,
								iconCls: "ip2-designer-relation-field",
								leaf: true,
								allowDrop: false,
								allowDrag: true,
								properties: {
									name: s_name,
									nodeType: "field",
									relation: true,
									title: s_title,
									entityClass: o_relationEntity.name
								}
							});

							i_self.updateColumnsArray("add", "relation-field-" + s_name);

							var i_node = i_fieldRoot.appendChild(i_record);
						}
					}
				}
				else {
					if (i_child) {
						if (
								(o_relation.between.entity == o_entity.name && o_relation.between.occurrence == "many") ||
								(o_relation.and.entity == o_entity.name && o_relation.and.occurrence == "many")
							) {
							var s_occurence = "";

							if (o_relation.between.entity == o_entity.name) {
								s_occurence = o_relation.and.occurrence;
							}
							else {
								s_occurence = o_relation.between.occurrence;
							}

							if (s_occurence == "one") {

								var o_childProperties = i_child.get("properties");

								Ext.apply(o_childProperties, {
									name: o_properties.as ? o_properties.as : o_relationEntity.name
								});
							}
						}
					}
				}
			}
		});

		i_relationRoot.collapse();
		i_relationRoot.expand();

		if (i_fieldRoot.childNodes.length > 0) {

			i_fieldRoot.collapse();
			i_fieldRoot.expand();
		}
	},

	doUpdateEntites: function() {

		var i_self = this;
		var i_entityManager = i_self.getEntityManager();
		var a_relation = i_entityManager.relationManager.getParentRelation();
		var i_designer = i_self.getDesigner();
		var o_model = i_designer.model;
		var i_root = i_self.getRootNode();
		var i_store = i_self.getStore();
		var i_model = i_store.getModel();

		var i_entityRoot = i_root.findChild("itemId", "relation-root", true);

		var a_entities = o_model.required;

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

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

			if (o_entity) {

				var s_title = (o_relation.properties.title) ? o_relation.properties.title : o_entity.title;

				var i_child = i_model.create({
					itemId: "entity-" + o_entity.name,
					iconCls: "ip2-designer-entity",
					leaf: false,
					allowDrop: true,
					allowDrag: false,
					properties: {
						name: o_entity.name,
						nodeType: "entity",
						title: ip2.i18n(s_title),
						entityClass: o_entity.name
					},
					children: []
				});

				i_entityRoot.appendChild(i_child);

				Ext.Array.each(o_entity.columns, function(o_column) {
					if (!i_self.columnAlreadyExists(o_column.name)) {

						var o_field = {
							itemId: o_column.name,
							iconCls: "ip2-designer-relation-field",
							leaf: true,
							allowDrop: false,
							allowDrag: true,
							properties: {
								nodeType: "field",
								name: o_column.name,
								from: o_entity.name,
								as: o_column.name,
								entityClass: o_entity.name,
								title: o_column.title
							}
						};

						i_child.appendChild(o_field);
					}
				});
			}
		});

		i_entityRoot.collapse();
		i_entityRoot.expand();
	},

	doRelationUpdate: function() {

		var i_self = this;

		i_self.createRelationGrids();
		i_self.createRelationFields();
	},

	getAffiliationNodes: function() {

		var i_self = this;
		var i_entityManager = i_self.getEntityManager();
		var i_store = i_self.getStore();
		var i_model = i_store.getModel();

		var i_manager = i_entityManager.getAffiliationManager();
		var i_managerStore = i_manager.getStore();
		var a_affiliations = i_managerStore.getRange();

		var i_root = i_self.store.getRootNode();

		var i_affiliationRoot = i_root.findChild("itemId", "affiliation-root", true);

		Ext.Array.each(a_affiliations, function(i_affiliation) {

			if (!i_self.columnAlreadyExists("affiliation-" + i_affiliation.get("name"))) {
				var title = i_affiliation.get("title");

				var i_record = i_model.create({
					itemId: "affiliation-" + i_affiliation.get("name"),
					iconCls: "ip2-designer-affiliation",
					leaf: true,
					allowDrop: false,
					allowDrag: true,
					properties: {
						name: i_affiliation.get("name"),
						url: i_affiliation.get("url"),
						nodeType: "affiliation-item",
						index: 0,
						title: ip2.i18n(title),
						component: i_affiliation.get("component") || {}
					},
					children: []
				});

				i_affiliationRoot.appendChild(i_record);
				i_self.updateColumnsArray("add", "affiliation-" + i_affiliation.get("name"));
			}
		});

		i_affiliationRoot.collapse();
		i_affiliationRoot.expand();
	},

	removeColumn: function(s_column) {

		var i_self = this;
		var i_root = i_self.getRootNode();

		var i_record = i_root.findChild("itemId", s_column, true);

		if (i_record) {
			i_record.remove();
			i_self.updateColumnsArray("remove", s_column);
		}
	},

	removeAffiliation: function(s_name) {

		var i_self = this;
		var i_root = i_self.getRootNode();
		var a_toRemove = [];

		i_root.cascadeBy(function(i_record) {

			var o_values = i_record.get("properties") || {};

			if (o_values.nodeType == "affiliation-item") {

				if (o_values.name == s_name) {

					if (a_toRemove.indexOf(i_record.get("itemId")) < 0) {
						a_toRemove.push(i_record.get("itemId"));
					}
				}
			}
		});

		a_toRemove = Ext.Array.filter(a_toRemove, function(value) {
			return value;
		});

		Ext.Array.each(a_toRemove, function(s_node) {
			i_self.removeColumn(s_node);
		});
	},

	removeRelation: function(s_entity) {

		var i_self = this;
		var i_root = i_self.getRootNode();
		var a_toRemove = [];

		i_root.cascadeBy(function(i_record) {

			var o_values = i_record.get("properties") || {};

			if (o_values.entityClass == s_entity) {

				if (a_toRemove.indexOf(i_record.get("itemId")) < 0) {

					a_toRemove.push(i_record.get("itemId"));
				}
			}
		});

		a_toRemove = Ext.Array.filter(a_toRemove, function(value) {
			return value;
		});

		a_toRemove.reverse();

		Ext.Array.each(a_toRemove, function(s_node) {
			i_self.removeColumn(s_node);
		});
	},

	updateColumnsArray: function(s_action, s_column) {

		var i_self = this;
		var o_keys = i_self.getKeys();
		var n_index = -1;

		switch (s_action) {
			case "add":
				n_index = o_keys.column.indexOf(s_column);
				if (n_index < 0) {
					o_keys.column.push(s_column);
				}
				break;
			case "remove":
				n_index = o_keys.column.indexOf(s_column);
				if (n_index > -1) {
					o_keys.column.splice(n_index, 1);
				}
				break;
		}
	},

	doSync: function(o_layoutKeys) {

		var i_self = this;
		var o_keys = Ext.clone(i_self.getKeys());

		var a_columns = Ext.Array.clone(o_keys.column);
		var a_layoutColumns = Ext.Array.clone(o_layoutKeys.column);

		var i_root = i_self.getRootNode();

		Ext.Array.each(a_layoutColumns, function(s_key) {

			var i_node = i_root.findChild("itemId", s_key, true);

			if (i_node) {
				i_node.remove(false);
			}
		});

		var a_diff = Ext.Array.difference(a_columns, a_layoutColumns);

		o_keys.column = a_layoutColumns.concat(a_diff);
		i_self.setKeys(o_keys);
	},

	columnAlreadyExists: function(s_column) {

		var i_self = this;
		var o_keys = i_self.getKeys();
		return o_keys.column.indexOf(s_column) > -1;
	}
});
