
Ext.define('Ext.ux.folderorganizer.ItemRelationSelector', {
	extend: 'Ext.tree.Panel',
	alias: ['widget.itemRelationSelector'],
	useArrows: true,
	rootVisible: false,
	multiSelect: true,
	singleExpand: false,
	hideHeaders: true,
	columns: [{
		xtype: 'treecolumn',
		dataIndex: 'GROUP',
		flex: 1
	}],
	layout: 'fit',
	autoScroll: true,
	initComponent: function() {
		var me = this;

		me.clearSelection();

		// family tree store
		if (!Ext.ClassManager.isCreated('familyTree')) {
			Ext.define('familyTree', {
				extend: 'Ext.data.Model',
				fields: [
					{ name: 'ID', type: 'string' },
					{ name: 'KEY', type: 'string' },
					{ name: 'GROUP', type: 'string' },
					{ name: 'leaf', type: 'boolean' },
					{ name: 'allowDrag', type: 'boolean' },
					{ name: 'allowDrop', type: 'boolean' },
					{ name: 'allowEdit', type: 'boolean' },
					{ name: 'allowRemove', type: 'boolean' },
					{ name: 'iconCls', type: 'string' }
				],
				idProperty: 'ID',
				proxy: {
					type: 'ajax',
					url: me.proxy,
					extraParams: {
						action: 'familyTreeStore',
						parentOnly: true,
						checkbox: true,
						displayRootNode: false
					}
				}
			});
		}

		me.store = Ext.create('Ext.data.TreeStore', {
			model: 'familyTree',
			clearOnLoad: false,
			autoLoad: true,
			listeners: {
				beforeload: {
					fn: function(store, operation) {
						var node = operation.node;
						var i_proxy = store.getProxy();
						var o_extraParams = i_proxy.getExtraParams();
						var s_node = node.get("ID");
						if (s_node == "root") {
							s_node = s_node + ".0";
						}
						Ext.apply(o_extraParams, {
							node: s_node
						});
						delete operation.node;
					}
				}
			}
		});

		me.listeners = {
			checkchange: function(node, newValue) {
				var family = node.data.KEY;
				if (me.checkedItems.family.indexOf(family) > -1) {
					var pos = me.checkedItems.family.indexOf(family);
					me.checkedItems.ID.splice(pos, 1);
					me.checkedItems.family.splice(pos, 1);
				}
				if (me.uncheckedItems.family.indexOf(family) > -1) {
					var pos = me.uncheckedItems.family.indexOf(family);
					me.uncheckedItems.ID.splice(pos, 1);
					me.uncheckedItems.family.splice(pos, 1);
				}
				if (newValue) {
					// new checked
					if (!me.multiSelect) {
						me.singleSelection();
					}
					me.checkedItems.family.push(family);
				}
				else {
					// existing unchecked
					me.uncheckedItems.family.push(family);
				};
			}
		};

		me.callParent(arguments);

		if (Ext.isFunction(me.wrapper.getDataParent)) {

			me.record = me.wrapper.getDataParent().getRecord();

			if (me.record) {
				me.onParentLoad();
			}
			else {
				// wait for data parent store loaded

				var store = me.wrapper.getDataParent().getStore();

				store.on('load', function(store, records) {
					if (Ext.isArray(records)) {
						me.record = records[0];
						me.onParentLoad();
					}
				});
			}
		}

		me.enableBubble("dirtychange");

		return me;
	},

	/**
	 * @method on parent load
	 *
	 */
	onParentLoad: function() {
		var me = this;

		me.clearSelection();

		me.getData(me.getExisting);
	},

	/**
	 * @method Get Existing: set checkbox as checked for already existing relation
	 *
	 */
	getExisting: function(records) {

		var me = this;

		me.existing = {
			ID: [],
			family: []
		};

		if (!records) {
			return;
		}

		// create unique array with parents
		var parentFamily = [];
		for (var i = 0; i < records.length; i++) {
			var data = records[i].data;
			var parents = data.parents.split('.');

			for (var p = 0; p < parents.length; p++) {
				if (parentFamily.indexOf(parents[p]) == -1) {
					parentFamily.push(parents[p]);
				}
			}
		}

		// expand all parents and set check mark when expanding is finished
		me.expandParent({
			parents: parentFamily,
			index: 0,
			records: records,
			success: function(records) {
				for (var i = 0; i < records.length; i++) {
					var data = records[i].data;
					me.setCheck(data.family, true, data.ID);
					me.existing.family.push(data.family);
				}
			}
		});
	},

	/**
	 * @method expand parent
	 *
	 */
	expandParent: function(args) {
		var me = this;

		if (args.index >= args.parents.length) {
			var task = new Ext.util.DelayedTask(function() {
			Ext.callback(args.success, me, [args.records]);
		});
			task.delay(500);
			return false;
		}

		var node = me.store.getNodeById('fami.' + args.parents[args.index]);
		if (node && !node.isExpanded()) {
			node.expand(false, function() {
				args.index = args.index + 1;
				var task = new Ext.util.DelayedTask(function() {
					me.expandParent(args);
				});
				task.delay((args.index >= args.parents.length) ? 0 : 500);
			}, me);
		}
		else {
			args.index = args.index + 1;
			me.expandParent(args);
		}
	},

	/**
	 * @method set uncheck for already check (single selection)
	 *
	 */
	singleSelection: function() {

		var me = this;

		for (var i = 0; i < me.existing.family.length; i++) {
			me.setCheck(me.existing.family[i], false);
		}
		me.existing.family = [];

		for (var i = 0; i < me.checkedItems.family.length; i++) {
			me.setCheck(me.checkedItems.family[i], false);
		}
		me.checkedItems.family = [];
	},

	/**
	 * @method set check or uncheck
	 *
	 */
	setCheck: function(family, checked, ID) {

		var node = this.store.getNodeById('fami.' + family);

		if (node) {
			node.set('checked', checked);
			if (ID) {
				node.set('relID', ID);
			}
		}
	},

	/**
	 * @method doSave
	 *
	 */
	doSave: function() {

		var me = this;

		var key = {
			product: me.getKeyValue()
		};

		// checked
		for (var i = 0; i < me.checkedItems.family.length; i++) {
			var data = me.getFamilyNode(me.checkedItems.family[i]);
			key.ID = data.relID;
			key.family = me.checkedItems.family[i];
			var node = me.store.getNodeById('fami.' + key.family);
			me.doUpdate('update', key, node);
		}

		// unchecked
		if (me.multiSelect || me.checkedItems.family.length == 0) {
			for (var i = 0; i < me.uncheckedItems.family.length; i++) {
				var data = me.getFamilyNode(me.uncheckedItems.family[i]);
				key.ID = data.relID;
				key.family = me.uncheckedItems.family[i];
				var node = me.store.getNodeById('fami.' + key.family);
				me.doUpdate('remove', key, node);
			}
		}

		me.existing.family = me.checkedItems.family;
		me.clearSelection();

		me.fireEvent('savecomplete', me, true);
	},

	/**
	 * @method doUpdate (empty function). Make you own function :-)
	 *
	 */
	doUpdate: function() {
	},

	/**
	 * @method doDelete (empty function). Make you own function :-)
	 *
	 */
	doDelete: function() {
		var me = this;

		var key = {
			product: me.getKeyValue()
		};

		// existing
		for (var i = 0; i < me.existing.family.length; i++) {
			var data = me.getFamilyNode(me.existing.family[i]);
			key.ID = data.relID;
			key.family = me.existing.family[i];
			me.setCheck(key.family, false, 0);
			me.doUpdate('remove', key);
		}

		// checked
		for (var i = 0; i < me.checkedItems.family.length; i++) {
			var data = me.getFamilyNode(me.checkedItems.family[i]);
			key.ID = data.relID;
			key.family = me.checkedItems.family[i];
			me.setCheck(key.family, false, 0);
			me.doUpdate('remove', key);
		}
	},

	/**
	 * @method get data for this product
	 *
	 */
	getData: function(cb) {
		var me = this;

		// get existing item data and load the records into writer store
		if (!Ext.ClassManager.isCreated('data')) {
			Ext.define('data', {
				extend: 'Ext.data.Model',
				fields: [
					{ name: 'ID', type: 'string' },
					{ name: 'family', type: 'int' },
					{ name: 'parents', type: 'string' }
				],
				idProperty: 'family',
				proxy: {
					type: 'ajax',
					url: me.proxy + '?action=' + me.getAction + '&item=' + me.getKeyValue(),
					reader: {
						type: 'json',
						rootProperty: 'rows'
					}
				}
			});
		}
		Ext.create('Ext.data.Store', {
			model: 'data',
			autoLoad: true,
			listeners: {
				load: function(store, records) {
					Ext.callback(cb, me, [records]);
				}
			}
		});
	},

	/**
	 * @method getKeyValue
	 *
	 */
	getKeyValue: function() {

		var me = this;

		return (me.record) ? me.record.data.ITMITMTKN : '';
	},

	/**
	 * @method get family node data
	 *
	 */
	getFamilyNode: function(family) {
		var node = this.store.getNodeById('fami.' + family);
		return node.data;
	},

	/**
	 * @method clean up selection
	 *
	 */
	clearSelection: function() {
		this.checkedItems = {
			ID: [],
			family: []
		};
		this.uncheckedItems = {
			ID: [],
			family: []
		};
	},

	resetDirty: function() {

		var i_self = this;
		var i_store = i_self.getStore();
		var a_nodes = i_store.getData().items;

		ip2.each(a_nodes, function(i_node) {
			i_node.oldChecked = i_node.get("checked");
			i_node.dirty = false;
		});

		i_self.fireEvent("dirtychange", i_self, false);
	},

	isDirty: function() {

		var i_self = this;
		var i_store = i_self.getStore();
		var a_nodes = i_store.getData().items;
		var b_dirty = false;

		ip2.each(a_nodes, function(i_node) {
			if (i_node.dirty) {
				b_dirty = true;
			}
		});

		return b_dirty;
	}
});
