/**
 * PeriodeSearchor.
 * 
 * @depends dago.js
 */
(function($) {
	$.PeriodeSearch = function(el, options) {
		// Setup base
		var base = this; // the javascript object. Always refer to base to
							// avoid
		// scope errors in inline functions
		base.$el = $(el); // the jQuery element
		base.el = el; // the DOM element
		base.pluginName = "PeriodeSearch";
		base.$el.data(base.pluginName, base); // Add a reverse reference to
		// the DOM object

		// options
		base.options = $.extend({}, $.PeriodeSearch.defaultOptions, options);
		// logging
		var log = MUSSAM.setupPluginLog(base);
		// Properties

		// Now where everything is declared and defined above, we are ready to
		// initialize.
		base.init = function() {
			log.info("init()");
			base.firstRendering = true; // will be false after rendering the first time. This is to avoid focusing periode input fields when rendering the form for the first time
			base.tabIndex = base.options.tabIndexOffset++;
			// Events

			base.render();
			base.firstRendering = false;
		}

		// Methods

		base.render = function() {
			log.info("render()");
			base.$el.empty();
			base.$editor = $("<div ></div>");
			base.$el.append(base.$editor);
			if (base.options.textDisplayElm) {
				base.$textDisplay = $(base.options.textDisplayElm);
			} else {
				base.$textDisplay = $("<div id='periodeTextDisplayElm'></div>");
				base.$el.append(base.$textDisplay);
			}
			base.$periodeStartAarForm = $("#periodeStartAar");
			if (!base.$periodeStartAarForm.length) {
				log.error("No periodeStartAar element found in DOM");
			}
		
			base.periodeStartAar = null;
			base.periodeSlutAar = null;
			
			base.$periodeSlutAarForm = $("#periodeSlutAar");
			if (!base.$periodeSlutAarForm.length) {
				log.error("No periodeSlutAar element found in DOM");
			}
		
			base.renderEditor();
			base.update(base.options.input);
		};

		base.renderEditor = function() {
			log.info("renderEditor()");
			var html = "";

			base.$editor.$typeSelect = $("<select tabIndex='" + (base.tabIndex++) + "' class='field periodeSelect'><option value='exactYear'>Pr&aelig;cist &aring;r</option> <option value='before'>F&oslash;r &aring;r</option> <option value='after'>Efter &aring;r</option> <option value='interval' selected>Fra/til &aring;r</option> <option value='decade'>&Aring;rti</option> <option value='century'>&aring;&aring;&aring;&aring;-tallet</option> </select>");
			var $typeSelectWrapper = $("<div/>");
			$typeSelectWrapper.append(base.$editor.$typeSelect);
			base.$editor.append($typeSelectWrapper);
			base.$editor.$typeSelect.change(function() {
				base.updateTypeSelect();
				base.updateYear();
			});

			base.$editor.$left = $("<input tabIndex='" + (base.tabIndex++) + "' type='text' class='fieldSmall'/>");
			base.$editor.$rightLabel = $("<span>&nbsp;&ndash;&nbsp;</span>");
			base.$editor.append("<br/>").append(base.$editor.$left).append(base.$editor.$rightLabel);
			base.$editor.$left.change(base.updateYear);
			base.$editor.$right = $("<input tabIndex='" + (base.tabIndex++) + "' type='text' class='fieldSmall' style='disabled: true;'/>");
			base.$editor.append(base.$editor.$right);
			base.$editor.$right.change(base.updateYear);

			var $kodeDiv = $("<div/>");
			base.$editor.$kode = $("<input tabIndex='" + (base.tabIndex++) + "' type='text' id='periodeKode' class='fieldSmall'/>");
			$kodeDiv.append("Kode&nbsp;").append(base.$editor.$kode);
			
			// Kode disabled for Mussam
			// base.$editor.append($kodeDiv);
			base.$editor.$kode.change(base.fetchKode);
		}

		base.renderTextDisplay = function(input) {
			log.info("renderTextDisplay()");
			if (input == null || input['isExactPeriod'] == null) {
				log.warn("renderTextDisplay() - no input");
				return;
			}
			var html = "";
			if (input['isExactPeriod']) {
				html = input.periodAsText + " " + input.matchText;
			} else if (input['matchText'] > "") {
				html = input['periodAsText'] + " <span title='"
						+ input['matchLongText'] + "'>" + input['matchText']
						+ " (omtrent)</span>";
			} else {
				html = "";
			}
			base.$textDisplay.html(html);
		}

		base.renderTextDisplayError = function(errorText) {
			base.$textDisplay.html("<span style='color: red'>" + errorText
					+ "</span>");
		}

		base.fetchInterval = function() {
			base.updatePeriodeForm(null, null);
			
			var ajaxUrl = MUSSAM.contextPath() + "/AjaxPeriode.action?event=jsonInterval";
			ajaxUrl += "&startAar=" + base.periodeStartAar + "&slutAar=" + base.periodeSlutAar;
			log.info("Ajax GET: " + ajaxUrl);
			$.ajax({
						url : ajaxUrl,
						type : 'GET',
						dataType : 'json',
						success : function(json) {
							if (json['error']) {
								log.info("fetchInterval() - Ajax GET error: " + JSON.stringify(json));
								base.updatePeriodeForm(null, null);
								base.$editor.$kode.val("");
								if (json['error']['msg'] == 'empty interval') {
								  base.renderTextDisplayError(MUSSAM.message('periode.interval.empty'));
								} else if (json['error']['msg'] == 'illegal interval') {
								  base.renderTextDisplayError(MUSSAM.message('periode.interval.illegal'));
								} else {
								  base.renderTextDisplayError(json.error['userMsg']);
								}
								base.updatePeriodeForm(base.periodeStartAar, base.periodeSlutAar);//Insert search interval even if it don't match a defined "periode"
							} else {
								log.info("fetchInterval() - Ajax GET succes: "
										+ JSON.stringify(json));
								base.renderTextDisplay(json.success.result);
								base.$editor.$kode.val(json.success.result.kode);
								base.updatePeriodeForm(base.periodeStartAar, base.periodeSlutAar);
							}
						},
						error : function(xhr, textStatus, exception) {
							log.error("fetchInterval() - AjaxError: " + textStatus + ", response: " + xhr.responseText);
							base.updatePeriodeForm(null, null);
							base.renderTextDisplayError(MUSSAM.message('periode.notfound'));
						}
					});
		}

		// not used
		base.fetchKode = function() {
	    var ajaxUrl = MUSSAM.contextPath() + "/AjaxPeriode.action?event=jsonKode";
			ajaxUrl += "?kode=" + encodeURIComponent(base.$editor.$kode.val());
			log.info("Ajax GET: " + ajaxUrl);
			$.ajax({
						url : ajaxUrl,
						type : 'GET',
						dataType : 'json',
						success : function(json) {
							if (json['error']) {
								log.info("fetchKode() - Ajax GET error: " + JSON.stringify(json));
								base.updatePeriodeForm(null, null);
								base.renderTextDisplayError(json.error['userMsg']);
							} else {
								log.info("fetchKode() - Ajax GET succes: " + JSON.stringify(json));
								base.update(json.success.result);
								base.updateYear();
								base.updatePeriodeForm(base.periodeStartAar, base.periodeSlutAar);
							}
							base.$editor.$kode.focus();
						},
						error : function(xhr, textStatus, exception) {
							log.error("fetchKode() - AjaxError: " + textStatus + ", response: " + xhr.responseText);
							base.updatePeriodeForm(null, null);
							base.renderTextDisplayError("Fejl: kunne ikke bestemme periode ud fra koden "
											+ base.$editor.$kode.val());
							base.$editor.$kode.focus();
						}
					});
		}

		/**
		 * Transfer data from input parameter to GUI elements.
		 */
		base.update = function(input) {
			log.info("update() - "); //  + JSON.stringify(input)
			base.renderTextDisplay(input);

			base.$editor.$kode.val(input.kode);
			if (input.startAar != null && input.startAar == input.slutAar) {
				base.$editor.$typeSelect.val("exactYear");
				base.$editor.$left.val(input.startAar);
				base.$editor.$right.val(input.slutAar);
			} else if (input.startAar == null && input.slutAar != null) {
				base.$editor.$typeSelect.val("before");
				base.$editor.$left.val(input.slutAar); // note that we use the
														// left input for the
														// slutAar value
				base.$editor.$right.val(null);
			} else if (input.startAar != null && input.slutAar == null) {
				base.$editor.$typeSelect.val("after");
				base.$editor.$left.val(input.startAar);
				base.$editor.$right.val(null);
			} else if ((9 == input.slutAar - input.startAar)
					&& (Math.min(Math.abs(input.startAar), Math.abs(input.slutAar)) % 10 == 0)) { // decade ex.
																// 1950-1959 =>
																// 50'erne or
																// -59 - -50 =>
																// 50'erne f.Kr.
				base.$editor.$typeSelect.val("decade");
				base.$editor.$left.val(input.startAar);
				base.$editor.$right.val(null);
			} else if ((99 == input.slutAar - input.startAar)
					&& (Math.min(Math.abs(input.startAar), Math.abs(input.slutAar)) % 100 == 0)) { // century ex.
																// 1800-1899 =>
																// 1800-tallet
																// or -199 -
																// -100 =>
																// 100-tallet
																// f.Kr
				base.$editor.$typeSelect.val("century");
				base.$editor.$left.val(input.startAar);
				base.$editor.$right.val(null);
			} else {
				base.$editor.$typeSelect.val("interval");
				base.$editor.$left.val(input.startAar);
				base.$editor.$right.val(input.slutAar);
			}
			base.updatePeriodeForm(input.startAar, input.slutAar);
			base.updateTypeSelect();
		}

		// Event handlers

		/**
		 * Transfer the (validated) GUI year values to the form - ready to be
		 * POST'ed.
		 */
		base.updatePeriodeForm = function(startAar, slutAar) {
			log.info("updatePeriodeForm():  " + startAar + " - " + slutAar + "")
			base.$periodeStartAarForm.val(startAar);
			base.$periodeSlutAarForm.val(slutAar);
		}

		/**
		 * Transfer the GUI elements to the
		 */
		base.updateYear = function() {
			log.info("updateYear()");
			var selectVal = base.$editor.$typeSelect.val();
			if (selectVal == 'exactYear') {
				base.periodeStartAar = base.$editor.$left.val();
				base.periodeSlutAar = base.$editor.$left.val();
			} else if (selectVal == 'before') {
				base.periodeStartAar = "";
				base.periodeSlutAar = base.$editor.$left.val();
			} else if (selectVal == 'after') {
				base.periodeStartAar = base.$editor.$left.val();
				base.periodeSlutAar = "";
			} else if (selectVal == 'interval') {
				base.periodeStartAar = base.$editor.$left.val();
				base.periodeSlutAar = base.$editor.$right.val();
			} else if (selectVal == 'decade') {
				if (base.$editor.$left.val() < 0) {
					base.periodeSlutAar = base.$editor.$left.val() * 1 - base.$editor.$left.val() % 10;
					base.periodeStartAar = base.periodeSlutAar * 1 - 9;
				} else {
					base.periodeStartAar = base.$editor.$left.val() * 1 - base.$editor.$left.val() % 10;
					base.periodeSlutAar = base.periodeStartAar * 1 + 9;
				}
			} else if (selectVal == 'century') {
				if (base.periodeStartAar < 0) {
					base.periodeSlutAar = base.$editor.$left.val() * 1 - base.$editor.$left.val() % 100;
					base.periodeStartAar = base.periodeSlutAar * 1 - 99;
				} else {
					base.periodeStartAar = base.$editor.$left.val() * 1 - base.$editor.$left.val() % 100;
					base.periodeSlutAar = base.periodeStartAar * 1 + 99;
				}
			} else {
				log.error("Unknown select value: " + selectVal);
				base.periodeStartAar = base.$editor.$left.val();
				base.periodeSlutAar = base.$editor.$left.val();
			}

			base.fetchInterval();
		}

		base.updateTypeSelect = function() {
			log.info("updateTypeSelect()");
			var selectVal = base.$editor.$typeSelect.val();
			if (selectVal == 'exactYear') {
				base.$editor.$right.val("");
				base.$editor.$right.hide();
				base.$editor.$rightLabel.hide();
				base.$editor.$left.show();
				if (!base.firstRendering) base.$editor.$left.focus();
			} else if (selectVal == 'before') {
				base.$editor.$right.val("");
				base.$editor.$right.hide();
				base.$editor.$rightLabel.hide();
				base.$editor.$left.show();
				if (!base.firstRendering) base.$editor.$left.focus();
			} else if (selectVal == 'after') {
				base.$editor.$right.val("");
				base.$editor.$right.hide();
				base.$editor.$rightLabel.hide();
				base.$editor.$left.show();
				if (!base.firstRendering) base.$editor.$left.focus();
			} else if (selectVal == 'interval') {
				base.$editor.$left.show();
				base.$editor.$right.show();
				if (!base.firstRendering) base.$editor.$right.focus();
				base.$editor.$rightLabel.show();
			} else if (selectVal == 'decade') {
				base.$editor.$right.val("");
				base.$editor.$right.hide();
				base.$editor.$rightLabel.hide();
				base.$editor.$left.show();
				if (!base.firstRendering) base.$editor.$left.focus();
			} else if (selectVal == 'century') {
				base.$editor.$right.val("");
				base.$editor.$right.hide();
				base.$editor.$rightLabel.hide();
				base.$editor.$left.show();
				if (!base.firstRendering) base.$editor.$left.focus();
			} else {
				log.error("Unknown select value: " + selectVal);
				base.$editor.$left.show();
				base.$editor.$right.show();
			}
		}

		base.init();
	};

	$.PeriodeSearch.defaultOptions = {
		tabIndexOffset : 0,
		textDisplayElm : null,
		input : {
			startAar : null,
			slutAar : null,
			kode : "",
			isExactPeriod : false,
			periodAsText : "",
			matchText : "",
			matchLongText : ""
		},
		useLogging : true
	};

	$.fn.PeriodeSearch = function(options) {
		return this.each(function() {
			(new $.PeriodeSearch(this, options));
		});
	};

	// This function breaks the chain, but returns
	// the object if it has been attached to the object.
	$.fn.getPeriodeSearch = function() {
		this.data("PeriodeSearch");
	};

})(jQuery);
