Ext.define('Ext.ux.folderorganizer.FolderPropertyGrid', {
	extend: 'Ext.grid.Panel',
	alias: ['widget.folderorganizerFolderPropertyGrid'],
	border: false,
	height: 144,
	collapsible: true,
	titleCollapse: true,
	autoScoll: true,
	initComponent: function() {
		var me = this;

		me.uiName = 'organizer';
		me.language = ip2.session.getLanguage();

		me.model = ip2.model({
			dmd: me.wrapper.dmdPath,
			entityName: 'WSHITMET00',
			dataLibrary: me.wrapper.folder.dataLibrary || ''
		});
		me.entity = me.wrapper.entity;
		me.dmdName = me.wrapper.dmdPath.split(".").shift();
		var i_proxy = me.model.getProxy();
		i_proxy.url = me.wrapper.folder.proxy;
		me.model.owner = {
			id: me.itemId,
			xtype: me.xtype
		};
		Ext.apply(i_proxy.extraParams, {
			action: me.action
		});
		me.store = Ext.create('Ext.data.Store', {
			model: me.model,
			listeners: {
				beforeload: function(store) {
					var i_proxy = store.getProxy();
					var o_extraParams = i_proxy.getExtraParams();
					o_extraParams.action = me.action;
					o_extraParams.folder;
					var selectedTreeNode = me.wrapper.treegrid.getSelectionModel().selected.items[0];
					if (selectedTreeNode) {
						o_extraParams.folder = selectedTreeNode.data.ID;
					}
				},
				load: function(store, records) {
					store.productKeys = [];

					for (var i = 0; i < records.length; i++) {
						store.productKeys.push(records[i].data.ITMITMTKN);
					}
				}
			}
		});

		me.columns = me.buildGridColumns();
		var b_dragAndDrop = ip2.isAccessible("app." + me.dmdName + ".data." + me.entity + ".update");

		me.viewConfig = {
			plugins: {
				ptype: 'gridviewdragdrop',
				ddGroup: 'organizerItems',
				enableDrag: b_dragAndDrop,
				enableDrop: b_dragAndDrop,
				appendOnly: false,
				onViewRender: function(view) {
					var dnd = this;

					if (dnd.enableDrag) {
						dnd.dragZone = Ext.create('Ext.view.DragZone', {
							view: view,
							name: me.itemId,
							ddGroup: dnd.dragGroup || dnd.ddGroup,
							dragText: dnd.dragText,
							isPreventDrag: function(e, record, item, index) {
								return (record.data.IRLRELTYP == 'cat' && me.getTreeNodeType() == 'itm') ? true : false;
							}
						});
					}

					if (dnd.enableDrop) {
						dnd.dropZone = Ext.create('Ext.grid.ViewDropZone', {
							view: view,
							ddGroup: dnd.dropGroup || dnd.ddGroup,
							onNodeOver: function(node, dragZone, e, data) {
								var s_entity = me.wrapper.treegrid.entity;
								var dnd = this;
								var view = dnd.view;
								var draggingRecords = data.records;
								var i_proto = Ext.dd.DropZone.prototype;
								var s_allowed = i_proto.dropAllowed;

								draggingRecords[0].allowDrop = true;

								if (!Ext.Array.contains(data.records, dnd.view.getRecord(node))) {
									dnd.positionIndicator(node, data, e);
								}

								// if related product - then drop after 'cat' relationtype is not allowed
								if (me.itemId == 'relatedPropertyGrid') {
									var pos = dnd.getPosition(e, node);
									var overRecord = view.getRecord(node);

									if (!Ext.Array.contains(draggingRecords, overRecord) &&
									pos == 'after' && !dnd.containsRecordAtOffset(draggingRecords, overRecord, 1)
									) {
										if (overRecord.data.IRLRELTYP == 'cat' && me.getTreeNodeType() == 'itm') {
											draggingRecords[0].allowDrop = false;
											return false;
										}
									}
								}

								// Tree node ?
								if (!me.isDropAllow(draggingRecords[0])) {
									draggingRecords[0].allowDrop = false;
									s_allowed = i_proto.dropNotAllowed;
								}

								return s_allowed;
							},
							onContainerOver: function(dd, e, data) {
								var dnd = this;
								var view = dnd.view;
								var count = view.store.getCount();
								var draggingRecords = data.records;
								var i_proto = Ext.dd.DropZone.prototype;
								var s_allowed = i_proto.dropAllowed;

								draggingRecords[0].allowDrop = true;

								if (dnd.overRecord && dnd.overRecord.data && dnd.overRecord.data.IRLRELTYP == 'cat' && me.getTreeNodeType() == 'itm') {
									draggingRecords[0].allowDrop = false;
									return false;
								}

								me.getFamilyStatus(draggingRecords[0]);
								if (count) {
									dnd.positionIndicator(view.getNode(count - 1), data, e);
								}
								else {
									delete dnd.overRecord;
									delete dnd.currentPosition;
									dnd.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
									dnd.valid = true;
								}
								if (!me.isDropAllow(draggingRecords[0])) {
									draggingRecords[0].allowDrop = false;
									s_allowed = i_proto.dropNotAllowed;
								}

								return s_allowed;
							},
							onNodeEnter: function(node, dragZone, e, data) {
								var dnd = this;

								me.getFamilyStatus(data.records[0]);
							},
							onNodeDrop: function(node, dragZone, e, data) {
								var me = this;
								var dropped = false;
								processDrop = function () {
										me.invalidateDrop();
										me.handleNodeDrop(data, me.overRecord, me.currentPosition);
										dropped = true;
										me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);
									},
									performOperation = false;

								performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, processDrop);
								if (performOperation !== false) {

									if (!dropped) {
										processDrop();
									}
								}

								return performOperation;
							}
						});
					}
				}
			},
			listeners: {
				beforedrop: function(node, data, targetRecord, dropPosition, dropFunction, eOpts) {
					var draggingRecord = data.records[0];
					if (ip2.isAccessible("app." + me.dmdName + ".data." + me.entity + ".delete")) {
						if (!draggingRecord.allowDrop) {
							return false;
						}

						data.sequence = me.calculateSequence(data, targetRecord, dropPosition);
						if (me.isReSequence(draggingRecord)) {
							data.copy = false;
						}
						else {
							data.copy = true;
						}
					}
					else {
						return false;
					}
				},
				drop: function(node, data, targetRecord, dropPosition, eOpts) {
					var draggingRecord = data.records[0];
					if (!data.copy) {
						me.reSequence(draggingRecord, data.sequence);
					}
					else {
						var treeNode = (data.view && data.view.xtype == 'treeview') ? true : false;
						me.createRow(draggingRecord, treeNode, data.sequence, dropPosition);
					}
				}
			},
			getRowClass: function (record, index) {
				if (record.get('PHANTOM') == '1') {
					return 'disabled-row';
				}
			}
		};
		me.callParent();
	},

	/* ----------------------------------------------------------------------------------------------------
		Get family status
	   ---------------------------------------------------------------------------------------------------- */
	getFamilyStatus: function(record) {
		record.familyStatus = 'member';
	},

	/* ----------------------------------------------------------------------------------------------------
		Is drop allow ?
	   ---------------------------------------------------------------------------------------------------- */
	isDropAllow: function(record) {
		var me = this;
		var isTreeNode = me.wrapper.treegrid.isTreeNodeDrag(record);
		var selectedTreeNodes = me.wrapper.treegrid.getView().getSelectedNodes();

		// drag and drop within folder property grid (re-sequence)
		if (me.isReSequence(record)) {
			return true;
		}

		if (isTreeNode) {
			var properties = Ext.decode(record.data.PROPERTIES);
			record.data.ITMITMTKN = parseInt(properties.itemnumber);
		}

		if (Ext.Array.contains(me.store.productKeys, record.data.ITMITMTKN)) {
			return false;
		}

		if (me.store.model.owner.id == 'familyPropertyGrid') {
			// check if target product is a single
			if (me.store.getCount() == 1) {
				return true;
			}

			// check if source product is a single
			if (record.data.ITMIFMTKN > 0 && record.familyStatus == 'member') {
				return false;
			}
		}

		if (me.dependcy && me.dependcy.store && me.dependcy.store.productKeys) {
			if (Ext.Array.contains(me.dependcy.store.productKeys, record.data.ITMITMTKN)) {
				return false;
			}
		}

		return true;
	},

	/* ----------------------------------------------------------------------------------------------------
		Re-sequence: Do the job server-side
	   ---------------------------------------------------------------------------------------------------- */
	reSequence: function(node, sequence) {
		var me = this;

		node.data.SEQUENCE = sequence;

		if (node.store.model.owner.id == 'familyPropertyGrid') {
			action = 'updateProductFamilySequence';
		}
		else {
			action = 'updateProductRelationSequence';
		}

		Ext.Ajax.request({
			url: me.model.proxy.url,
			params: {
				action: action,
				itemToken: node.data.ITMITMTKN,
				relToken: node.data.IRLIRLTKN,
				sequence: sequence
			}
		});
	},

	/* ----------------------------------------------------------------------------------------------------
		Re-sequence: Calculate new sequence
	   ---------------------------------------------------------------------------------------------------- */
	calculateSequence: function(data, targetRecord, position) {
		var me = this;

		var afterSeq;
		var beforeSeq;
		var nextSibling;
		var previousSibling;
		var position = position || 'before';

		if (targetRecord === undefined) {
			targetRecord = me.store.first();
		}

		switch (position) {
			case 'after':
				afterSeq = targetRecord.data.SEQUENCE;
				nextSibling = me.store.getAt(me.store.indexOf(targetRecord) + 1);
				if (nextSibling && nextSibling.data.IRLTYP != 'cat') {
					beforeSeq = nextSibling.data.SEQUENCE;
				}
				else {
					beforeSeq = afterSeq + 20;
				}
				break;
			case 'before':
				previousSibling = me.store.getAt(me.store.indexOf(targetRecord) - 1);
				if (previousSibling) {
					afterSeq = previousSibling.data.SEQUENCE;
				}
				else {
					afterSeq = 0;
				}
				beforeSeq = (targetRecord) ? targetRecord.data.SEQUENCE : 20;
				break;
		}
		var sequence = parseFloat(afterSeq + ((beforeSeq - afterSeq) / 2));

		return sequence;
	},

	/* ----------------------------------------------------------------------------------------------------
		is drag and drop with same container (re-sequence)
	   ---------------------------------------------------------------------------------------------------- */
	isReSequence: function(record) {
		if (record.store.model == undefined) {
			return false;
		}
		else if (record.store.model.owner && record.store.model.owner.id == this.itemId) {
			return true;
		}
		return false;
	},

	/* ----------------------------------------------------------------------------------------------------
		Build grid column base on data model
	   ---------------------------------------------------------------------------------------------------- */
	buildGridColumns: function() {

		var me = this;
		var gridColumns = [];
		var uiColumns = me.store.model.prototype.entity.ui.grids[me.uiName].columns;
		var o_dmd = ip2.resource.baseConfig.dmd;
		var o_webshop = o_dmd.webshop;
		var o_model = o_webshop.model;
		var a_entities = o_model.entities;
		var dmdModel = Ext.Array.findBy(a_entities, function(o_value) {
				return o_value.name == "WSHITMET00";
			});

		for (var i = 0; i < uiColumns.length; i++) {
			var column = {};

			Ext.apply(column, uiColumns[i]);

			column.dataIndex = column.name;
			if (!column.width) {
				column.flex = 1;
			}

			if (!column.title) {
				if (dmdModel.columns[column.name]) {
					column.title = dmdModel.columns[column.name].title;
				}
			}

			if (Ext.isObject(column.title)) {
				column.title = column.title[me.language];
			}

			column.header = column.title;

			if (column.uitype) {
				if (ip2.uitypes[column.uitype] && ip2.uitypes[column.uitype].grid && ip2.uitypes[column.uitype].grid.renderer) {
					column.renderer = ip2.uitypes[column.uitype].grid.renderer;
				}
			}

			gridColumns.push(column);
		}

		// add icon columns
		var s_entity = me.entity;
		var column = {
			xtype: 'actioncolumn',
			width: 26,
			entity: s_entity,
			items: [{
				itemId: 'remove',
				text: me.getI18N('remove'),
				tooltip: me.getI18N('removeTips').toString(),
				handler: function(grid, rowIndex, colIndex) {
					var record = grid.getStore().getAt(rowIndex);
					me.removeRow(record);
				},
				getClass: function(value, metadata, record) {
					var i_column = this;
					if (ip2.isAccessible("app." + me.dmdName + ".data." + i_column.entity + ".delete")) {
						if (record.get('PHANTOM') == '1') {
							return 'icon icon-delete x-hidden-display';
						}
						else {
							return "icon icon-delete x-grid-center-icon";
						}
					}
					else {
						return 'icon icon-delete x-hidden-display';
					}
				}
			}]
		};
		gridColumns.push(column);

		return gridColumns;
	},

	/* ----------------------------------------------------------------------------------------------------
		Create row
	   ---------------------------------------------------------------------------------------------------- */
	createRow: function(record, isTreeNode, sequence, dropPosition) {

		var me = this;
		var action;

		if (me.itemId == 'familyPropertyGrid') {
			action = 'addProductInFamily';
		}
		else {
			action = 'addProductInRelation';
		}

		// Override TreeNode by loading a data record
		if (isTreeNode) {
			var properties = Ext.decode(record.data.PROPERTIES);
			var payload = {
				action: 'getRow',
				key: '{ITMITMTKN:' + properties.itemnumber + '}',
				model: 'WSHITMET00',
				context: 'grid',
				uiName: me.wrapper.content.uiName,
				dmdFile: 'webshop.dmd',
				action: 'getRow'
			};
			var result = ip2.sajax.request({
				url: '/ip2-services/ip2dmdProxy.aspx?' + $.param(payload),
				method: 'GET',
				asJson: true
			});
			var index = me.store.indexOf(record);

			me.store.remove(record);

			me.store.insert(index, result.rows[0]);
			record = me.store.getAt(index);

			// reset treenode selection
			var node = me.wrapper.treegrid.store.getNodeById(me.selectedFolderToken);
			me.wrapper.treegrid.getSelectionModel().select(node);
		}

		Ext.Ajax.request({
			url: me.model.proxy.url,
			params: {
				action: action,
				folderToken: me.selectedFolderToken,
				familyToken: record.data.ITMIFMTKN,
				itemToken: record.data.ITMITMTKN,
				dropPosition: dropPosition,
				sequence: sequence
			},
			success: function(response, request) {
				var result = Ext.decode(response.responseText);
				for (var rowInx = 0; rowInx < result.rows.length; rowInx++) {
					var record = me.store.findRecord('ITMITMTKN', result.rows[rowInx].ITMITMTKN);
					for (var key in result.rows[rowInx]) {
						record.set(key, result.rows[rowInx][key]);
					}
					me.store.productKeys.push(result.rows[rowInx].ITMITMTKN);
				}

				me.folderPropertyAdded(record);
			}
		});
	},

	/* ----------------------------------------------------------------------------------------------------
		Remvoe row
	   ---------------------------------------------------------------------------------------------------- */
	removeRow: function(record) {
		var me = this;
		var action;
		var token;
		var itemToken;

		if (record.data.IRLRELTYP) {
			action = 'removeProductInRelation';
			token = record.data.IRLIRLTKN;
			itemToken = record.data.ITMITMTKN;
		}
		else {
			action = 'removeProductInFamily';
			token = record.data.ITMIFMTKN;
			itemToken = record.data.ITMITMTKN;
		}

		Ext.Ajax.request({
			url: me.model.proxy.url,
			params: {
				action: action,
				token: token,
				itemToken: itemToken
			},
			record: record,
			success: function(response, request) {
				var index = me.store.productKeys.indexOf(request.record.data.ITMITMTKN);
				if (index > -1) {
					me.store.productKeys.splice(index, 1);
				}
				me.store.remove(request.record);

				me.folderPropertyRemoved(request.record.data);
			}
		});
	},

	/* ----------------------------------------------------------------------------------------------------
		get tree node type
	   ---------------------------------------------------------------------------------------------------- */
	getTreeNodeType: function() {
		var me = this;

		var node = me.wrapper.treegrid.store.getNodeById(me.selectedFolderToken);
		return (node.data.cid == 3) ? 'itm' : 'cat';
	},

	/* ----------------------------------------------------------------------------------------------------
		Call after Folder Property added (Can be override by owner)
	   ---------------------------------------------------------------------------------------------------- */
	folderPropertyAdded: function(data) {
	},

	/* ----------------------------------------------------------------------------------------------------
		Call after Folder Property removed (Can be override by owner)
	   ---------------------------------------------------------------------------------------------------- */
	folderPropertyRemoved: function(data) {
	},

	/* ----------------------------------------------------------------------------------------------------
		Get i18n text by language (Can be override by owner)
	   ---------------------------------------------------------------------------------------------------- */
	getI18N: function(key) {
		return ip2.folderorganizer.getTextValue(key);
	}

});
