Ext.define("Ext.ux.gallery.view.MediaGrid", {

	extend: "Ext.grid.Panel",

	alias: ["widget.gallerymediagrid"],

	mixins: {
		keyMapping: "Ext.ux.util.KeyMapping"
	},
	
	config: {
		
		linkConfig: null,
		actionColumns: null,
		allowImageRender: 1,
		dcMap: null
	},

	initComponent: function () {

		var i_cmp = this;

		Ext.apply(i_cmp, {
			cls: "x-ux-imagegrid"
		});

		i_cmp.language = i_cmp.language || wsh.i18n.getPrimary();

		i_cmp.initColumns();

		i_cmp.callParent(arguments);

		i_cmp.initKeyMapping();

		i_cmp.enableBubble("datachange");

		return i_cmp;
	},

	initColumns: function () {

		var i_cmp = this;
		var o_actionColumns = i_cmp.actionColumns;
		var a_columns = [];

		i_cmp.dcMap = {};

		// Create the action columns from definition
		Ext.Object.each(o_actionColumns, function (s_key, o_config) {

			o_config._key = s_key;

			var f_behavior;
			switch (o_config.type) {
				case "radiocheckbox":
					f_behavior = i_cmp.applyRadioCheckboxBehavior;
					o_config.inputType = "radio";
					o_config.context || (o_config.context = "column");
				break;
				case "radio":
					f_behavior = i_cmp.applyRadioBehavior;
					o_config.inputType = "radio";
					o_config.context || (o_config.context = "column");
				break;
				case "checkbox":
					o_config.inputType = "checkbox";
					f_behavior = i_cmp.applyCheckboxbehavior;
				break;
				default:
					o_config.inputType = "checkbox";
					f_behavior = i_cmp.applyCheckboxbehavior;
				break;
			}

			var f_getMappedName = function (s_key) {

				var s_name = false;
				var o_map = {
					header: ["title"],
					dataGroup: ["group"]
				};

				ip2.each(o_map, function (a_val, s_map) {
					var n_index = ip2.indexOf(a_val, s_key);
					if (n_index > -1) {
						s_name = s_map;
						return false;
					}
				});

				return s_name;
			};

			var f_sanitize = function (value, s_key, o_context) {

				// Could be a title or tooltip or whatever - use ip2.i18n
				if (ip2.isObject(value)) {
					value = ip2.i18n(value);
				}

				// Special conditions
				switch (s_key) {

				case "context":
					o_context.dataGroup || (o_context.dataGroup = o_context.group);
					if (!o_context.dataGroup) {
						o_context.dataGroup = o_context.dataIndex || o_context.name;
					}
				break;

				default:
				break;
				}

				return value;
			};

			ip2.each(o_config, function (value, s_key, o_context) {

				// Could be this is an mapped key
				var s_map = f_getMappedName(s_key);
				if (s_map) {
					o_context[s_map] = f_sanitize(value, s_map, o_context);
					delete o_context[s_key];
				}
				else {
					o_context[s_key] = f_sanitize(value, s_key, o_context);
				}
			});

			var o_column = ip2.extend({
				header: "",
				width: 55
			}, o_config, {
				sortable: false,
				resizable: false,
				hideable: false,
				align: "center",
				menuDisabled: true,
				dataIndex: s_key,
				toolTip: ip2.i18n(o_config.toolTip) || ip2.i18n(o_config.header),
				renderer: function (b_value, o_meta, i_record, n_row, n_col, i_store, i_view) {

					var o_input = i_cmp.createSpecialColumnInput(i_record, o_config);
					f_behavior.call(i_cmp, o_input.id, o_config);

					return o_input.html;
				}
			});

			a_columns.push(o_column);
		});

		// Then concat the remaining columns
		a_columns = a_columns.concat([
			{
				hidden: true,
				dataIndex: "type",
				sortable: false,
				draggable: false,
				resizable: false,
				hideable: false,
				menuDisabled: true
			},
			{
				header: ip2.i18n({
					da: "Medie",
					en: "Media"
				}),
				toolTip: ip2.i18n({
					da: "Hvis muligt vises et preview af mediet",
					en: "If possible a preview of the media will be shown"
				}),
				align: "center",
				width: 100,
				dataIndex: "url",
				renderer: function (s_value, metaData, i_record) {

					var value = i_record.get("url");
					var s_url = value;
					var s_lang = i_cmp.language;
					if (Ext.isObject(value)) {
						s_url = value[s_lang];
						if (!s_url) {
							s_url = value.any || "";
						}
					}

					var s_dc = "?_dc=" + ip2.getDcTimestamp();

					var s_url = Ext.ux.file.util.Handler.getUrlByExtension(s_url, true);

					var s_html = [
						"<div style=\"height: 24px;\">",
							"<img ",
								"data-internalid=\"" + i_record.internalId + "\" ",
								"class=\"grid-preview\" ",
								"height=\"24\"",
								"src=\"" + s_url + s_dc + "\"",
							"/>",
						"</div>"
					].join("");

					return s_html;
				}
			},
			{
				header: ip2.i18n({
					da: "Navn",
					en: "Name"
				}),
				toolTip: ip2.i18n({
					da: "Navn",
					en: "Name"
				}),
				flex: 1,
				dataIndex: "url",
				renderer: function (s_value) {

					var value = s_value;
					var s_lang = i_cmp.language;
					if (Ext.isObject(value)) {
						s_value = value[s_lang];
						if (!s_value) {
							s_value = value.any || "";
						}
					}

					return s_value.split("/").pop();
				}
			},
			{
				header: ip2.i18n({
					da: "Overskrift",
					en: "Headline"
				}),
				toolTip: ip2.i18n({
					da: "Overskrift",
					en: "Headline"
				}),
				flex: 2,
				dataIndex: "title",
				renderer: function (s_value) {
					var value = s_value;
					var b_stringed = ip2.isStringedObject(value);
					if (b_stringed) {
						var o_value = JSON.parse(value);
						i_cmp.language = i_cmp.language || wsh.i18n.getPrimary();
						var s_lang = i_cmp.language;
						value = ip2.i18nWithLanguage(o_value, s_lang);
					}
					else {
						if (Ext.isObject(value)) {
							var o_value = value;
							i_cmp.language = i_cmp.language || wsh.i18n.getPrimary();
							var s_lang = i_cmp.language;
							value = ip2.i18nWithLanguage(o_value, s_lang);
						}
					}
					return value;
				}
			},
			{
				header: ip2.i18n({
					da: "Link",
					en: "Link"
				}),
				toolTip: ip2.i18n({
					da: "Link",
					en: "Link"
				}),
				flex: 2,
				dataIndex: "link",
				renderer: function (o_value, o_meta, i_record, n_row, n_col, i_store, i_view) {

					o_value = o_value || {};

					var s_return = "";
					var s_type = o_value.type;
					var o_i18n;
					var s_url;

					if (!s_type) {
						return s_return;
					}

					switch (s_type) {
					case "page":
						var s_token = o_value.token;
						var s_title = o_value.title;

						o_i18n = {
							da: "Side: ",
							en: "Page: "
						};

						if (s_token && !s_title) {
							o_i18n.da += "med token " + s_token;
							o_i18n.en += "with token " + s_token;
						}
						else if (s_title) {
							o_i18n.da += s_title;
							o_i18n.en += s_title;
						}

						s_return = ip2.i18n(o_i18n);
					break;

					case "stack":
						o_i18n = {
							da: "Stak:",
							en: "Stack:"
						};

						s_return = [ip2.i18n(o_i18n), o_value.title || o_value.token].join(" ");

					break;

					case "url":
						s_url = o_value.url;
						var b_external = ip2.isExternalUrl(s_url);

						o_i18n = {
							da: b_external ? "Ekstern URL:" : "Intern URL: ",
							en: b_external ? "Extern URL:" : "Intern URL:"
						};

						s_return = [ip2.i18n(o_i18n), s_url].join(" ");
					break;

					case "document":
						s_url = o_value.value.url;

						o_i18n = {
							da: "Dokument: ",
							en: "Document: "
						};

						s_return = [ip2.i18n(o_i18n), s_url].join(" ");
					break;

					default:
					break;
					}

					return s_return;
				},
				hidden: i_cmp.linkConfig ? false : true
			},
			{
				header: ip2.i18n({
					en: "Caption",
					da: "Billedunderrubrik"
				}),
				toolTip: ip2.i18n({
					en: "Caption",
					da: "Billedunderrubrik"
				}),
				flex: 4,
				dataIndex: "caption",
				hidden: true
			},
			{
				xtype: "actioncolumn",
				iconCls: "pf-navigate_cross",
				width: 80,
				sortable: false,
				draggable: false,
				resizable: false,
				hideable: false,
				menuDisabled: true,
				align: "center",
				handler: function (i_view, n_row) {
					this.up("gallerymediagrid").fireEvent("itemremove", n_row);
				}
			}
		]);

		Ext.apply(i_cmp, {
			columns: a_columns,
			_previewMap: {
				image: function (i_record) {
					return {
						xtype: "image",
						src: i_record.get("url"),
						height: 345,
						maxWidth: 420
					};
				},
				video: function (i_record) {

					var value = i_record.get("url");
					var s_url = value;
					if (Ext.isObject(value)) {
						s_url = value[i_cmp.language];
						if (!s_url) {
							s_url = value.any || "";
						}
					}
					var i_meta = ip2.mediaMeta.fromUrl(s_url);
					var o_config;

					if (i_meta && i_meta.getIframe()) {
						o_config = {
							xtype: "container",
							html: i_meta.getIframe(420, 345, true)
						};
					}

					return o_config;
				}
			},
			cls: "x-ux-imagegrid",
			listeners: {
				afterrender: {
					fn: function(i_self) {
						var i_header = i_self.headerCt;
						i_self.tip = Ext.create("Ext.tip.ToolTip", {
							target: i_header.el,
							delegate: ".x-column-header",
							trackMouse: true,
							renderTo: Ext.getBody(),
							listeners: {
								beforeshow: {
									fn: function(tip) {
										var i_column = i_header.down("gridcolumn[id=" + tip.triggerElement.id + "]");
										if (i_column && i_column.toolTip) {
											tip.update(ip2.i18n(i_column.toolTip));
										}
										else {
											return false;
										}
									}
								}
							}
						});
					}
				}
			}
		});

		return i_cmp;
	},

	changeLanguage: function(s_lang) {
		var i_self = this;
		i_self.language = s_lang;
		var i_view = i_self.getView();
		i_view.refresh();
	},

	createSpecialColumnInput: function (i_record, o_config) {

		var i_cmp = this;

		var s_recordId = i_record.internalId;
		var value = i_record.get(o_config._key);

		var s_checked = value ? "checked" : "";
		var s_inputType = o_config.inputType;

		var s_name = [
			o_config.dataGroup || o_config.dataIndex || o_config.name,
			i_cmp.id
		].join("-");

		var s_id = [
			o_config.dataIndex || o_config.dataGroup || o_config.name,
			s_recordId,
			ip2.unique()
		].join("-");

		if (o_config.context == "row" || o_config.context == null) {
			s_name = [s_name, s_recordId].join("-");
		}

		var s_html = Ext.create("Ext.XTemplate",
			"<table ",
				"class=\"x-ux-gallery-cell\"",
				"style=\"text-align: center;",
				"width: 100%;\"",
			">",
				"<tr>",
					"<td valign=\"middle\">",
						"<input ",
							"id=\"" + s_id + "\"",
							"type=\"" + s_inputType + "\"",
							"class=\"" + s_name + "\"",
							"name=\"" + s_name + "\"",
							"value=\"" + s_recordId + "\"",
							"key=\"" + o_config._key + "\"",
							s_checked,
						"/>",
					"</td>",
				"</tr>",
			"</table>").html;

		return {
			id: s_id,
			html: s_html
		};
	},

	// TODO: Optimize for row type context or none (radiobutton used as checkbox)
	applyRadioCheckboxBehavior: function (s_id, o_config) {

		var i_cmp = this;

		// We wrap in a timeout to get behind in the stack
		// form the renderer calling us - so the HTML can be
		// rendered
		setTimeout(function () {

			var i_el = Ext.get(s_id);

			if (i_el) {

				i_el.on("click", function (o_event, i_self) {
					var s_class = i_self.name;
					var a_group = i_cmp.getInputByClass(s_class);
					var s_key = s_class.split("-").shift();

					ip2.each(a_group, function (i_input) {

						var i_record = i_cmp.getRecordFromInput(i_input);
						var o_values = {};
						if (i_self.id != i_input.id) {
							o_values[s_key] = false;
						}
						else {
							o_values[s_key] = !i_record.get(s_key);
						}
						i_cmp.silentSet(i_record, o_values);
					});

					i_self._changeChecker = true;

					/*
						var s_key = i_self.name.split("-").pop();
						var i_record = i_cmp.getRecordFromInput(i_self);
						var b_selfChange = i_self._selfCheck;

						if ( !i_self._changeChecker ) {

							i_self.checked = false;

							i_cmp.allowImageRender--;
							i_record.set(s_key, false);
							i_cmp.allowImageRender++;
						}

						i_self._changeChecker = false;
					*/
				});
			}
		}, 4);
	},

	// TODO: Optimize for row type context
	applyRadioBehavior: function (s_id, o_config) {

		var i_cmp = this;
		var i_store = i_cmp.store;

		// We wrap in a timeout to get behind in the stack
		// form the renderer calling us - so the HTML can be
		// rendered
		setTimeout(function () {

			var i_el = Ext.get(s_id);

			if (i_el) {

				i_el.on("change", function (o_event, i_self) {

					var s_class = i_self.name;
					var a_group = [];

					// row context based behavior
					if (o_config.context == "row") {

						var o_values = {};

						a_group = i_cmp.getInputByClass(s_class);

						ip2.each(a_group, function (i_input) {

							var s_key = (function (a_attr) {
								var found;
								ip2.each(a_attr, function (attr, s_attr) {
									if (attr.name == "key") {
										found = attr.value;
									}
								});
								return found;
							})(i_input.attributes);

							o_values[s_key] = i_input.checked;

							//o_values[s_key] = i_input.id == s_id ? true : false;
						});

						var i_record = i_cmp.getRecordFromInput(i_self);
						i_cmp.silentSet(i_record, o_values);
					}

					// column context based behavior
					else {

						a_group = i_cmp.getInputByClass(s_class);

						ip2.each(a_group, function (i_input) {

							var s_key = i_input.name.split("-").shift();
							var i_record = i_cmp.getRecordFromInput(i_input);
							var o_values = {};

							o_values[s_key] = i_input.id == s_id ? true : false;
							i_cmp.silentSet(i_record, o_values);
						});
					}
				});
			}
		}, 4);
	},

	applyCheckboxbehavior: function (s_id, o_config) {

		var i_cmp = this;

		// We wrap in a timeout to get behind in the stack
		// form the renderer calling us - so the HTML can be
		// rendered
		setTimeout(function () {

			var i_el = Ext.get(s_id);

			if (i_el) {

				i_el.on("change", function (o_event, i_self) {

					var i_record = i_cmp.getRecordFromInput(i_self);
					var s_key = i_self.name.split("-").shift();
					var o_values = {};

					o_values[s_key] = i_self.checked;

					i_cmp.silentSet(i_record, o_values);
				});
			}
		}, 4);
	},

	onEnterKey: function (i_view, i_record) {

		var i_cmp = this;
		var i_store = i_cmp.getStore();
		var n_row;

		i_store.each(function (i_item, n_index) {
			if (i_item.internalId == i_record.internalId) {
				n_row = n_index;
			}
		});

		i_cmp.fireEvent("itemedit", n_row);

		return i_cmp;
	},

	onDeleteKey: function (i_view, i_record, i_node, n_index) {

		var i_cmp = this;

		i_cmp.fireEvent("deletekey", i_record, n_index);

		return i_cmp;
	},

	silentSet: function (i_record, o_values) {

		var i_cmp = this;
		var i_store = i_cmp.getStore();
		i_cmp.allowImageRender--;
		i_record.set(o_values);
		i_store.fireEvent("datachanged", i_store);
		i_cmp.allowImageRender++;

		return i_cmp;
	},

	getInputByClass: function (s_class) {

		var i_cmp = this;
		var i_el = i_cmp.getView().getEl();
		var a_input = i_el.query(".x-ux-gallery-cell input." + s_class);

		return a_input;
	},

	getColumnInputs: function (s_key) {

		var i_cmp = this;
		var i_el = i_cmp.getView().getEl();
		var a_input = i_el.query(".x-ux-gallery-cell input." + s_key);

		return a_input;
	},
	getRecordFromInput: function (i_input) {

		var i_cmp = this;
		var i_store = i_cmp.getStore();
		var s_id = i_input.value;
		var i_record;

		i_store.findBy(function (i_found) {
			if (i_found.internalId == s_id) {
				i_record = i_found;
				return true;
			}
		});

		return i_record;
	}
});
