Ext.define('Ext.ux.gallery.MediaRelation', {

	extend: 'Ext.ux.gallery.Media',

	alias: ['widget.mediagalleryrelation'],

	parentStore: null,

	// Object with the serverParams set to pass on
	// directly to the service
	// Will be gotten from the following 4 values from XPD
	serverParams: null,

	// These 4 values will be added to the serverParams config
	// object used for the service
	parentEntity: '',
	parentEnumType: '',
	childEntity: '',
	childEnumType: '',
	records: null,

	initComponent: function () {

		var i_cmp = this;
		var o_config = i_cmp.initialConfig;

		Ext.apply(i_cmp, {
			serverParams: o_config.serverParams || {
				parentEntity: null,
				parentToken: null,
				parentType: null,
				childEntity: null,
				childType: null,
				language: null,
				action: 'getJoinedRelation'
			},
			parentEntity: o_config.parentEntity != null ? o_config.parentEntity : i_cmp.parentEntity,
			parentEnumType: o_config.parentEnumType != null ? o_config.parentEnumType : i_cmp.parentEnumType,
			childEntity: o_config.childEntity != null ? o_config.childEntity : i_cmp.childEntity,
			childEnumType: o_config.childEnumType != null ? o_config.childEnumType : i_cmp.childEnumType
		});

		i_cmp.callParent(arguments);
		i_cmp.records = {};
		i_cmp.on({
			'afterrender': {
				fn: i_cmp.onAfterRender,
				scope: i_cmp
			}
		});
		i_cmp.enableBubble("reset");

		return i_cmp;
	},

	initValue: function () {

		var i_cmp = this;
		var value = i_cmp.value;

		//i_cmp.setValue(value);
		i_cmp.originalValue = value;
		i_cmp.isValueInit = true;

		return i_cmp;
	},

	createParentStore: function () {

		var i_cmp = this;
		var s_dmdProxy = '/ip2-services/ip2dmdproxy.aspx?model=WSHRELET00&uiName=portfolio&context=grid&dmdFile=dmd/webshop.dmd';
		var i_model;
		if (Ext.ClassManager.isCreated("ip2.temp.Model")) {
			i_model = Ext.ClassManager.get("ip2.temp.Model");
		}
		else {
			i_model = Ext.define('ip2.temp.Model', {
				extend: "Ext.data.Model",
				fields: [
					'_id',
					'RELRELTKN', 'RELPNTTYP', 'RELPNTTKN', 'RELPNTLNG', 'RELCHDTYP', 'RELCHDTKN', 'RELCHDPROP',
					'FILFILTKN', 'FILCREATE', 'FILMODIFY', 'FILCRTBY', 'FILMEDIA', 'FILNAME', 'FILHEAD', 'FILSUB', 'FILPATH',
					'FILORIPATH', 'FILEXT', 'FILWIDTH', 'FILHEIGHT', 'FILSIZE', 'FILTAG', 'FILREL', 'FILEXTERNAL'
				],
				idProperty: "RELRELTKN"
			});
		}
		return i_cmp.parentStore = Ext.create('Ext.data.Store', {
			model: i_model,
			autoLoad: true,
			proxy: {
				type: 'ajax',
				api: {
					'read': '/ip2-services/wshproxy.aspx',
					'create': s_dmdProxy + '&action=upsert',
					'update': s_dmdProxy + '&action=upsert',
					'delete': s_dmdProxy + '&action=delete'
				},
				reader: {
					type: 'json',
					rowProperty: "rows",
					totalProperty: 'totalRows'
				}
			},
			listeners: {
				beforeload: {
					fn: function(store) {
						var i_proxy = store.getProxy();
						var o_extraParams = i_proxy.getExtraParams();
						Ext.apply(o_extraParams, i_cmp.serverParams);
					}
				}
			}
		});
	},

	getParentStore: function () {

		return this.parentStore;
	},

	onAfterRender: function () {

		var i_cmp = this;
		var i_parent;

		var s_primaryKey;
		var n_primaryKey;
		var s_languageKey;

		var getDataParent = function (i_parent) {

			while (i_parent && !i_parent.dataParent) {
				i_parent = i_parent.up();
			}

			return i_parent.dataParent;
		};

		var getDataLanguage = function (i_parent) {

			while (i_parent && !i_parent.language) {
				i_parent = i_parent.up();
			}

			return i_parent.language;
		};

		// Prepare the params object to pass to the service
		// which will be saved on i_cmp.serverParams
		i_cmp.serverParams.parentEntity = i_cmp.parentEntity;
		i_cmp.serverParams.childEntity = i_cmp.childEntity;

		if (!i_cmp.primaryKey || !i_cmp.languageKey) {

			i_parent = getDataParent(i_cmp);

			s_primaryKey = i_parent.dmdInfo.entity.idColumn;
			n_primaryKey = i_parent.keys[s_primaryKey];

			if (i_parent.language) {
				s_languageKey = i_parent.language;
			}
			else {
				s_languageKey = getDataLanguage(i_cmp);
			}

			i_cmp.oldLang = s_languageKey;
		}

		if (!i_cmp.primaryKey) {

			i_cmp.serverParams.parentToken = n_primaryKey;
		}
		if (!i_cmp.languageKey && s_languageKey) {

			i_cmp.serverParams.language = s_languageKey;
		}

		// Deal with ENUM of parentEnumType=>parentType
		// Deal with ENUM of childEnumType=>childType
		i_cmp.serverParams.parentType = i_cmp.getTypeEnumValue('parentRelationTypes', i_cmp.parentEnumType);
		i_cmp.serverParams.childType = i_cmp.getTypeEnumValue('childRelationTypes', i_cmp.childEnumType);
		i_cmp.serverParams.childEntity = i_cmp.serverParams.childEntity + "_GRID_PORTFOLIO";

		i_cmp.createParentStore();

		i_cmp.bindStores();
	},

	addControls: function () {

		var i_cmp = this;

		i_cmp.on({
			'afterrender': {
				fn: function (i_self) {
					i_self.syncButtons();
				},
				single: true
			},
			'create': {
				fn: function (i_self) {
					i_self.syncButtons();
				}
			},
			'update': {
				fn: function (i_self) {
					i_self.syncButtons();
				}
			},
			'remove': {
				fn: function (i_self) {
					i_self.checkAutoSelectColumns();
					i_self.syncButtons();
				}
			},
			'empty': {
				fn: function (i_self) {
					i_self.syncButtons();
				}
			}
		});

		i_cmp.control({
			'grid': {
				itemedit: i_cmp.onCollectionItemEdit,
				itemdblclick: i_cmp.onCollectionItemEdit,
				itemremove: i_cmp.onCollectionItemRemove,
				deletekey: i_cmp.onCollectionItemRemove,
				itemcontextmenu: i_cmp.onCollectionContext,
				scope: i_cmp
			},
			'dropbox': {
				dragenter: i_cmp.onDragEnter,
				afterrender: function(item) {
					i_cmp.dropzone = Ext.widget("filedropzone", {
						animateTarget: item.getEl(),
						extensions: i_cmp.extensions,
						dropFn: function(a_records) {
							i_cmp.onDrop(a_records);
						}
					});
				}
			}
		});

		return i_cmp;
	},

	onDragEnter: function (i_dropbox, o_event) {

		var i_cmp = this;
		i_cmp.dropzone.show();
	},

	onDrop: function(a_records) {
		var i_cmp = this;
		var a_models = [];
		var i_parentStore = i_cmp.getParentStore();
		var n_childenum = i_cmp.serverParams.childType;
		var n_parentenum = i_cmp.serverParams.parentType;
		var n_primaryKey = i_cmp.serverParams.parentToken;

		ip2.each(a_records, function(i_record) {
			var i_model = i_parentStore.model.create(i_record.data);
			i_model.set({
				RELCHDTYP: n_childenum,
				RELPNTTYP: n_parentenum,
				RELPNTTKN: n_primaryKey,
				RELCHDTKN: i_record.get("FILFILTKN")
			});
			a_models.push(i_model);
		});
		i_parentStore.add(a_models);
	},

	bindStores: function() {

		var i_cmp = this;
		var i_parentStore = i_cmp.getParentStore();
		var i_gridStore = i_cmp.getStore();
		i_cmp.isDropping = false;

		i_parentStore.on({
			load: {
				fn: function(store, a_records) {

					var i_entityform = i_cmp.up("entityform");
					var a_result = [];
					var a_all = [];

					if (i_entityform && i_entityform.action == "copy") {
						Ext.Array.each(a_records, function(i_record) {
							i_record.set(i_record.idProperty, null);
						});
					}

					Ext.Array.each(a_records, function(i_record) {
						var i_gridrecord = initParentRecord(i_record);
						a_result.push(i_gridrecord);
					});

					if (a_result.length > 0) {
						i_cmp.createData(a_result, {
							addRecords: true
						});
					}

					i_parentStore.each(function(i_record, n_index) {
						a_all.push(i_record.data);
					});

					i_cmp.records[i_cmp.serverParams.language] = a_all;

					i_cmp.fireEvent("reset");
				}
			},
			add: {
				fn: function(i_store, a_records) {
					var a_result = [];
					var a_all = [];
					Ext.Array.each(a_records, function(i_record) {
						var i_gridrecord = initParentRecord(i_record);
						a_result.push(i_gridrecord);
					});
					i_cmp.createData(a_result, {
						addRecords: true
					});
					i_parentStore.each(function(i_record, n_index) {
						a_all.push(i_record.data);
					});
					i_cmp.records[i_cmp.serverParams.language] = a_all;
				}
			}
		});

		i_gridStore.on({
			remove: {
				fn: function(store, a_records) {
					if (i_cmp.isDropping) {
						return;
					}
					var a_all = [];
					ip2.each(a_records, function(i_record) {
						var i_parentRecord = i_parentStore.findRecord('_id', i_record.get('_id'));
						i_parentStore.remove(i_parentRecord);
					});
					i_parentStore.each(function(i_record, n_index) {
						a_all.push(i_record.data);
					});
					i_cmp.records[i_cmp.serverParams.language] = a_all;
				}
			},
			beforereorder: {
				fn: function(store) {
					i_cmp.isDropping = true;
				}
			},
			reorder: {
				fn: function(store, a_records, n_index) {
					i_cmp.isDropping = false;
				}
			}
		});

		function initParentRecord(i_parentRecord) {

			if (!i_parentRecord.get("_id")) {
				i_parentRecord.set('_id', ip2.unique('tmp-'));
			}
			var o_relProp = i_parentRecord.get('RELCHDPROP');
			if (!Ext.isObject(o_relProp)) {
				o_relProp = {};
			}
			else {
				if (!o_relProp.type) {
					o_relProp.type = "image";
				}
			}
			var o_gridRecord = ip2.extend({}, o_relProp, i_cmp.parent2grid(i_parentRecord, i_parentRecord.data));

			var i_gridRecord = i_gridStore.model.create(o_gridRecord);

			var systemSet = false;

			// TODO: Don't overridee set methods, now even when you want a record change event!
			i_gridRecord.set = (function(orig) {
				return function() {
					var ret = orig.apply(this, arguments);
					if (!systemSet) {
						systemSet = true;
						var changes = ip2.clone(this.data);
						if (!Ext.Object.isEmpty(changes)) {
							var i_parentRecord = i_parentStore.findRecord('_id', this.get('_id'));
							if (i_parentRecord) {
								i_parentRecord.set(i_cmp.grid2parent(this, changes));
							}
							else {
								console.log('parentRecord is missing');
							}
						}
						systemSet = false;
					}
					return ret;
				};
			})(i_gridRecord.set);

			i_parentRecord.set = (function(orig) {
				return function() {
					var ret = orig.apply(this, arguments);
					if (!systemSet) {
						systemSet = true;
						var changes = ip2.clone(this.data);
						if (!Ext.Object.isEmpty(changes)) {
							var i_gridRecord = i_gridStore.findRecord('_id', this.get('_id'));
							if (i_gridRecord) {
								i_gridRecord.set(i_cmp.parent2grid(this, changes));
							}
							else {
								console.log('gridRecord is missing');
							}
						}
						systemSet = false;
					}
					return ret;
				};
			})(i_parentRecord.set);
			return i_gridRecord;
		}
	},

	parent2grid: function(i_parentRecord, changes) {
		var o_set = {};

		if (changes.RELCHDPROP) {
			ip2.extend(o_set, changes.RELCHDPROP);
		}

		if (changes.RELCHDTKN) {
			o_set.RELCHDTKN = changes.RELCHDTKN;
		}
		if (changes._id) {
			o_set._id = changes._id;
		}

		if (changes.FILNAME || changes.FILPATH) {
			if (i_parentRecord.get("FILEXTERNAL")) {
				o_set.url = i_parentRecord.get("FILORIPATH");
			}
			else {
				o_set.url = i_parentRecord.get("FILPATH") + i_parentRecord.get("FILNAME");
			}
		}
		if (changes.FILNAME) {
			o_set.name = changes.FILNAME;
		}

		return o_set;
	},

	grid2parent: function(i_gridRecord, changes) {
		var o_set = {};

		o_set.RELCHDPROP = ip2.clone(i_gridRecord.data);
		delete o_set.RELCHDPROP.RELCHDTKN;

		if (changes.RELCHDTKN) {
			o_set.RELCHDTKN = changes.RELCHDTKN;
		}
		if (changes._id) {
			o_set._id = changes._id;
		}

		return o_set;
	},

	getTypeEnumValue: function (s_key, enumValue) {

		var i_cmp = this;
		var s_lang = wsh.i18n.getPrimary();

		var i_ns = ip2.resource.get('adm.ns', true);
		var o_value = i_ns.getEnumValue(s_key + '~' + enumValue);

		return o_value[s_lang];
	},

	onCollectionItemAdd: function () {

		var i_cmp = this;
		i_cmp.openItemEditor();

		return i_cmp;
	},

	openItemEditor: function (i_gridRecord) {

		var i_cmp = this;
		var o_defaults = i_cmp.editorConfig;
		var i_parentStore = i_cmp.getParentStore();
		var i_parentRecord;

		var o_config = {
			type: 'image',
			ignoreStaticDir: i_cmp.ignoreStaticDir,
			activeTab: 'mediaproperties'
		};

		var isEdit = i_gridRecord ? true : false;

		if (isEdit) {
			i_parentRecord = i_parentStore.findRecord('_id', i_gridRecord.get('_id'));

			o_config.action = 'edit';
			o_config.type = i_gridRecord.get('type') || o_config.type;
			o_config.record = i_gridRecord;
			o_config.title = [ip2.i18n(i_cmp.itemEditTitle), i_parentRecord.get('FILNAME')].join(' ');
		}
		else {

			i_parentRecord = i_parentStore.model.create();
			i_parentRecord.set({ _id: ip2.unique('tmp-') });
			o_config.record = Ext.create('Ext.data.Store', { fields: [] }).model.create();
			o_config.action = 'add';
			o_config.title = ip2.i18n(i_cmp.itemCreateTitle);
		}

		Ext.apply(o_config, o_defaults);

		var i_window = Ext.widget('mediaeditorrelation', o_config);

		i_window.on('aftersave', function(item, record) {

			if (!isEdit) {
				i_parentRecord.set(i_cmp.grid2parent(record, ip2.extend({ type: o_config.type }, record.data)));
				i_parentRecord = i_parentStore.add(i_parentRecord.data)[0];
			}
			else {
				i_gridRecord.set('type', o_config.type);
			}

			var i_combo = item.down('[name="RELCHDTKN"]');
			var i_fileRecord = i_combo.getRecord();

			// If fileRecord is null it means that we didnt change the image:
			if (i_fileRecord) {
				i_parentRecord.set(i_fileRecord.data);
			}
		});

		return i_cmp;
	},

	createData: function (data, o_options) {

		var i_cmp = this;
		var i_store = i_cmp.getStore();
		var a_data = Ext.Array.from(data);

		// If we have nothing in store, and we have actionColumns applied
		// then we need to apply default autoSelect values to first dataset in a_data
		var n_store = i_store.getCount();
		var o_actionColumns = i_cmp.actionColumns;

		// Check autoSelect defaults for row context groups in actionColumns
		ip2.each(a_data, function (i_data, n_index, a_context) {

			// Get row context based default values for autoSelect
			var o_defaults = i_cmp.getAutoSelectDefaults('row');

			// If store is empty then we need to apply column context defaults
			if (!n_store && n_index == 0 && i_cmp.isValueInit) {
				var o_columnDefaults = i_cmp.getAutoSelectDefaults('column');
				ip2.extend(o_defaults, o_columnDefaults);
			}
			if (i_data.phantom != null && i_data.modified != null) {
				i_data.set(o_defaults);
			}
			else {
				a_context[n_index] = ip2.defaults(i_data, o_defaults);
			}
		});
		var a_result = [];
		ip2.each(a_data, function(i_record) {
			a_result.push(i_record.data);
		});

		i_store.loadRecords(a_data, o_options);

		i_cmp.fireEvent("create", i_cmp);

		return i_cmp;
	},

	doSave: function(f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var i_cmp = this;
		var i_parentStore = i_cmp.getParentStore();

		if (i_parentStore) {
			var a_records = i_parentStore.getData().items.slice(0);
			var a_return = [];
			ip2.each(a_records, function(i_record) {
				var o_clone = ip2.clone(i_record.data);
				var i_model = i_parentStore.model.create(o_clone);
				var a_keys = Ext.Object.getKeys(i_model.data);
				ip2.each(a_keys, function(s_key) {
					if (s_key.slice(0, 3) != 'REL' && s_key != "_id") {
						delete i_model.data[s_key];
					}
				});
				a_return.push(i_model);
			});
			i_cmp.doSync(a_return, f_callback);
		}
		else {
			f_callback();
		}
	},

	getBatches: function(a_records) {

		var i_self = this;
		var i_entityform = i_self.up("entityform");
		var n_tkn = i_self.serverParams.parentToken;

		if (i_entityform) {
			var i_entityRecord = i_entityform.getForm().getRecord();
			n_tkn = i_entityRecord.get(i_entityRecord.idProperty);
			i_self.serverParams.parentToken = n_tkn;
		}

		var i_parentStore = i_self.getParentStore();
		var a_languages = wsh.getLanguages();
		var a_batch = [];
		var a_deleted = i_parentStore.getRemovedRecords();
		var a_gridRecords = i_self.getStore().data.items;
		var i_dummy = i_parentStore.model.create();

		var a_sorted = [];

		ip2.each(a_records, function(i_record) {
			ip2.each(a_gridRecords, function(i_gridRecord, n_index) {
				if (i_gridRecord.get("RELCHDTKN") == i_record.get("RELCHDTKN")) {
					i_record.set("RELCHDSEQ", n_index);
				}
			});
		});

		ip2.each(a_records, function (i_record) {
			if (!Ext.isNumber(i_record)) {
				var key = {};
				i_record.set({
					RELCHDTYP: i_self.serverParams.childType,
					RELPNTTYP: i_self.serverParams.parentType,
					RELPNTTKN: n_tkn,
					RELPNTLNG: i_self.serverParams.language
				});
				key[i_record.idProperty] = i_record.get(i_record.idProperty) || 0;
				a_batch.push({
					type: 'upsert',
					dmd: 'dmd/webshop.dmd',
					entity: "WSHRELET00",
					key: key,
					row: i_record.data
				});
			}
		});

		ip2.each(a_deleted, function (i_record) {
			var s_language = i_record.get("RELPNTLNG");
			if (s_language == i_self.serverParams.language) {
				var i_parentRecord = i_parentStore.findRecord(i_record.idProperty, i_record.get(i_record.idProperty));
				if (!i_parentRecord) {
					var key = {};
					key[i_record.idProperty] = i_record.get(i_record.idProperty);
					a_batch.push({
						type: 'delete',
						dmd: 'dmd/webshop.dmd',
						entity: "WSHRELET00",
						key: key,
						row: i_record.data
					});
				}
			}
		});

		ip2.each(a_languages, function(s_lang) {

			if (s_lang != i_self.serverParams.language) {
				var a_langRecords = i_self.records[s_lang] || [];
				var a_records = a_langRecords.slice(0);
				ip2.each(a_records, function(o_record) {
					var i_model = i_parentStore.model.create(o_record);
					var a_keys = Ext.Object.getKeys(i_model);
					ip2.each(a_keys, function(s_key) {
						if (s_key.slice(0, 3) != 'REL') {
							delete i_model.data[s_key];
						}
					});
					var key = {};
					i_model.RELCHDTYP = i_self.serverParams.childType;
					i_model.RELPNTTYP = i_self.serverParams.parentType;
					i_model.RELPNTTKN = n_tkn;
					i_model.RELPNTLNG = s_lang;
					key[i_dummy.idProperty] = i_model.get(i_dummy.idProperty) || 0;
					a_batch.push({
						type: 'upsert',
						dmd: 'dmd/webshop.dmd',
						entity: "WSHRELET00",
						key: key,
						row: i_model.data
					});
				});
			}
		});

		return a_batch;
	},

	doSync: function(a_records, f_callback) {

		var i_self = this;
		var a_batch = i_self.getBatches(a_records);
		var i_gridStore = i_self.getStore();
		var i_grid = i_self.getGrid();

		Ext.Ajax.request({
			url: '/ip2-Services/ip2dmdproxy.aspx',
			jsonData: {
				transaction: {
					batch: a_batch
				}
			},
			success: function (xhr) {
				var o_resp = JSON.parse(xhr.responseText);
				i_gridStore.removeAll(true);
				i_grid.getView().refresh();
				i_self.parentStore.load();
				f_callback();
			}
		});
	},

	changeLanguage: function(s_lang) {
		var i_self = this;
		var i_parent = i_self;
		if (i_self.parentStore) {
			var i_gridStore = i_self.getStore();
			var i_grid = i_self.getGrid();
			var a_values = i_self.getValues();
			i_self.records[i_self.serverParams.language] = a_values;
			var a_records = i_self.records[s_lang];
			i_self.serverParams.language = s_lang;
			i_self.parentStore.proxy.api.read = '/ip2-services/wshproxy.aspx?' + Ext.Object.toQueryString(i_self.serverParams);
			if (a_records == undefined) {
				i_gridStore.removeAll(true);
				i_grid.getView().refresh();
				i_self.parentStore.load();
			}
			else {
				i_gridStore.removeAll(true);
				i_grid.getView().refresh();
				i_self.parentStore.removeAll(true);
				i_self.parentStore.add(a_records);
			}
		}
	},

	getValues: function() {
		var i_self = this;
		var a_return = [];
		var i_parentStore = i_self.parentStore;
		var i_gridStore = i_self.getStore();
		if (i_gridStore && i_parentStore) {
			var a_records = i_parentStore.data.items.slice(0);
			i_gridStore.each(function(i_record) {
				ip2.each(a_records, function(i_parentRecord) {
					if (i_parentRecord.get("_id") == i_record.get("_id")) {
						var o_model = ip2.clone(i_parentRecord.data);
						var o_data = ip2.clone(i_record.data);
						o_model.RELCHDPROP = o_data;
						delete o_data._id;
						delete o_model._id;
						a_return.push(o_model);
					}
				});
			});
		}
		return a_return;
	}
});
