// i18n resource
$.lang('display', {
	de: 'Anzeige',
	en: 'Display'
});
$.lang('emailSupportNotification', {
	de: 'E-Mail-Benachrichtigung wurde aktiviert!',
	en: 'Email notification was activated!'
});


$(function(){
	var allSelects = $('.massDataElsShell select'),
	checkFirstSelectValue = function(val, modus){
		if (val == 25850 || val == 25840){
			// clm or wettreg
			StationSelectService.climateData({'clima': val});
			$('#stationMap').show();
			if (!modus){
				$("#stationName").empty();
				$("#stationId").val(null);
			}
		}else{
			// nothing selected
			StationSelectService.climateData({'clima': null});
			$('#stationMap').hide();
			$("#stationName").empty();
			$("#stationId").val(null);
		}
	}
	checkFirstSelectValue(allSelects.eq(0).val(), 'start');
	allSelects.change(function(){
		setSimulationAvailable();
		if (allSelects.eq(0).get(0) === this){
			checkFirstSelectValue($(this).val());
		}
	});
	setStationName($("#stationId").val());
});


var setSimulationAvailable = function() {
	if ($('form.massDataElsShell').length){
		var params = Utils.getUrlParamsAsJson('?' + $('form.massDataElsShell').serialize()), url, ready = true, k, simTyp;
		delete params["com.livinglogic.cms.apps.search.model.SearchState.search_submit"];
		delete params["app"];
		simType = $('#simulationTyp');
		params.simType = simType.val();
		for (k in params){
			if (params[k] === ''){
				ready = false;
			}
		}
		if (ready){
			url = AjaxURLManager.getUrlWithKey('simulationavailable', params);
			$.extend(params, {'t': new Date().getTime()});
			$.getJSON(url, function(data, textStatus){
				$('#renderTime').html(data.statustext);
				if (data.available) {
					$("#renderInfo").addClass('renderedOverlayAvailable');
				} else {
					$("#renderInfo").removeClass('renderedOverlayAvailable');
				}
			});
		}else{
			if ($('#renderTime').text() !== ''){
				$('#renderTime').empty();
				$("#renderInfo").removeClass('renderedOverlayAvailable');
			}
		}
	}
}
$(function(){
	setSimulationAvailable();
	if($('#gebietId').val()){
		setGebietName($('#gebietId').val());
	}
	$('select[name^=searchLookup]').click(function(){
		var isReady = true;
		$('select[name^=searchLookup]').each(function(i){
			if ($(this).val() === ''){
				isReady = false;
			}
		});
		if (isReady){
			setSimulationAvailable();
		}
	});
});



function setStationName(stat_id) {
	var url = AjaxURLManager.getUrlWithKey('stationname', {'stat_id': stat_id});
	$("#stationName").empty();
	if (stat_id) {
		$.getJSON(url, function(data, textStatus){
			$("#stationName").text(data.value);
		});
	}
}

var getStationMapHref = function() {
	var href = 'http://www.landcare-dss.de/google/stationmap.html';
	if ($('#climatedata').val() == 25850) {
		// clm
		href = href + '?climatedata=clm&type=' + $('#stationType').val();
	} else if ($('#climatedata').val() == 25840) {
		// wettreg
		href = href + '?climatedata=wettreg&type=' + $('#stationType').val();
	}
	if ($('#stationId').val()) {href = href + '&stat_id=' + $('#stationId').val();}
	return href;
}


function setGebietName(geb_id) {
	var url = AjaxURLManager.getUrlWithKey('areadata', {'geb_id': geb_id});
	$("#gebietName").empty();
	if (geb_id) {
		$.getJSON(url, function(data, textStatus){
			$("#gebietName").empty();
			if (data.name) {
				$("#gebietName").append("<b>" + data.name + "</b>");
			} else {
				$("#gebietName").append("<span style=\"margin-right: 7px;\"><b>S-W:</b> " + Math.round(data.y1*100) / 100 + ", " + Math.round(data.x1*100) / 100 + "</span><span><b>N-O:</b> " + Math.round(data.y2*100) / 100 + ", " + Math.round(data.x2*100) / 100 + "</span>");
			}
		});
	}
}

function selectGebiet(geb_id){
	$("#gebietId").val(geb_id);
	setGebietName(geb_id);
	setSimulationAvailable();
}


function selectStation(stat_id){
	$("#stationId").val(stat_id);
	setStationName(stat_id);
	setSimulationAvailable();
}

function initializeAreaMap(callback, geb_id, kd_id) {
	if (GBrowserIsCompatible()) {
		var north = 55;
		var east = 15;
		var south = 47;
		var west = 6;
		var map = new GMap2(document.getElementById("gebietSelectPopupInner"));
		map.setCenter(new GLatLng((south + north) / 2, (east + west) / 2));
		map.setZoom(6);
		map.enableScrollWheelZoom();
		map.disableDoubleClickZoom();
		map.setUIToDefault();
		var areaControl = new AreaControl(callback, geb_id, kd_id);
		map.addControl(areaControl);
		var params = {};
		if (kd_id) {
			params.kd_id = kd_id;
		}
		if (geb_id) {
			params.geb_id = geb_id;
		}
		var url = AjaxURLManager.getUrlWithKey('areas', params);
		$.getJSON(url, function(data, textStatus){
			areaControl.setAreas(data.items);
			/*GEvent.addListener(map, 'zoomend', function(zOld, zNew){
			});*/
		});
	}
}

function initializeStationMap(climatedata, type, stat_id) {
	if (GBrowserIsCompatible()) {
		var north = 55;
		var east = 15;
		var south = 47;
		var west = 6;

		var map = new GMap2(document.getElementById("stationSelectPopupInner"));
		map.setCenter(new GLatLng((south + north) / 2, (east + west) / 2));
		map.setZoom(6);
		map.setUIToDefault();
		var cd;

		var blueIcon = new GIcon(G_DEFAULT_ICON);
		blueIcon.image = "http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png";

		var redIcon = new GIcon(G_DEFAULT_ICON);
		redIcon.image = "http://gmaps-samples.googlecode.com/svn/trunk/markers/red/blank.png";
		if (climatedata == 25850){
			cd = 'clm';
		}else if (climatedata == 25840){
			cd = 'wettreg';
		}else{
			cd = 'null';
		}
		var params = {};
		params.climatedata = cd;
		params.type = type;
		params.stat_id = stat_id;
		var url = AjaxURLManager.getUrlWithKey('stationlist', params);
		$.getJSON(url, function(data, textStatus){
			for (var i in data.items) {
				var marker = null;
				if (stat_id == data.items[i].id) {
					marker = new GMarker(new GLatLng(data.items[i].lat, data.items[i].lon), { icon:redIcon });
				} else {
					marker = new GMarker(new GLatLng(data.items[i].lat, data.items[i].lon), { icon:blueIcon });
				}
				(function(i, marker){
					GEvent.addListener(marker, "click", function() {
						marker.openInfoWindowHtml("<h4>" + data.items[i].name + '</h4><button onclick="StationSelectService.addStation(' + data.items[i].id + ', \'' + data.items[i].name + '\')">Station auswählen</button>')
					});
				})(i, marker);

				if (cd == "clm" && (type == null || type.length == 0)) {
					var mgr = new MarkerManager(map);
					if (i%18 == 0) {
						mgr.addMarker(marker, 6);
					} else if (i%9 == 0) {
						mgr.addMarker(marker, 7);
					} else if (i%3 == 0) {
						mgr.addMarker(marker, 8);
					} else {
						mgr.addMarker(marker, 9);
					}
					mgr.refresh();
				} else {
					map.addOverlay(marker);
				}
			}
		});
	}
}

// >> AJAX URL Manager jQuery 1.2.6 Version: rel-1-0-0
	AjaxURLManager = {
		mode: 'static',
		URL: {},
		sessionData: null,
		baseURL: '/backend/',
		baseURLStatic: '../static/',
		setBaseURL: function(url){
			this.baseURL = url;
		},
		setBaseURLStatic: function(url){
			this.baseURLStatic = url;
		},
		setMode: function(mode){
			this.mode = APP_MODE = mode;
		},
		registerKey: function(key, attrs, staticFile, allwaysStatic){
			this.URL[key] = {'attrs': attrs, 'staticFile': staticFile, 'allwaysStatic': allwaysStatic};
		},
		getUrlWithKey: function(key, attrs){
			if (this.URL[key]){
				var data = this.URL[key];
				if (data.attrs || attrs){
					if (data.attrs) attrs = $.extend(data.attrs, attrs);
					var realAttrs = {};
					for (var k in attrs){
						if (attrs[k] != null) realAttrs[k] = attrs[k];
					}
					if (this.sessionData) realAttrs = $.extend(realAttrs, this.sessionData);
					attrs = '?' + $.param(realAttrs);
				}else{
					if (this.sessionData){
						var attrs = $.extend(data.attrs, this.sessionData);
						attrs = '?' + $.param(this.sessionData);
					}
				}
				if (this.mode == 'static' && data.staticFile || data.allwaysStatic && data.staticFile){
					return [this.baseURLStatic,data.staticFile,attrs].join('');
				}
				return [this.baseURL,key,attrs].join('');
			}
			return null;
		}
	}
	AjaxURLManager.setMode('live');
	AjaxURLManager.registerKey('xreview', null, null, false);
	AjaxURLManager.registerKey('xreviewcomments', null, null, false);
	AjaxURLManager.registerKey('simulationsearch', null, null, false);
	AjaxURLManager.registerKey('simulationavailable', null, null, false);
	AjaxURLManager.registerKey('stationname', null, null, false);
	AjaxURLManager.registerKey('areadata', null, null, false);
	AjaxURLManager.registerKey('areas', null, null, false);
	AjaxURLManager.registerKey('stationlist', null, null, false);
	AjaxURLManager.registerKey('simulationresults', null, null, false);
	AjaxURLManager.registerKey('notify', null, null, false);
// <<


// >> XReview Version: exp-3 requires:
	// jQuery 1.2.6+,
	// toJson extension,
	// cookie plugin,
	// lang extension,
	// AjaxUrlManager rel-1-0-1,
	// Utilities rel-1-0-0

	// >> language resources
		$.lang('reviewPrompt', {
				"de": "Simulation bewerten",
				"en": "Rate simulation"
		});
		
		$.lang('reviewPopupTitle', {
				"de": "Wertung auswÃ¤hlen",
				"en": "Choose rating"
		});
		
		$.lang('xreviewPopupNoRating', {
				"de": "Keine Wertung",
				"en": "No rating"
		});
		
		$.lang('xreviewCommentsMore', {
				"de": "alles anzeigen",
				"en": "view more"
		});
		
		$.lang('xreviewCommentsLess', {
				"de": "weniger anzeigen",
				"en": "view less"
		});
		
		// language resources for form error messages
		$.lang('formError_name', {
				"de": "Bitte geben Sie einen Namen ein",
				"en": "Please enter your name"
		});
		
		$.lang('formError_headline', {
				"de": "Bitte geben Sie eine Überschrift ein",
				"en": "Please enter a headline"
		});
		
		$.lang('formError_comment', {
				"de": "Bitte geben Sie einen Kommentar ein",
				"en": "Please enter a comment"
		});
	// <<


	// >> XReview
		XReview = $.extend(
			$.clone(LLObject),
			{
				create: function (opts) {
					var o = LLObject.create.call(this);
					o.reviews = [];
					o.defaults = {
						'target': null,
						'baseReceiveHandler': 'xreview', // server side script receiver name for the base request.
						'baseSendHandler': 'xreview', // server side script receiver name for item clicks.
						'commentsReceiveHandler': 'xreviewcomments', // server side script receiver name for comments data.
						'maxVisualElements': 5, // maximum count of the visuals e.q. stars.
						'reviewOverallPrefix': 'xreviewOverall_', // Prefix of the overall container class name.
						'reviewType': 'simple', // simple | standard.
						'addReviewTotal': true, // added a total review number to the review action prompt.
						'reviewRequiresLogin': false, // Only logged on users can create a review.
						'onAfterInit': null, // Fires a callback after the initialisation.
						'onReviewSuccess': null, // Fires a callback if a request runs successfully.
						'onAfterElementCreated': null // Fires a callback if an review element creation has finished.
					};
					o.data = null;
					if (opts && typeof opts === 'object'){
						o.defaults = $.extend(o.defaults, opts);
					}
					o.detailId = null;
					return o;
				},
				init: function () {
					var ocs = this.getOverallIdCollectionString(),
							url = AjaxURLManager.getUrlWithKey(this.defaults.baseReceiveHandler, {'type': this.defaults.reviewType, 'ocs': ocs}),
							self = this,
							cb;
					$.getJSON(url, function (data, textStatus) {
						self.data = data;
						self.preparePageOverall();
						if (self.defaults.reviewRequiresLogin){
							User = (typeof XIST4C_GLOBALS !== 'undefined' &&  XIST4C_GLOBALS.login  &&  XIST4C_GLOBALS.login.userID &&  XIST4C_GLOBALS.login.userID != 'null') || null;
							if (User){
								self.preparePageReviewAction();
							}
						}else{
							self.preparePageReviewAction();
						}
						cb = self.defaults.onAfterInit;
						if (cb && typeof cb === 'function'){
							cb.call(self);
						}
					});
				},
				findPageOverallReviews: function () {
					return $('div[class^=' + this.defaults.reviewOverallPrefix + ']');
				},
				detailIdHandler: function (elm) {
					var pfx = this.defaults.reviewOverallPrefix,
							className = elm.attr("class"),
							self = this;
					return {
						get: function () {return className.substring(pfx.length, className.length);},
						set: function () {return (self.detailId = className.substring(pfx.length, className.length));}
					};
				},
				getOverallIdCollectionString: function () {
					var str = '',
							ovRevs = this.findPageOverallReviews(),
							self = this;
					ovRevs.each(function (i) {
						str += self.detailIdHandler($(this)).get() + ',';
					});
					if (str.length > 0){
						str = str.substring(0, str.length - 1);
					}
					return str;
				},
				preparePageOverall: function () {
					var ovRevs = this.findPageOverallReviews(),
							ovRevsData = this.data.reviews,
							self = this,
							elm, id, value, XrOv;
					ovRevs.each(function (i) {
						elm = $(this);
						id = self.detailIdHandler(elm).set();
						value = ovRevsData['_' + id].rating;
						XrOv = XReviewOverall.create();
						XrOv.target = elm;
						XrOv.id = self.defaults.reviewOverallPrefix + i;
						XrOv.domel = elm.get(0);
						XrOv.value = value;
						XrOv.parent = self;
						XrOv.data = ovRevsData['_' + id];
						self.reviews.push(XrOv);
						XrOv.make();
					});
				},
				preparePageReviewAction: function () {
					var target = $('div[class^=xreviewAction_]'), Xra, type;
					if (target.size() > 0){
						type = this.defaults.reviewType;
						if (type === 'simple'){
							Xra = XReviewSimpleOuterBox.create();
						}else if(type === 'standard'){
							Xra = XReviewStandardOuterBox.create();
						}
						Xra.target = target;
						Xra.id = 'xreview_abc'; /* todo: find a way to store a unique id */
						Xra.parent = this;
						Xra.data = this.data.reviews['_' + this.detailId];
						Xra.make();
					}
				},
				preparePageComments: function (data) {
					var target, url;
					if (this.defaults.allowComments){
						target = $('div.xreviewComments');
						if (target.size() > 0){
							url = AjaxURLManager.getUrlWithKey('xreviewcomments', {'detailId': this.detailId});
						}
					}
				},
				makeStandardReviewBoxLayout: function (commentFormTool) {
					var lay, self, data;
					if (commentFormTool){
						lay = $(
							'<div class="xreviewPopup">' +
								'<div class="xrDes1">' +
									'<div class="xrDes2">' +
										'<div class="xrDes3">' +
											'<div class="title">' + $.lang('reviewPopupTitle') + '</div>' +
											'<table cellpadding="0" cellspacing="0" border="0" class="itemsOuter">' +
											'</table>' +
										'</div>' +
									'</div>' +
								'</div>' +
							'</div>'
						);
					}else{
						lay = $(
							'<div id="xreviewStandardReviewPopup" class="xreviewPopup">' +
								'<div class="xrDes1">' +
									'<div class="xrDes2">' +
										'<div class="xrDes3">' +
											'<form method="post" action="#">' +
												'<input type="hidden" name="reviewId" value="' + this.detailId + '" />' +
												'<div class="title">' + $.lang('reviewPopupTitle') + '</div>' +
												'<table cellpadding="0" cellspacing="0" border="0" class="itemsOuter">' +
												'</table>' +
												'<div class="viewport buttonsShell">' +
													'<div class="button sendButton"></div>' +
													'<div class="button cancelButton"></div>' +
													'<div class="floatTerm"></div>' +
												'</div>' +
											'</form>' +
										'</div>' +
									'</div>' +
								'</div>' +
							'</div>'
						);
						self = this;
						lay.find('.sendButton').bind('click', function (e) {
							data = $('#xreviewStandardReviewPopup').find(':input').serializeArray();
							self.requestReview(data[0].value, data[1].value);
							self.closeReviewPopup();
						});
						lay.find('.cancelButton').bind('click', function (e) {
							self.closeReviewPopup();
						});
					}
					return lay;
				},
				openReviewPopup: function (pos) {
					$('#xreviewStandardReviewPopup').css(pos);
					$('#xreviewStandardReviewPopup').show('fast');
				},
				closeReviewPopup: function () {
					$('#xreviewStandardReviewPopup').hide('fast');
				},
				handleRatingRecordAndReturnPermission: function(formData){
					var cookieName = 'X-Review',
							User = (typeof XIST4C_GLOBALS !== 'undefined' &&  XIST4C_GLOBALS.login &&  XIST4C_GLOBALS.login.userID &&  XIST4C_GLOBALS.login.userID != 'null') || null,
							expireVal = 365,
							data;
					if (User){
						return {
							'userId': XIST4C_GLOBALS.login.userID || null,
							'userName': XIST4C_GLOBALS.login.userName || null
						};
					}else{
						if ($.cookie(cookieName)){
							eval('data = ' + $.cookie(cookieName));
							if ($.inArray(String(this.detailId), data.data) > -1){
								return false;
							}else{
								data.data.push(this.detailId);
								$.cookie(cookieName, $.toJson(data), { path: '/', expires: expireVal });
								return true;
							}
						}else{
							data = {type: "XReviewCookieData", data: [this.detailId]};
							$.cookie(cookieName, $.toJson(data), { path: '/', expires: expireVal });
							return true;
						}
					}
				},
				requestReview: function (detailId, rating, formData) {
					var url = AjaxURLManager.getUrlWithKey(this.defaults.baseSendHandler),
							params = {'detailId': detailId, 'rating': rating},
							fire = false,
							permission, self, cb;
					permission = this.handleRatingRecordAndReturnPermission(formData);
					if (formData){
						params = $.extend(params, {'formData': encodeURIComponent($.toJson(formData))});
					}
					if (typeof permission === 'object'){
						params = $.extend(params, permission);
						fire = true;
					}else if (permission === true){
						fire = true;
					}
					self = this;
					if (fire){
						$.ajax({
							type: 'post',
							url: url,
							data: params,
							success: function (data, msg) {
								eval('data = ' + decodeURIComponent(data));
								self.data = data;
								cb = self.defaults.onReviewSuccess;
								if (cb && typeof cb === 'function'){
									cb.call(self);
								}
								self.preparePageOverall();
								self.preparePageReviewAction();
							},
							error: function (req, status, error) {
								
							}
						});
					}
				}
			}
		);
	// <<

	// >> XReview Overall
		XReviewOverall = $.extend(
			$.clone(LLObject),
			{
				create: function () {
					var o = LLObject.create.call(this);
					o.type = 'XReviewOverall';
					o.target = null;
					o.value = 0;
					o.items = [];
					o.id = null;
					o.domel = null;
					o.parent = null;
					o.data = null;
					return o;
				},
				makeLayout: function () {
					var lay = $(
						'<div id="' + this.id + '" class="xreviewItemBox xreviewOverallItemBox">' +
							'<div class="inner"></div>' +
						'</div>'
					);
					return lay;
				},
				addItemsToShell: function (target) {
					var val = this.value,
							normVal = Math.floor(val * 2 + 0.5) / 2,
							count = this.parent.defaults.maxVisualElements,
							i, Item;
					for (i = 0; i < count; i+=1){
						Item = XReviewItem.create();
						Item.target = target;
						Item.parent = this;
						Item.index = i;
						if (i <= normVal){
							Item.active = true;
						}else if(i - 1 <= normVal){
							if (Math.floor(normVal) !== normVal){
								Item.half = true;
							}
						}
						Item.make();
						this.items.push(Item);
					}
				},
				afterElementCreated: function(){
					var cb = this.parent.defaults.onAfterElementCreated;
					if (cb && typeof cb === 'function'){
						cb.call(this);
					}
				},
				make: function () {
					var bl = this.makeLayout();
					this.target.empty().append(bl);
					this.addItemsToShell(bl.find('.inner'));
					this.afterElementCreated();
				}
			}
		);
	// <<

	// >> XReview Item
		XReviewItem = $.extend(
			$.clone(LLObject),
			{
				create: function () {
					var o = LLObject.create.call(this);
					o.target = null;
					o.parent = null;
					o.active = false;
					o.half = false;
					o.index = 0;
					o.detailId = null;
					return o;
				},
				makeLayout: function () {
					var lay = $(
						'<div class="xreviewItem xreviewItem_passive"></div>'
					);
					if (this.active){
						lay.removeClass('xreviewItem_passive').addClass('xreviewItem_active');
					}
					if (this.half){
						lay.removeClass('xreviewItem_passive');
						lay.removeClass('xreviewItem_active');
						lay.addClass('xreviewItem_half');
					}
					return lay;
				},
				bindEvents: function (lay) {},
				make: function () {
					var item = this.makeLayout();
					this.bindEvents(item);
					this.target.append(item);
				}
			}
		);
	// <<


	// >> XReview Simple outer box
		XReviewSimpleOuterBox = $.extend(
			$.clone(XReviewOverall),
			{
				create: function () {
					var o = XReviewOverall.create.call(this);
					o.type = 'XReviewSimpleOuterBox';
					o.hasBind = false;
					o.data = null;
					return o;
				},
				makeLayout: function () {
					var lay, prompt, total, pmt;
					lay = $(
						'<div id="' + this.id + '" class="xreviewItemBox xreviewSimpleItemBox">' +
							'<div class="inner"></div>' +
						'</div>'
					);
					prompt = $.lang('reviewPrompt');
					total = this.parent.defaults.addReviewTotal;
					if (prompt){
						pmt = $(
							'<div class="viewport xreviewPromptViewport">' +
								'<div class="promptOuter">' +
									'<span class="pmt">' + prompt + '</span>' +
								'</div>' +
							'</div>'
						);
						if (total){
							pmt.find('.promptOuter').append(
								'<span class="total">(' + this.data.total + ')</span>'
							);
						}
					}else{
						if (total){
							pmt = $(
								'<div class="viewport">' +
									'<div class="promptOuter">' +
										'<span class="total">(' + this.data.total + ')</span>' +
									'</div>' +
								'</div>'
							);
						}else{
							pmt = null;
						}
					}
					lay.find('.inner').prepend(pmt);
					return lay;
				},
				addItemsToShell: function (target) {
					var count = this.parent.defaults.maxVisualElements, i, Item;
					for (i = 0; i < count; i+=1){
						Item = SimpleXReviewItem.create();
						Item.target = target;
						Item.parent = this;
						Item.index = i;
						Item.detailId = this.parent.detailId;
						Item.make();
						this.items.push(Item);
					}
				}
			}
		);
	// <<


	// >> XReview Standard outer box
		XReviewStandardOuterBox = $.extend(
			$.clone(XReviewOverall),
			{
				create: function () {
					var o = XReviewOverall.create.call(this);
					o.type = 'XReviewStandardOuterBox';
					o.hasBind = false;
					o.data = null;
					return o;
				},
				makeLayout: function () {
					var lay, self, pos, popupHeight, total;
					lay = $(
						'<div id="' + this.id + '" class="xreviewItemBox xreviewStandardItemBox">' +
							'<div class="inner">' +
								'<div class="reviewActionButton"></div>' +
							'</div>' +
						'</div>'
					);
					self = this;
					lay.find('.reviewActionButton').bind('click', function (e) {
						pos = $(this).offset();
						popupHeight = $('#xreviewStandardReviewPopup').height();
						pos.top -= popupHeight + 10;
						self.parent.openReviewPopup(pos);
					});
					total = this.parent.defaults.addReviewTotal;
					return lay;
				},
				addItemsToShell: function (target) {
					$('body').append(this.parent.makeStandardReviewBoxLayout());
					var Item = StandardXReviewItem.create();
					Item.target = target;
					Item.parent = this;
					Item.index = 0;
					Item.detailId = this.parent.detailId;
					Item.make();
					this.items.push(Item);
				}
			}
		);
	// <<

	// >> Simple XReview Item
		SimpleXReviewItem = $.extend(
			$.clone(XReviewItem),
			{
				create: function () {
					var o = XReviewItem.create.call(this);
					return o;
				},
				bindEvents: function (lay) {
					var self = this;
					if (!this.parent.hasBind){
						$('#' + this.parent.id).find('div.inner').bind('mouseleave', function (e) {
							$(this).find('.xreviewItem').removeClass('xreviewItem_hover');
						});
						this.parent.hasBind = true;
					}
					lay.hover(
						function () {
							$(this).prevAll('.xreviewItem').andSelf().addClass('xreviewItem_hover');
						},
						function () {
							$(this).removeClass('xreviewItem_hover');
						}
					);
					if (this.detailId){
						lay.bind('click', function (e) {
							self.parent.parent.requestReview(self.detailId, self.index, null);
						});
					}
				}
			}
		);
	// <<

	// >> Standard XReview Item
		StandardXReviewItem = $.extend(
			$.clone(XReviewItem),
			{
				create: function () {
					var o = XReviewItem.create.call(this);
					return o;
				},
				makeLayout: function (firstItem) {
					var lay = $(
						'<tr>' +
							'<td class="option"></td>' +
							'<td class="visual">' +
							'</td>' +
						'</tr>'
					);
					if (!firstItem){
						lay.find('.visual').append('<div class="xreviewItemBox"></div>');
					}
					return lay;
				},
				makeOption: function () {
					return $('<input type="radio" name="rating" value="" />');
				},
				make: function (target) {
					var firstItem, firstOpt, max, i, j, item, opt, XrItem;
					if (!target || target.size() === 0){
						target = $('#xreviewStandardReviewPopup').find('.itemsOuter');
					}
					firstItem = this.makeLayout(true).clone();
					firstOpt = this.makeOption().clone().attr({'checked': 'checked'});
					firstOpt.attr({'value': -1});
					firstItem.find('.option').append(firstOpt);
					firstItem.find('.visual').html('<div class="noRatingPrompt">' + $.lang('xreviewPopupNoRating') + '</div>');
					target.append(firstItem);
					max = this.parent.parent.defaults.maxVisualElements;
					if (typeof max === 'undefined'){
						max = this.parent.defaults.maxVisualElements;
					}
					for (i = 0; i < max; i+=1){
						item = this.makeLayout().clone();
						opt = this.makeOption().clone().attr({'value': i});
						item.find('.option').append(opt);
						for (j = 0; j < i+1; j+=1){
							XrItem = XReviewItem.create();
							XrItem.target = item.find('.xreviewItemBox');
							XrItem.parent = this;
							XrItem.active = true;
							XrItem.index = j;
							XrItem.make();
						}
						target.append(item);
					}
				}
			}
		);
	// <<


	// >> XReview comments
		XReviewComments = $.extend(
			$.clone(LLObject),
			{
				create: function (opts) {
					var o = LLObject.create.call(this);
					o.comments = [];
					o.form = null;
					o.target = null;
					o.parent = null;
					o.defaults = {
						'target': null, // jquery object to append the comments.
						'xreview': null, // review base rating tool object.
						'baseReceiveHandler': 'xreviewcomments', // server side script receiver name for the base request.
						'baseSendHandler': 'xreview', // server side script receiver name for item clicks.,
						'commentsPrefix': 'xreviewComments_', // Prefix of the comments container class name.
						'commentsClipping': null, // Text clipping after number of chars.
						'commentFormPath': 'commentForm/', // Path to the XHTML form document.
						'requiredFormFields': [], // List with required form field names.
						'reviewRequiresLogin': false // Only logged on users can create a review.
					};
					o.data = null;
					if (opts && typeof opts === 'object'){
						o.defaults = $.extend(o.defaults, opts);
					}
					o.parent = o.defaults.xreview;
					return o;
				},
				init: function () {
					var target, url, self, XRCom;
					target = this.target = $('div[class^=' + this.defaults.commentsPrefix + ']');
					target.empty();
					target = this.makeBaseLayout(target);
					if (target.size() > 0){
						url = AjaxURLManager.getUrlWithKey(this.defaults.baseReceiveHandler, {'detailId': this.parent.detailId});
						self = this;
						$.getJSON(url, function (data, textStatus) {
							self.data = data;
							$(data.comments).each(function (i) {
								XRCom = XReviewComment.create();
								XRCom.parent = self;
								XRCom.data = this;
								XRCom.target = target;
								self.comments.push(XRCom);
								XRCom.make();
							});
							self.appendForm();
						});
					}
				},
				makeBaseLayout: function (target) {
					var lay = $('<div class="xreviewCommentsBaseContainer"></div>');
					target.append(lay);
					return target.find('.xreviewCommentsBaseContainer');
				},
				getCommentsId: function (elm) {
					var pfx = this.defaults.commentsPrefix,
							className = elm.attr("class");
					return className.substring(pfx.length, className.length);
				},
				appendForm: function () {
					var User, makeForm, Form, self = this;
					makeForm = function(){
						Form = XReviewCommentForm.create();
						Form.data = self.data;
						Form.target = self.target;
						Form.parent = self;
						self.form = Form;
						Form.make();
					};
					if (this.defaults.reviewRequiresLogin){
						User = (typeof XIST4C_GLOBALS !== 'undefined' &&  XIST4C_GLOBALS.login &&  XIST4C_GLOBALS.login.userID &&  XIST4C_GLOBALS.login.userID != 'null') || null;
						if (User){
							makeForm();
						}
					}else{
						makeForm();
					}
				}
			}
		);
	// <<

	// >> XReview comment
		XReviewComment = $.extend(
			$.clone(LLObject),
			{
				create: function () {
					var o = LLObject.create.call(this);
					o.parent = null;
					o.data = null;
					o.target = null;
					return o;
				},
				makeLayout: function () {
					var lay = $(
						'<div class="xreviewComment">' +
							'<div class="name"></div>' +
							'<div class="xreviewItemBox"></div>' +
							'<div class="headline"></div>' +
							'<div class="comment"></div>' +
						'</div>'
					);
					return lay;
				},
				injectData: function (item, clippingAfter, clippingKey) {
					var d = this.data, k, i, XrItem, text, eventFunc, rating;
					eventFunc = function (e) {
						e.preventDefault();
						e.stopPropagation();
						$(this).parents('.commentClippingOuter').find('.buttonOuter').toggle();
						$(this).parent('.buttonOuter').prevAll('.hiddenText').toggle();
						$(this).parent('.buttonOuter').prevAll('.dots').toggle();
					};
					for (k in d){
						if (k !== 'undefined'){
							if (k === 'rating'){
								rating = d[k];
								for (i = 0; i < this.parent.parent.defaults.maxVisualElements; i+=1){
									XrItem = XReviewItem.create();
									XrItem.target = item.find('.xreviewItemBox');
									XrItem.parent = this;
									if (! (rating === null || rating === -1)){
										if (i <= rating){
											XrItem.active = true;
										}
									}
									XrItem.index = i;
									XrItem.make();
								}
								continue;
							}
							if (clippingAfter && k === clippingKey){
								if (d[k].length > clippingAfter + 50){
									text = $(
										'<div class="commentClippingOuter">' +
											'<span class="clipping">' + d[k].substring(0, clippingAfter) + '</span>' +
											'<span class="dots">...</span>' +
											'<span class="hiddenText">' + d[k].substring(clippingAfter, d[k].length) + '</span>' +
											'<div class="buttonOuter more"><a href="#">' + $.lang('xreviewCommentsMore') + '</a></div>' +
											'<div class="buttonOuter less" style="display: none;"><a href="#">' + $.lang('xreviewCommentsLess') + '</a></div>' +
										'</div>'
									);
									item.find('.' + k).html(text);
									item.find('.hiddenText').hide();
									item.find('.buttonOuter a').bind('click', eventFunc);
									continue;
								}
							}
							item.find('.' + k).html(d[k]);
						}
					}
				},
				make: function () {
					var item = this.makeLayout();
					this.injectData(item, this.parent.defaults.commentsClipping, this.parent.data.clippingKey);
					this.target.append(item);
				}
			}
		);
	// <<


	// >> XReview  comment form
		XReviewCommentForm = $.extend(
			$.clone(LLObject),
			{
				create: function () {
					var o = LLObject.create.call(this);
					o.data = null;
					o.target = null;
					o.parent = null;
					return o;
				},
				injectXReviewRatingTool: function () {
					// xreviewRatingTool
					var XRev = this.parent.defaults.xreview, target;
					$('#xreviewRatingTool').append(XRev.makeStandardReviewBoxLayout(true));
					target = $('#xreviewRatingTool .itemsOuter');
					this.addItemsToShell(target, XRev);
				},
				addItemsToShell: function (target, XRev) {
					var Citem = StandardXReviewItem.create();
					Citem.target = target;
					Citem.parent = this.parent;
					Citem.index = 0;
					Citem.reviewId = XRev.reviewId;
					Citem.make(target);
				},
				makeLayout: function () {
					var lay = $(
						'<div id="xreviewCommentForm" class="xreviewCommentForm">' +
							'<div class="viewport showHideButtonOuter">' +
								'<div class="button showButton"></div>' +
								'<div class="button hideButton" style="display: none;"></div>' +
							'</div>' +
							'<div id="xreviewCommentFormContainer" style="display: none;"></div>' +
						'</div>'
					);
					lay.find('.button').bind('click', function (e) {
						$('#xreviewCommentForm').find('.button, #xreviewCommentFormContainer').toggle();
					});
					return lay;
				},
				makeErrorsBaseLayout: function () {
					var lay = $(
						'<div id="commentErrorMessages">' +
							'<ul class="errors">' +
							'</ul>' +
						'</div>'
					);
					return lay;
				},
				makeErrorLayout: function (msg) {
					return $('<li>' + msg + '</li>');
				},
				makeSubmitButtonLayout: function () {
					var lay, self, error, formData, XRev, detailId;
					lay = $(
						'<div class="viewport submitButtonOuter">' +
							'<div class="submitButton"></div>' +
						'</div>'
					);
					self = this;
					lay.find('.submitButton').bind('click', function (e) {
						error = self.checkRequiredFormFields();
						if (!error){
							formData = self.getFormDataAsJson();
							XRev = self.parent.defaults.xreview;
							detailId = XRev.detailId;
							if (detailId){
								XRev.requestReview(detailId, formData.rating, formData);
							}
						}
					});
					return lay;
				},
				getFormDataAsJson: function () {
					var fields = $('#xreviewCommentForm').find(':input').serializeArray(),
							params = {}, i, field;
					for (i = 0; i < fields.length; i += 1){
						field = fields[i];
						params[field.name] = field.value;
					}
					return params;
				},
				checkRequiredFormFields: function () {
					var conf = this.parent.defaults.requiredFormFields,
							fields = $('#xreviewCommentForm').find(':input'),
							target = $('#commentErrorMessages'),
							error, self, f, name, value, emsg;
					target.remove();
					target = [];
					error = false;
					self = this;
					$(fields).each(function (i) {
						f = $(this);
						name = f.attr('name');
						value = f.val();
						if ($.inArray(name, conf) > -1 && value === ''){
							error = true;
							emsg = self.makeErrorLayout($.lang('formError_' + name));
							if (target.length === 0){
								target = self.makeErrorsBaseLayout();
								$('#xreviewCommentForm').prepend(target);
							}
							target.append(emsg);
						}
					});
					return error;
				},
				make: function () {
					var self = this,
							target = this.target,
							sb, page;
					target.append(this.makeLayout());
					sb = this.makeSubmitButtonLayout();
					page = this.parent.defaults.commentFormPath + 'xreviewCommentForm_' + $.lang() + '.html';
					$('#xreviewCommentFormContainer').load(page + ' #xreviewCommentFormShell', function (responseText, textStatus, XMLHttpRequest) {
						self.injectXReviewRatingTool();
						$('#xreviewCommentFormContainer').append(self.makeSubmitButtonLayout());
					});
				}
			}
		);
	// <<
// <<


// >> simulation search form handler
/*	SimulationSearchFormHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				o.type = $('#simulationSearchType');
				o.station = $('#simulationSearchStation');
				o.zip = $('#simulationSearchZip');
				o.zipLen = 5;
				return o;
			},
			init: function(){
				var t = this.type, z = this.zip, self = this;
				this.handleOptions();
				if (t.length){
					t.bind('change', function(e){
						self.handleOptions(e);
					});
				}
				if (z.length){
					z.bind('keyup', function(e){
						self.handleOptions(e);
					});
				}
			},
			getOptionFromJson: function(obj, selected){
				var opt = $('<option value="' + obj.value + '">' + obj.name + '</option>');
				if (selected){
					opt.attr({'selected': 'selected'});
				}
				if (typeof obj.dist !== 'undefined'){
					opt.text(opt.text() + ' (' + obj.dist + ' km)');
				}
				return opt;
			},
			handleOptions: function(e){
				var url,
				params = null,
				t = this.type,
				z = this.zip,
				target = this.station,
				self = this,
				selectedOptVal = null,
				selected,
				fire = false;
				params = {
					station_type: t.val()
				};
				if (e && e.type === 'keyup'){
					if (z.length && z.val().length >= this.zipLen && !isNaN(parseInt(z.val(), 10))){
						params.zip = z.val();
						fire = true;
					}else if(z.length && z.val().length === 0){
						fire = true;
					}
				}else if (e && e.type === 'change'){
					if (z.length && z.val().length >= this.zipLen && !isNaN(parseInt(z.val(), 10))){
						params.zip = z.val();
					}
					fire = true;
				}else{
					if (target.length){
						selectedOptVal = target.val() / 1;
						if (z.length && z.val().length >= this.zipLen && !isNaN(parseInt(z.val(), 10))){
							params.zip = z.val();
						}
						fire = true;
					}
				}
				if (fire){
					url = AjaxURLManager.getUrlWithKey('simulationsearch', params);
					$.getJSON(url, function(data, textStatus){
						if (data && data.type === "simulationSearch"){
							target.empty();
							$(data.items).each(function(i){
								selected = false;
								if (selectedOptVal === this.value){
									selected = true;
								}
								target.append(self.getOptionFromJson(this, selected));
							});
						}
					});
				}
			}
		}
	);
	
	$(function(){
		var SimSearchForm = SimulationSearchFormHandler.create();
		SimSearchForm.init();
	});*/
// <<


// >> rectangle
	function Rectangle(bounds, opt_weight, opt_color) {
		this.bounds_ = bounds;
		this.weight_ = opt_weight || 2;
		this.color_ = opt_color || "#888888";
	}
	Rectangle.prototype = new GOverlay();
	
	// Creates the DIV representing this rectangle.
	Rectangle.prototype.initialize = function(map) {
		// Create the DIV representing our rectangle
		var div = document.createElement("div");
		div.style.border = this.weight_ + "px solid " + this.color_;
		div.style.position = "absolute";
	
		// Our rectangle is flat against the map, so we add our selves to the
		// MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
		// below the marker shadows)
		map.getPane(G_MAP_MAP_PANE).appendChild(div);
	
		this.map_ = map;
		this.div_ = div;
	}
	
	// Remove the main DIV from the map pane
	Rectangle.prototype.remove = function() {
		this.div_.parentNode.removeChild(this.div_);
	}
	
	// Copy our data to a new Rectangle
	Rectangle.prototype.copy = function() {
		return new Rectangle(this.bounds_, this.weight_, this.color_,
												 this.backgroundColor_, this.opacity_);
	}
	
	// Redraw the rectangle based on the current projection and zoom level
	Rectangle.prototype.redraw = function(force) {
		// We only need to redraw if the coordinate system has changed
		if (!force) return;
	
		// Calculate the DIV coordinates of two opposite corners of our bounds to
		// get the size and position of our rectangle
		var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
		var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());
	
		// Now position our DIV based on the DIV coordinates of our bounds
		this.div_.style.width = Math.abs(c2.x - c1.x) + "px";
		this.div_.style.height = Math.abs(c2.y - c1.y) + "px";
		this.div_.style.left = (Math.min(c2.x, c1.x) - this.weight_) + "px";
		this.div_.style.top = (Math.min(c2.y, c1.y) - this.weight_) + "px";
	}
// <<


// >> Chart handler
	ChartHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(sim_id){
				var o = LLObject.create.call(this);
				o.sim_id = sim_id;
				o.data = null;
				o.div = $('#chartDiv');
				o.queueinfo = $('#queueInfo');
				return o;
			},
			init: function(){
				var self = this;
				this.timer();
			},
			timer: function(){
				var self = this, url, params;
				params = {};
				params.sim_id = this.sim_id;
				params.t = new Date().getTime();
				url = AjaxURLManager.getUrlWithKey('simulationresults', params);
				$.getJSON(url, function(result, textStatus){
					if (result.data !== null && result.data !== undefined && result.data.length > 0) {
						if (self.interval){
							clearInterval(self.interval);
							self.interval = null;
						}
						self.setData(result.data);
						$('#serviceShell, #renderSupport').hide();
					} else {
						$('#serviceShell').show();
						self.queueinfo.empty().html(result.statustext);
						if (typeof XIST4C_GLOBALS.login !== 'undefined' && XIST4C_GLOBALS.login.userID !== 'null'){
							var userId = XIST4C_GLOBALS.login.userID, params
							mailButton = $('#renderSupport');
							mailButton.unbind();
							mailButton.bind('click', function(e){
								params = {};
								params.sim_id = self.sim_id
								params.kd_id = userId;
								var url = AjaxURLManager.getUrlWithKey('notify');
								$.ajax({
									type: 'post',
									url: url,
									data: params,
									success: function(data, msg){
										if (data === 'OK'){
											alert($.lang('emailSupportNotification'));
										}
									},
									error: function(req, status, error){}
								});
							});
							mailButton.show();
						}
						if (!self.interval){
							self.interval = setInterval(function(){
								self.timer();
							}, 3000);
						}
					}
				});
			},
			setData: function(data, order){
				this.div.html(data);
			}
		}
	);
//<<


// >> Grid map handler
	GridMapHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(sim_id, west, south, east, north){
				var o = LLObject.create.call(this);
				o.sim_id = sim_id;
				o.data = null;
				o.west = west;
				o.south = south;
				o.east = east;
				o.north = north;
				o.div = $('#gridMapDiv');
				o.comboBoxTarget = $('#gridMapComboBoxOuter');
				o.comboBox = null;
				o.minmax = $('#gridMapMinMax');
				o.queueinfo = $('#queueInfo');
				o.currentVal = null;
				return o;
			},
			init: function(){
				var self = this, zoomLevel;
				this.comboBoxTarget.empty().append(this.makeHistThumbShell());
				this.comboBoxTarget.append(this.makeComboBox());
				this.comboBox = $('#gridMapComboBox');
				this.comboBox.bind('change click keyup', function(e){
					self.handleOptions(e);
				});
				this.map = new GMap2(document.getElementById('gridMapDiv'));
				this.map.setCenter(new GLatLng((this.south + this.north) / 2, (this.east + this.west) / 2));
				this.latLngBounds = new GLatLngBounds(new GLatLng(this.south, this.west), new GLatLng(this.north, this.east))
				zoomLevel = this.map.getBoundsZoomLevel(this.latLngBounds);
				this.map.addOverlay(new Rectangle(this.latLngBounds));
				this.map.setZoom(zoomLevel);
				this.map.setUIToDefault();
				this.timer();
			},
			timer: function(){
				var self = this, url, params;
				params = {};
				params.sim_id = this.sim_id;
				params.t = new Date().getTime();
				url = AjaxURLManager.getUrlWithKey('simulationresults', params);
				$.getJSON(url, function(result, textStatus){
					if (result.data !== null && result.data !== undefined && result.data.size > 0) {
						if (self.interval){
							clearInterval(self.interval);
							self.interval = null;
						}
						self.setData(result.data, result.order);
						$('#serviceShell, #renderSupport').hide();
					} else {
						$('#serviceShell').show();
						self.queueinfo.empty().html(result.statustext);
						if (typeof XIST4C_GLOBALS.login !== 'undefined' && XIST4C_GLOBALS.login.userID !== 'null'){
							var userId = XIST4C_GLOBALS.login.userID, params
							mailButton = $('#renderSupport');
							mailButton.unbind();
							mailButton.bind('click', function(e){
								params = {};
								params.sim_id = self.sim_id
								params.kd_id = userId;
								var url = AjaxURLManager.getUrlWithKey('notify');
								$.ajax({
									type: 'post',
									url: url,
									data: params,
									success: function(data, msg){
										if (data === 'OK'){
											alert($.lang('emailSupportNotification'));
										}
									},
									error: function(req, status, error){}
								});
							});
							mailButton.show();
						}
						if (!self.interval){
							self.interval = setInterval(function(){
								self.timer();
							}, 3000);
						}
					}
				});
			},
			setData: function(data, order){
				this.data = data;
				this.setOptions(order);
				this.handleOptions();
			},
			setOptions: function(order){
				var first = true, i, grid, option;
				this.comboBox.empty();
				for (i = 0; i < order.length; i+=1){
					if (i !== "size"){
						grid = this.data[order[i]];
						option = '<option value="' + order[i] + '"';
						if (first) {
							option = option + ' selected="selected"';
						}
						option = option + '>' + grid.name + '</option>';
						this.comboBox.append($(option));
						first = false;
					}
				}
			},
			makeScaleLayout: function(){
				var lay = $(
					'<div id="gMapScale">' +
						'<div class="viewport">' +
						'</div>' +
					'</div>'
				);
				return lay;
			},
			makeUnitLayout: function(unit){
				var lay = $(
					'<div class="scaleUnit">' + unit + '</div>'
				);
				return lay;
			},
			makeScaleItem: function(value){
				var lay = $(
					'<div class="scaleItem">' +
						'<div class="pipe">|</div>' +
						'<div class="value">' + value + '</div>' +
					'</div>'
				);
				return lay;
			},
			makeComboBox: function(){
				return $('<span class="prompt">' + $.lang('display') + '</span><select id="gridMapComboBox" name=""></select>');
			},
			makeHistThumbShell: function(){
				var lay = $(
					'<div class="viewport" id="historyThumbnail"></div>'
				);
				return lay;
			},
			makeHistThumbClone: function(){
				var lay = $(
					'<a class="imageLink"></a>'
				);
				return lay.clone();
			},
			updateHistImages: function(){
				var d = this.data, currVal = this.comboBox.val(), target = $('#historyThumbnail'), item, attrs = {},
				i, linkElm, histImg, histImgs, TAttrs = {}, img;
				item = d[currVal];
				LL_XPopup.xpopups = [];
				TAttrs.group = 'histImgs';
				TAttrs.background = 'true';
				TAttrs.fixedPosition = 'true';
				if (typeof item === 'object'){
					if (item.histimgs !== null && item.histimgs !== undefined && typeof item.histimgs.length === 'number'){
						for (i = 0; i < item.histimgs.length; i+=1){
							histImg = item.histimgs[i];
							linkElm = this.makeHistThumbClone();
							linkElm.attr({
								href: XIST4C_GLOBALS.landcareUploadPath + histImg.img.src,
								rel: 'lightbox[histImgs]'
							});
							linkElm.css({
								display: 'block',
								width: histImg.imgthumb.width,
								height: histImg.imgthumb.height
							});
							if (i > 0){
								linkElm.css({
									display: 'none'
								});
							}
							img = Utils.pixel();
							img.attr({
									src: XIST4C_GLOBALS.landcareUploadPath + histImg.imgthumb.src,
									height: histImg.imgthumb.height,
									width: histImg.imgthumb.width
							});
							linkElm.append(img);
							target.append(linkElm);
							TAttrs.url = linkElm.attr('href');
							LL_XPopup.registerPopup(linkElm, 'click', 'IMAGE', 'p_c', 'c', 0, 0, TAttrs);
						}
						target.show();
					} else {
						target.hide();
					}
				}
			},
			handleOptions: function(e){
				var grid;
				if (this.comboBox.val() !== this.currentVal) {
					this.currentVal = this.comboBox.val();
					if (this.overlay !== null && this.overlay !== undefined) {
						this.map.removeOverlay(this.overlay);
					}
					this.updateHistImages();
					grid = this.data[this.comboBox.val()];
					if (grid !== null && typeof grid === 'object') {
						this.overlay = new ProjectedOverlay(XIST4C_GLOBALS.landcareUploadPath + grid.img.src, this.latLngBounds);
						this.map.addOverlay(this.overlay);
						this.displayScale();
					}
				}
			},
			round: function(val, digits){
				val = val * Math.pow(10, digits);
				val = Math.round(val) + '';
				val = val.replace(/\..*$/, '');
				val = val.substring(0, val.length - digits) + ',' + val.substring(val.length - digits);
				if (val.substring(0, 1) === ','){
					val = '0' + val;
				}
				return val;
			},
			getScaleObjects: function(min, max, count){
				var scaleWidth = 430, scaleVal, nextPos = 0, nextVal = 0, i, items = [], item = {}, lay;
				scaleVal = (max - min) / (count - 1);
				for (i = 0; i < count; i+=1){
					item.pos = nextPos -= 1; // reduce pipe char width.
					lay = this.makeScaleItem(this.round(min + scaleVal * i, 2));
					item.lay = lay;
					nextPos += Math.ceil(scaleWidth / (count - 1));
					if (nextPos > scaleWidth){
						nextPos = scaleWidth;
					}
					items.push(item);
					item = {};
				}
				return items;
			},
			displayScale: function(){
				var min, max, grid, items, i, item;
				grid = this.data[this.comboBox.val()];
				min = grid.min;
				max = grid.max;
				this.minmax.empty().append(this.makeScaleLayout());
				$('#gMapScale .viewport').append(this.makeUnitLayout(grid.unit));
				items = this.getScaleObjects(min, max, 8);
				for (i = 0; i < items.length; i+=1){
					item = items[i];
					item.lay.css({'left': item.pos});
					$('#gMapScale .viewport').append(item.lay);
				}
			}
		}
	);
//<<


// >> Form Info Handler
	FormInfoHandler = $.extend(
		$.clone(LLObject),
		{
			create: function(){
				var o = LLObject.create.call(this);
				return o;
			},
			makeInfoPanelLayout: function(){
				return $(
					'<div id="searchInfoPanel"></div>'
				).hide();
			},
			bindFormInfoElements: function(){
				var vp = $('<div class="viewport"></div>'), info = $('form.massDataElsShell').find('.searchFormInfo'),
				infoText;
				info.prepend(vp);
				info.find('.infoMsg').each(function(i){
					if ($(this).text() !== ''){
						$(this).parent().show();
					}
				});
				$('#searchInfoPanel').bind('mouseleave', function(e){
					$(this).hide('fast');
				});
				info.bind('click', function(e){
					$('#searchInfoPanel').empty().html($(this).find('.infoMsg').html()).show('fast');
					$(this).find('.viewport').append($('#searchInfoPanel'));
				});
			},
			make: function(){
				var b = $('body');
				if (b.find('#searchInfoPanel').length < 1){
					b.append(this.makeInfoPanelLayout());
				}
				this.bindFormInfoElements();
			}
		}
	);
// <<


// >> Station select service
	StationSelectService = {
		data: {},
		makeCssPopupLayout: function(){
			var lay = $(
				'<div id="stationSelectPopup">' +
					'<div class="viewport">' +
						'<div class="closeButton"></div>' +
					'</div>' +
					'<div class="inner" id="stationSelectPopupInner"></div>' +
				'</div>'
			);
			return lay;
		},
		climateData: function(data){
			if (data && typeof data === 'object'){
				$.extend(this.data, data);
				return data;
			}
			return this.data;
		},
		addStation: function(stationId, stationName){
			$('#stationId').val(stationId);
			setStationName(stationId);
			$('#stationSelectPopup').hide('fast');
			setSimulationAvailable();
		},
		bindChooseStationButton: function(){
			var self = this;
			$('#stationMap').bind('click', function(e){
				e.preventDefault();
				e.stopPropagation();
				$.extend(self.data, {'stationId': $('#stationId').val()});
				self.openPopupAndLoadGMap();
			});
		},
		openPopupAndLoadGMap: function(){
			var d = this.data, self = this, pup = $('#stationSelectPopup'), left, top, pos;
			$('body').css({'overflow': 'hidden'});
			pup.height($(window).height() - 200);
			pup.find('.inner').height($(window).height() - 200);
			pup.width($(window).width() - 200);
			left = ($(window).width() - pup.width()) / 2;
			top = ($(window).height() - pup.height()) / 2;
			top += $(window).scrollTop();
			pup.css({'position': 'absolute', 'left': left, 'top': top});
			pup.show();
			initializeStationMap(d.clima, d.type, d.stationId);
		},
		make: function(){
			var pup = this.makeCssPopupLayout().hide();
			$('body').append(pup);
			$('#stationSelectPopup').bind('click', function(e){
				e.preventDefault();
				e.stopPropagation();
			});
			$('#stationSelectPopup .closeButton').bind('click', function(e){
					$('#stationSelectPopup').hide();
					$('body').css({'overflow': 'auto'});
			});
			this.bindChooseStationButton();
			$.extend(this.data, {'type': $('#stationType').val()});
			$.extend(this.data, {'stationId': $('#stationId').val()});
		}
	}
// <<


// >> Area select service
	AreaSelectService = {
		data: {},
		makeCssPopupLayout: function(){
			var lay = $(
				'<div id="gebietSelectPopup">' +
					'<div class="viewport">' +
						'<div class="closeButton"></div>' +
					'</div>' +
					'<div class="inner" id="gebietSelectPopupInner"></div>' +
				'</div>'
			);
			return lay;
		},
		climateData: function(data){
			if (data && typeof data === 'object'){
				$.extend(this.data, data);
				return data;
			}
			return this.data;
		},
		setArea: function(gebietId){
			$('#gebietId').val(gebietId);
			setGebietName(gebietId);
			$('#gebietSelectPopup').hide('fast');
			setSimulationAvailable();
		},
		bindChooseAreaButton: function(){
			var self = this;
			$('#gebietMap').bind('click', function(e){
				e.preventDefault();
				e.stopPropagation();
				$.extend(self.data, {'geb_id': $('#gebietId').val()});
				self.openPopupAndLoadGMap();
			});
		},
		openPopupAndLoadGMap: function(){
			var d = this.data, self = this, pup = $('#gebietSelectPopup'), left, top, pos;
			$('body').css({'overflow': 'hidden'});
			pup.height($(window).height() - 200);
			pup.find('.inner').height($(window).height() - 200);
			pup.width($(window).width() - 200);
			left = ($(window).width() - pup.width()) / 2;
			top = ($(window).height() - pup.height()) / 2;
			top += $(window).scrollTop();
			pup.css({'left': left, 'top': top});
			pup.show();
			if (d.kd_id === 'null'){
				d.kd_id = null;
			}
			initializeAreaMap(
				function(geb_id){self.setArea(geb_id);},
				d.geb_id,
				d.kd_id
			);
		},
		make: function(){
			var pup = this.makeCssPopupLayout().hide();
			$('body').append(pup);
			$('#gebietSelectPopup').bind('click', function(e){
				e.preventDefault();
				e.stopPropagation();
			});
			$('#gebietSelectPopup .closeButton').bind('click', function(e){
				$('#gebietSelectPopup').hide();
				$('body').css({'overflow': 'auto'});
			})
			this.bindChooseAreaButton();
			var uid = XIST4C_GLOBALS.login.userID;
			if (uid === null){
				uid = '';
			}
			$.extend(this.data, {'kd_id': uid});
			$.extend(this.data, {'geb_id': $('#gebietId').val()});
		}
	}
	$(function(){
		StationSelectService.make();
		AreaSelectService.make();
	});
// <<

$(function(){
	$('body').bind('click', function(e){
		$('#stationSelectPopup, #gebietSelectPopup').hide();
		$(this).css({'overflow': 'auto'});
	});
});

