var mainPanel;
var viewport;
var map;
var layerlist = new Layerlist();
var lang = defaultLanguage;
var layerBase;
var lastNode = null;
var logos = new Logos();

Ext.onReady(function() {

	Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
	Ext.QuickTips.init();

	Ext.form.Field.prototype.msgTarget = 'qtip';

	var cookieExpires = new Date();
	cookieExpires = new Date(cookieExpires.getTime() + 1000 * 60 * 60 * 24 * 365);

	Array.prototype.contains = function(elem) {
		var i;
		for (i = 0; i < this.length; i++) {
			if (this[i] == elem) {
				return true;
			}
		}
		return false;
	};

	function stripslashes(str) {
		return (str + '').replace(/\\(.?)/g, function(s, n1) {
					switch (n1) {
						case '\\' :
							return '\\';
						case '0' :
							return '\u0000';
						case '' :
							return '';
						default :
							return n1;
					}
				});
	}

	Array.prototype.remove = function(arrayElement) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == arrayElement)
				this.splice(i, 1);
		}
	}

	if (!Array.prototype.forEach) {
		Array.prototype.forEach = function(fun /* , thisp */) {
			var len = this.length >>> 0;
			if (typeof fun != 'function')
				throw new TypeError();

			var thisp = arguments[1];
			for (var i = 0; i < len; i++) {
				if (i in this)
					fun.call(thisp, this[i], i, this);
			}
		};
	}

	OpenLayers.Control.WMSGetFeatureInfo.prototype.findLayers = function() {

		var candidates = this.layers || this.map.layers;
		var layers = [];
		var layer, url;
		for (var i = 0, len = candidates.length; i < len; ++i) {
			layer = candidates[i];
			if (layer instanceof OpenLayers.Layer.WMS && (!this.queryVisible || layer.getVisibility())) {
				url = layer.url instanceof Array ? layer.url[0] : layer.url;
				layers.push(layer)
			}
		}
		return layers;
	};

	/*
	 * Modifies the default OpenLayers WMS layer implementation by setting wrapDateLine = true, transitionEffect =
	 * 'resize', format='image/png' and preventing the loading of tiles outside the latitude range [-90,90] (reducing load
	 * on the target WMS server).
	 */

	OpenLayers.Layer.WMS_x = OpenLayers.Class(OpenLayers.Layer.WMS, {
				getURL : function(bounds) {
					bounds = this.adjustBounds(bounds);
					extent = new OpenLayers.Bounds.fromArray(this.metadata.llbbox);
					extent.transform(new OpenLayers.Projection('EPSG:4326'), map.projection);
					if (!bounds.intersectsBounds(extent)) {
						return Ext.BLANK_IMAGE_URL;
					}
					var imageSize = this.getImageSize();
					var newParams = {};
					// WMS 1.3 introduced axis order
					var reverseAxisOrder = this.reverseAxisOrder();
					newParams.BBOX = this.encodeBBOX ? bounds.toBBOX(null, reverseAxisOrder) : bounds.toArray(reverseAxisOrder);
					newParams.WIDTH = imageSize.w;
					newParams.HEIGHT = imageSize.h;
					var requestString = this.getFullRequestString(newParams);
					return requestString;
				},
				CLASS_NAME : "OpenLayers.Layer.WMS_x"
			});

	layerBase = new OpenLayers.Layer.VirtualEarth("Areal", {
				type : VEMapStyle.Hybrid,
				minZoomLevel : 3,
				maxZoomLevel : 16,
				isBaseLayer : true,
				animationEnabled : false,
				sphericalMercator : true,
				maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
			});

	var layerOverviewBackground = new OpenLayers.Layer.WMS("OpenLayers WMS",
			"http://infoterra.de/geoserver/floodserver/gwc/service/wms", {
				layers : 'overview:europe',
				format : 'image/png'
			}, {
				buffer : 0
			});

	var styleOverviewRegions = new OpenLayers.Style();

	var rule1 = new OpenLayers.Rule({
				filter : new OpenLayers.Filter.Comparison({
							type : OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
							property : "region_sta",
							value : 5
						}),
				symbolizer : {
					strokeWidth : 1,
					strokeOpacity : 0.8,
					strokeColor : '${strokeColo}',
					fillColor : '${fillColor}',
					fillOpacity : 0.2
				}
			});

	styleOverviewRegions.addRules([rule1]);

	var myStyles = new OpenLayers.StyleMap({
				"default" : styleOverviewRegions,
				"select" : new OpenLayers.Style({
							fillOpacity : 0.3,
							strokeWidth : 2

						}),
				"temporary" : new OpenLayers.Style({
							fillOpacity : 0.5,
							strokeWidth : 2
						})
			});

	var layerOverviewRegions = new OpenLayers.Layer.Vector("Regions", {
				strategies : [new OpenLayers.Strategy.BBOX()],
				protocol : new OpenLayers.Protocol.WFS({
							url : '/floodserver/wfs',
							featureType : 'Regions',
							featurePrefix : 'overview',
							featureNS : 'http://www.floodrisk.eu/overview',
							geometryName : 'the_geom',
							version : '1.1.0',
							srsName : 'EPSG:4326'
						}),
				styleMap : myStyles
			});

	var getFeatureInfoControl = new OpenLayers.Control.WMSGetFeatureInfo({
				queryVisible : true,
				url : 'http://infoterra.de/geoserver/floodserver/wms'

			});

	map = new OpenLayers.Map({
				units : "m",
				numZoomLevels : 13,
				projection : new OpenLayers.Projection("EPSG:900913"),
				displayProjection : new OpenLayers.Projection("EPSG:4326"),
				maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
				controls : [new OpenLayers.Control.PanZoomBar(),
						new OpenLayers.Control.MousePosition({
									formatOutput : displayMousePosition,
									element : 'ext-gen29'
								}), // getFeatureInfoControl
						new OpenLayers.Control.ZoomBox(), new OpenLayers.Control.Navigation(),
						new OpenLayers.Control.LoadingPanel()]
			});

	// getFeatureInfoControl.activate();
	// getFeatureInfoControl.events.register('getfeatureinfo', this, showInfo);

	function showInfo(event) {

		var html = "";
		var features = Ext.util.JSON.decode(event.text);
		features.data.forEach(function(feature) {
					if (!feature.n) {
						if (!feature.data.n) {
							html += feature.data[0].name
									+ ': <img src="/floodserver/wms?SERVICE=WMS&FORMATS=image%2Fpng&TRANSPARENT=TRUE&VERSION=1.1.1'
									+ '&REQUEST=GetLegendGraphic&EXCEPTIONS=application%2Fvnd.ogc.se_xml&FORMAT=image%2Fpng&LAYER=flood_'
									+ lang + '%3A' + feature.data[0].name
									+ '&LEGEND_OPTIONS=forceLabels:on&SCALE=13867008.522629378&RULE=' + feature.data[0].fcode + '">'
						}
					}
				});

		$('statusBarInfo').innerHTML = html;
	}

	var staticOverviewMap = new OpenLayers.StaticOverviewMap({
				units : "m",
				syncMap : map,
				resolutions : [0.16],
				layers : [layerOverviewBackground, layerOverviewRegions],
				projection : new OpenLayers.Projection("EPSG:4326"),
				controls : []
			});
	var dragControl = new OpenLayers.Control.DragFeature(staticOverviewMap.boxes);
	staticOverviewMap.addControl(dragControl);
	dragControl.activate();

	var overviewPopupPanel = new Ext.Panel({
		id : "overviewPopupPanel",
		height : 50,
		width : 300,
		html : "",
		hidden : true,
		style : 'position:relative;top:-245px;left:-5px;background:transparent url("images/overviewbg.png");background-repeat:no-repeat;padding:8px 13px;font:bold 11px/15px tahoma,arial,verdana,sans-serif;'
	});

	var highlightCtrl = new OpenLayers.Control.SelectFeature(layerOverviewRegions, {
				hover : true,
				highlightOnly : true,
				renderIntent : "temporary",
				eventListeners : {
					featurehighlighted : function(event) {
						feature = event.feature;
						overviewPopupPanel.show();
						Ext.fly("overviewPopupPanel").dom.innerHTML = language.getString(lang, 'popup_'
										+ feature.attributes.region_nam);
					},
					featureunhighlighted : function(event) {
						overviewPopupPanel.hide();

					}

				}
			});

	var selectCtrl = new OpenLayers.Control.SelectFeature(layerOverviewRegions, {
				clickout : true,
				onSelect : function(feature) {
					map
							.zoomToExtent(feature.geometry.clone().getBounds()
									.transform(staticOverviewMap.projection, map.projection));
					this.unselect(feature);
				}
			});

	staticOverviewMap.addControl(highlightCtrl);
	staticOverviewMap.addControl(selectCtrl);

	highlightCtrl.activate();
	selectCtrl.activate();

	treePanelLayer = new Ext.tree.TreePanel({
				root : new Ext.tree.AsyncTreeNode(),
				rootVisible : false,
				loader : new GeoExt.tree.WMSCapabilitiesLoader({
							dataUrl : 'capabilities.php?lang=' + lang,
							layerOptions : {
								isBaseLayer : false
							},
							requestMethod : 'GET',
							layerParams : {
								'TRANSPARENT' : 'TRUE'
							},
							// customize the createNode method to add a checkbox to nodes
							createNode : function(attr) {
								attr.expanded = true;
								attr.layerlist = layerlist;
								if (attr.leaf) {
									attr.id = 'layer_' + attr.layer.metadata.name.substring(9);
									attr.layer.params.LAYERS = attr.layer.params.LAYERS.replace("flood_" + lang, "flood_en");
									if (layerlist.isInLayerlist(attr.layer)) {
										attr.checked = true;
										attr.layer.opacity = layerlist.getOpacity(attr.layer);
										map.addLayer(attr.layer);
									} else {
										attr.checked = false;
										attr.layer.opacity = 0.7;
									}

								} else {
									attr.checked = undefined;
								}

								// attr.checked = attr.leaf ? false : undefined;
								return GeoExt.tree.WMSCapabilitiesLoader.prototype.createNode.apply(this, [attr]);
							},
							listeners : {
								load : function() {
									treePanelLayer.expandAll();
									updateLogos();
								}
							}
						}),
				title : 'Layer',
				autoScroll : true,
				region : 'center',
				frame : false,
				border : false,
				listeners : {
					append : function(tree, parent, node) {
						if (node.leaf) {
							node.appendChild(new Ext.tree.TreeNode({
										iconCls : 'noIcon',
										leaf : false,
										uiProvider : Ext.ux.sliderTreeNodeUI
									}));
						}
					},
					click : function(node) {
						if (node.leaf) {
							toggleCheck(node, true);
							if (lastNode) {
								if (lastNode.firstChild) {
									lastNode.firstChild.getUI().hide();
								}
							}
							if (node.firstChild) {
								node.firstChild.getUI().show();
								node.firstChild.getUI().slider.setValue(parseInt(node.attributes.layer.opacity * 100));
							}
							lastNode = node;
						}
					},
					checkchange : function(node, checked) {
						updateLogos();
						if (checked === true) {
							map.addLayer(node.attributes.layer);
							layerlist.addLayer(node.attributes.layer);
						} else {
							map.removeLayer(node.attributes.layer);
							layerlist.removeLayer(node.attributes.layer);
						}
					}
				}
			});

	// Layout

	var mainPanel = {
		region : 'center',
		id : 'mappanel',
		border : false,
		// title : 'Map',
		xtype : 'gx_mappanel',
		map : map,
		split : true
	};

	var panelOverview = {
		region : 'north',
		height : 270,
		split : true,
		border : false,
		items : [{
					xtype : 'gx_mappanel',
					id : 'overviewPanel',
					title : language.getString(lang, 'overview'),
					map : staticOverviewMap,
					height : 270,
					width : 300
				}, overviewPopupPanel]
	};

	var legendPanel = new GeoExt.LegendPanel({
				title : language.getString(lang, 'legend'),
				height : 340,
				region : 'south',
				frame : false,
				border : false,
				autoScroll : true,
				collapsible : true,
				collapsed : true,
				collapsedTitle : {
					element : {
						tag : 'div',
						html : language.getString(lang, 'legend'),
						style : "margin-left:5px; margin-top:2px; color:#15428B;font:bold 11px/15px tahoma,arial,verdana,sans-serif;"
					}
				},
				defaults : {
					labelCls : 'mylabel',
					style : 'padding:5px',
					imageFormat : 'image/png'
				},
				bodyStyle : 'padding:5px'
			});

	viewport = new Ext.Viewport({
				layout : 'border',
				items : [{
							region : 'north',
							id : 'header',
							border : false,
							style : 'background-image: url("images/background.jpg");',
							height : 95,
							layout : 'border',
							items : [{
										region : 'center',
										border : false,
										style : 'text-align:center;margin-top:20px;margin-left:80px',
										html : '<img src="images/floodserver.png">'
									}, {
										region : 'east',
										width : 300,
										border : false,
										layout : 'column',
										id : 'panelLanguage',
										defaults : {
											border : false,
											style : 'position:relative;top:35px;',
											width : 35
										},
										items : []
									}]
						}, {
							border : false,
							split : true,
							region : 'center',
							layout : 'border',
							items : [mainPanel, {
										region : 'south',
										height : 30,
										border : false,
										layout : 'column',
										items : [{
													border : false,
													items : [{
																id : 'statusBarLon',
																border : false,
																style : 'font: bold 11px/15px tahoma,arial,verdana,sans-serif;width:150px;',
																html : 'Lon: -'
															}, {
																id : 'statusBarLat',
																border : false,
																style : 'font: bold 11px/15px tahoma,arial,verdana,sans-serif;width:150px;',
																html : 'Lat: -'
															}]
												}, {
													id : 'statusBarInfo',
													style : 'font: bold 11px/15px tahoma,arial,verdana,sans-serif;'
												}]
									}]
						}, {
							region : 'west',
							width : 245,
							split : true,
							layout : 'tdgi_border',
							items : [treePanelLayer, legendPanel]
						}, {
							region : 'east',
							width : 300,
							layout : 'border',
							split : true,
							border : false,
							items : [panelOverview, {
										region : 'center',
										split : true,
										layout : 'border',
										border : false,
										items : [{
													id : 'searchPanel',
													region : 'north',
													split : true,
													title : language.getString(lang, 'search'),
													height : 50,
													items : [searchCombo = new GeoExt.ux.GeoNamesSearchCombo({
																map : map,
																zoom : 10,
																emptyText : language.getString(lang, 'search_emptyText'),
																loadingText : language.getString(lang, 'search_loadingText')
															})]
												}, {
													xtype : 'panel',
													split : true,
													region : 'center',
													border : false,
													autoScroll : true,
													items : [{
																xtype : 'panel',
																id : 'logoPanel'
															}]
												}]

									}]
						}]
			});

	languageList.forEach(function(l) {
				Ext.getCmp('panelLanguage').add({
					items : [{
						xtype : 'button',
						lang : l,
						cls : 'x-btn-icon',
						icon : 'images/flags/' + l + '.png',
						handler : function() {
							lang = l;
							while (map.layers.length > 1) {
								map.removeLayer(map.layers[1]);
							};
							treePanelLayer.getLoader().dataUrl = "capabilities.php?lang=" + l;
							treePanelLayer.getLoader().load(treePanelLayer.root);

							legendPanel.setTitle(language.getString(l, "legend"));
							document.getElementById(legendPanel.getId() + "-xcollapsed").childNodes[0].innerText = language
									.getString(l, "legend");
							Ext.getCmp('overviewPanel').setTitle(language.getString(l, 'overview'));
							searchCombo.emptyText = language.getString(l, 'search_emptyText');
							searchCombo.loadingText = language.getString(l, 'search_loadingText');
							searchCombo.setValue('');
							Ext.getCmp('searchPanel').setTitle(language.getString(l, 'search'));
						}
					}]
				})
			});
	Ext.getCmp('panelLanguage').add({
				items : [{
							xtype : 'button',
							cls : 'x-btn-icon',
							icon : 'images/house.png',
							handler : function() {
								window.location = 'index.php?lang=' + lang;
							}
						}]
			});
	Ext.getCmp('panelLanguage').add({
				width : 155,
				style : 'position:relative;top:5px',
				items : [{
							border : false,
							html : '<a href="http://www.infoterra.de" target="_blank"><img src="images/astrium.png"></a>'
						}, {
							border : false,
							html : '<a href="http://www.geomer.de/en/" target="_blank"><img src="images/geomer.png"></a>'
						}]
			});

	Ext.getCmp('panelLanguage').doLayout();

	var mapStore = new GeoExt.data.LayerStore({
				map : map,
				layers : [layerBase]
			});
	var startCenter = new OpenLayers.LonLat(10, 50);
	staticOverviewMap.setCenter(startCenter, 0);
	startCenter.transform(new OpenLayers.Projection('EPSG:4326'), new OpenLayers.Projection('EPSG:900913'));
	map.setCenter(startCenter, 2);
	map.events.register('moveend', staticOverviewMap, staticOverviewMap.syncMaps);
	map.events.register('moveend', map, updateLogos);
	staticOverviewMap.syncMaps();

	function updateLogos() {
		var visibleLayers = Array();
		// logos.reset();
		treePanelLayer.getRootNode().cascade(function(node) {
					if (node.attributes.layer && node.leaf) {
						mapbounds = map.getExtent();
						layerbounds = new OpenLayers.Bounds.fromArray(node.attributes.layer.metadata.llbbox);
						layerbounds.transform(new OpenLayers.Projection('EPSG:4326'), map.projection);
						if (mapbounds.intersectsBounds(layerbounds)) {
							node.getUI().addClass('highlight_node');
							if (node.attributes.checked) {
								visibleLayers.push(node.attributes.layer.metadata.name.substring(9));
							}
						} else {
							node.getUI().removeClass('highlight_node');
						}
					}
				});
		// generate HTML for logos
		Ext.Ajax.request({
					url : 'db.php',
					params : {
						action : 'getLogoHtml',
						lang : lang,
						layers : Ext.util.JSON.encode(visibleLayers)
					},
					success : function(response) {
						Ext.fly("logoPanel").dom.innerHTML = stripslashes(response.responseText);
					}
				});
	}

	function toggleCheck(node, isCheck) {
		if (node) {
			var args = [isCheck];
			node.cascade(function() {
						c = args[0];
						this.ui.toggleCheck(c);
						this.attributes.checked = c;
					}, null, args);
		}
	}

	function displayMousePosition(lonLat) {
		$('statusBarLon').innerHTML = 'Lon: ' + lonLat.lon;
		$('statusBarLat').innerHTML = 'Lat: ' + lonLat.lat;
	}
});

function zoomToLayer(node) {
	treePanelLayer.fireEvent('click', node);
	var llbbox = node.attributes.layer.metadata.llbbox;
	var llbboxol = new OpenLayers.Bounds(llbbox[0], llbbox[1], llbbox[2], llbbox[3]);
	llbboxol.transform(new OpenLayers.Projection('EPSG:4326'), new OpenLayers.Projection('EPSG:900913'));
	map.zoomToExtent(llbboxol);
}

function showInfoWindowOfLayer(layername, winId) {
	Ext.getCmp(winId).close();
	var node = treePanelLayer.getNodeById('layer_' + layername);
	showInfoWindow(node);
}

function showInfoWindow(node) {
	var layer_name = node.attributes.layer.metadata.name.substring(9);
	var dO = new Date();
	winId = 'infoWindow_' + dO.getTime();
	Ext.Ajax.request({
				url : 'db.php',
				params : {
					action : 'getProjectHtml',
					lang : lang,
					winId : winId,
					layer : layer_name
				},
				success : function(response) {
					var windowProject = new Ext.Window({
								id : winId,
								resizable : false,
								width : 550,
								height : 420,
								autoScroll : true,
								title : node.attributes.text,
								items : [{
											border : false,
											bodyStyle : 'padding:5px',
											html : response.responseText
										}],
								tbar : [{
											text : language.getString(lang, 'gotolayer'),
											cls : 'x-btn-text-icon',
											icon : 'images/world_zoom.png',
											handler : function() {
												zoomToLayer(node);
											}
										}]
							});
					windowProject.show();
				}
			});
}
