Ext.define("Portfolio.util.Message", {

	singleton: true,

	alternateClassName: [
		"ip2.message"
	],

	config: {
		grid: null,
		model: null,
		showErrors: false,
		oldText: ""
	},

	init: Ext.emptyFn,

	requires: [
		"Portfolio.message.view.Main"
	],

	constructor: function(o_config) {

		var i_self = this;

		i_self.initConfig(o_config);

		i_self.initError();

		return i_self;
	},

	initGrid: function (o_config) {

		var i_self = this;

		Ext.apply(o_config, {
			listeners: {
				viewerror: {
					fn: function(i_record) {
						i_self.onView(i_record);
					}
				},
				itemcontextmenu: {
					fn: function (i_view, i_record, item, index, e, options) {

						e.preventDefault();

						var a_coords = e.getXY();
						var i_contextMenu = i_self.getContextMenu(i_record);

						i_contextMenu.showAt(a_coords);
					}
				}
			}
		});

		var i_grid = Ext.widget("portfolio-message-grid",
			o_config
		);

		var i_store = i_grid.getStore();
		var i_model = i_store.getModel();

		i_self.setGrid(i_grid);
		i_self.setModel(i_model);

		Ext.GlobalEvents.fireEvent("messageReady", i_self);

		return i_grid;
	},

	getContextMenu: function (i_record) {

		var i_self = this;
		var i_grid = i_self.getGrid();

		var i_menu = Ext.widget("menu", {
			items: [
				{
					xtype: "menuitem",
					text: ip2.i18n({
						da: "Vis",
						en: "Show"
					}),
					iconCls: "pf-magnifying_glass",
					handler: function() {
						i_self.onView(i_record);
					}
				},
				{
					xtype: "menuitem",
					text: ip2.i18n({
						da: "Ryd",
						en: "Clear"
					}),
					iconCls: "pf-delete",
					handler: function() {

						i_grid.getStore().removeAll();

						if (i_self.getShowErrors()) {
							i_grid.setTitle(i_self.getOldText());
							i_self.setOldText("");
							i_grid.header.setIcon("");
						}
					}
				}
			]
		});

		return i_menu;
	},

	onView: function(i_record) {

		var i_self = this;
		var s_url = i_record.get("url");
		var s_debugType = i_record.get("debugType");
		var s_mode = "javascript";
		var s_stack = i_record.get("completeStackTrace");

		var s_description = i_record.get("description");
		var s_date = i_record.get("date");

		var s_title = [
			"<strong>" + s_description + "</strong>",
			" (",
				Ext.util.Format.date(s_date, "Y.m.d   H:m:s"),
			")"
		].join("");

		switch (s_debugType) {
			case "js":
				s_mode = "javascript";
				break;
			case "json":
				s_mode = "json";
				break;
		}

		var i_stackArea = Ext.widget("panel", {
			title: "Stacktrace",
			layout: "fit",
			flex: 1,
			collapsed: false,
			collapsible: true,
			collapseDirection: "right",
			split: true
		});

		var i_messageArea = Ext.widget("panel", {
			title: "Message",
			layout: "fit",
			flex: 2,
			collapsed: false,
			collapsible: true,
			collapseDirection: "left",
			split: true
		});

		var i_contentArea = Ext.widget("panel", {
			layout: {
				type: "hbox",
				align: "stretch"
			},
			border: false,
			defaults: {
				margin: "0 5 0 0"
			},
			flex: 1
		});

		var i_stackTrace = Ext.widget("acetextarea", {
			hideLabel: true,
			mode: "javascript",
			name: "completeStackTrace",
			useWorker: false,
			margin: "0 0 0 0",
			listeners: {
				editorready: {
					fn: function() {

						var i_field = this;

						i_field.setValue(s_stack);
					},
					buffer: 100
				}
			}
		});

		var i_editor = Ext.widget("acetextarea", {
			hideLabel: true,
			name: "src",
			mode: s_mode,
			useWorker: false,
			flex: 1,
			listeners: {
				editorready: {
					fn: function() {

						var i_aceEditor = this;

						var n_line = i_record.get("lineNo");
						var o_params = i_record.get("params") || "";

						if (s_url) {
							Ext.Ajax.request({
								url: s_url,
								success: function(i_response) {

									var s_src = i_response.responseText;
									i_aceEditor.setValue(s_src);
									i_aceEditor.gotoLine(n_line);
								}
							});
						}
						else {
							i_aceEditor.setValue(o_params);
						}
					},
					buffer: 100
				}
			}
		});

		i_messageArea.add(i_editor);
		i_stackArea.add(i_stackTrace);

		i_contentArea.add([i_messageArea, i_stackArea]);

		var i_form = Ext.widget("form", {
			layout: {
				type: "vbox",
				align: "stretch"
			},
			border: false,
			record: i_record,
			bodyStyle: {
				background: "transparent"
			},
			bodyPadding: 10,
			items: [
				{
					xtype: "fieldset",
					layout: "anchor",
					defaults: {
						anchor: "100%",
						xtype: "textfield",
						readOnly: true,
						labelWidth: 160
					},
					title: ip2.i18n({
						da: "Informationer",
						en: "Information"
					}),
					items: [
						{
							fieldLabel: ip2.i18n({
								da: "Tekst",
								en: "Text"
							}),
							name: "description"
						},
						{
							fieldLabel: ip2.i18n({
								da: "Url",
								en: "Url"
							}),
							itemId: "url",
							name: "url"
						},
						{
							fieldLabel: ip2.i18n({
								da: "Besked",
								en: "Message"
							}),
							name: "message"
						},
						{
							fieldLabel: ip2.i18n({
								da: "Linie nummer",
								en: "Line Number"
							}),
							name: "lineNo"
						},
						{
							xtype: "hidden",
							name: "debugType"
						}
					]
				},
				i_contentArea
			]
		});

		var o_size = ip2.getWindowSize();

		var i_window = Ext.widget("window", {
			title: s_title,
			layout: "fit",
			width: o_size.width * 0.8,
			height: o_size.height * 0.9,
			resizable: true,
			listeners: {
				afterrender: {
					fn: function (i_self) {

						i_form.loadRecord(i_record);
					},
					single: true
				}
			},
			items: [
				i_form
			],
			buttonAlign: "right",
			buttons: [
				{
					text: ip2.i18n({
						da: "Luk",
						en: "Close"
					}),
					handler: function() {
						i_window.close();
					}
				}
			]
		});

		if (!s_stack) {
			i_stackArea.setCollapsed(true);
		}

		i_window.show();
	},

	AddJs: function(err) {

		var i_self = this;
		var message = err;

		message.Message = err.message;
		i_self.Add("Script error", message, "js");
	},

	AddLog: function(prop, log) {

		var i_self = this;
		var message;
		var url;

		url = Object.prototype.toString.call(log);
		try {
			message = JSON.stringify(log, null, 4);
		}
		catch (err) {
			message = "Cannot convert circular structure to string.";
		}
		i_self.Add(prop, {
			message: message,
			url: url
		}, "log");
	},

	AddAjax: function(i_response) {

		var o_result = {};
		var i_self = this;

		try {
			o_result = Ext.decode(i_response.responseText, true) || {};
			if (o_result.Message) {
				var p = o_result.Message.indexOf("\r");
				var s_title = (p > 0) ? o_result.Message.substring(0, p) : o_result.Message;
				i_self.Add(s_title, o_result, "ajax");
			}
			else {
				o_result.Message = i_response.responseText;
				i_self.Add(i_response.status + ": " + i_response.statusText, message, "ajax");
			}
		}
		catch (err) {
			o_result.Message = i_response.responseText;
			i_self.Add(i_response.status + ": " + i_response.statusText, message, "ajax");
		}
	},

	ProxyException: function (i_proxy, i_response, i_operation) {

		var i_self = this;
		var o_message = {};
		var s_title = "";

		if (i_operation.error) {
			o_message = i_operation.getError();
		}
		else if (i_response) {

			o_message = Ext.decode(i_response.responseText, true);

			if (o_message) {
				s_title = ip2.i18n("serverSideDBerror").replace(/:/g, "");
			}
		}

		i_self.Add(s_title, o_message);
	},

	Add: function(s_description, o_error, s_debugType) {

		o_error = o_error || {
			message: "",
			stack: ""
		};

		Ext.applyIf(o_error, {
			message: "",
			Message: ""
		});

		s_debugType = s_debugType || "js";

		var i_self = this;
		var i_grid = i_self.getGrid();

		if (i_grid) {

			var i_store = i_grid.getStore();

			var s_message = o_error.Message ? o_error.Message : o_error.message || "";

			var s_src = o_error.src || o_error.url || "";

			var i_model = i_self.getModel();

			var i_record = i_model.create({
				description: s_description,
				message: s_message,
				completeStackTrace: o_error.completeStackTrace || o_error.CompleteStackTrace || "",
				errorType: o_error.ErrorType || "",
				isRestException: o_error.IsRestException || "",
				src: s_src,
				lineNo: o_error.lineNo || "",
				date: new Date(),
				urlText: o_error.urlText || s_message,
				url: s_src,
				params: o_error.params,
				debugType: s_debugType
			});

			i_store.add(i_record);

			var s_title = s_description + ' ' + ip2.i18n({
				da: "klik her for flere detaljer",
				en: "click here for more details"
			});



			if (i_self.getShowErrors()) {

				i_grid.header.setIcon("/system/shared/collection/icons/16x16/plain/sign_warning.png");

				var s_oldText = i_grid.getTitle();

				var s_stored = i_self.getOldText();

				if (!s_stored) {
					i_self.setOldText(s_oldText);
				}

				i_grid.setTitle(s_title);
			}
		}
	},

	initError: function() {

		var i_self = this;

		window.onerror = function(s_message, s_url, n_lineno, n_colno, o_error) {

			// THIS IS ANGULAR HACK TO HANDLE ZONE ALREADY LOADED ERROR

			if (!/Zone already]/.test(s_message)) {

				i_self.Add(o_error.name, {
					message: s_message,
					url: s_url,
					lineNo: n_lineno,
					completeStackTrace: o_error.stack
				}, "js");
			}

			Portfolio.util.Handler.unmask();

			Portfolio.app.fireEvent("applicationError", o_error);

			return true;
		};
	}
});
