var map;
var myGroupsList;
var contextLayers = null;

function loadViewer(){
	OpenLayers.Util.onImageLoadErrorColor = "transparent";
	OpenLayers.ImgPath = Descartes._getScriptLocation() + '../img/';
	OpenLayers.DOTS_PER_INCH = 96.0;
	
	// Adaptation de la carte a la taille par defaut
	var sizes = [];
	var defaultSize = 0;
	var dummy = 0;
	descartesMap.sizes.each(
		function(size) {
			if (size.defaultSize) {
				$('map').style.width = size.width;
				$('map').style.height = size.height;
				defaultSize = dummy;
			}
			dummy++;
			sizes.push(new OpenLayers.Size(size.width, size.height));
		}
	);
	// ----------------------------------------------------------------
	// Creation de la carte OpenLayers
	// ----------------------------------------------------------------
	var maxBounds = new Descartes.Utils.extendBounds(descartesMap.maxBounds.xMin,
											descartesMap.maxBounds.yMin,
											descartesMap.maxBounds.xMax,
											descartesMap.maxBounds.yMax
										);
	var initBounds = new OpenLayers.Bounds(descartesMap.initBounds.xMin,
											descartesMap.initBounds.yMin,
											descartesMap.initBounds.xMax,
											descartesMap.initBounds.yMax
										);
	var mapOptions = {
		units: "m",
		projection: "EPSG:" + descartesMap.projection,
		maxExtent: maxBounds,
		restrictedExtent: maxBounds,
		maxResolution: 'auto',
		maxScale:descartesMap.maxScale,
		fractionalZoom: true,
		controls: [],
		theme: Descartes._getScriptLocation() + '../theme/descartes.css'
	};
	map = new OpenLayers.Map( 'map', mapOptions );
	
	map.addLayers([new OpenLayers.Layer.Image("fond", OpenLayers.ImgPath + "menu_pixel.gif", maxBounds, sizes[0])]);

	// Declaration des couches OpenLayers
	var descartesLayers = [];
	var showLegend = false;
	var opacityBroken = false;
	for (var indexLayer=0 ; indexLayer<descartesMap.layers.length ; indexLayer++) {
		var layer = descartesMap.layers[indexLayer];
		var baseLayer = false;
		var isTransparent = !baseLayer;
		if (layer.format == "image/jpg" || layer.format == "image/jpeg") {
			isTransparent = false;
		}
		var isAlpha = (layer.cartelieLayer && layer.format == "image/png");
		var opacity = layer.opacity;
    	if (Descartes.Utils.isIE6() && layer.cartelieLayer && layer.format == "image/png") {
    		opacity = 100;
    		opacityBroken = true;
    	}
		
		descartesLayers.push(new OpenLayers.Layer.WMS(layer.title, layer.server.replace(/&amp;/g,"&"), 
														{
															layers:layer.layer,
															opacity:opacity/100,
															isBaseLayer: baseLayer,
															transparent: isTransparent,
															format:layer.format
														},
														{
															transitionEffect:"resize",
															minScale:layer.minScale,
															maxScale:layer.maxScale,
															units: "m",
															singleTile:true,
															ratio:1.0,
															alpha: isAlpha
														}
													)
						);
		descartesLayers[indexLayer].isBaseLayer = false;
		descartesLayers[indexLayer].events.register("loadstart", descartesLayers[indexLayer], debutChargement);
		descartesLayers[indexLayer].events.register("loadend", descartesLayers[indexLayer], suiviChargement);
		if (layer.legend != null) {
			showLegend = true;
		}
	}
	for (var indexLayer=(descartesMap.layers.length-1) ; indexLayer>=0 ; indexLayer--) {
		map.addLayer(descartesLayers[indexLayer]);
	}
	
	if (opacityBroken == true) {
		alert("Votre version d'Internet Explorer ne supporte pas toutes les possibilités de CARTELIE.\nPassez à la version 7 au minimum.");
	}
	
	// Parametrage de la mini-carte de navigation
	var overviewLayer = new OpenLayers.Layer.WMS.Untiled( "Minicarte", descartesMap.overview.url);
	var overviewBounds = new Descartes.Utils.extendBounds(descartesMap.overview.bounds.xMin,
												descartesMap.overview.bounds.yMin,
												descartesMap.overview.bounds.xMax,
												descartesMap.overview.bounds.yMax
											);
	var options = {
		displayClass:'descartesOverviewMap',
		minRectSize:10,
		mapOptions:{maxExtent: overviewBounds,units: "m",projection: "EPSG:" + descartesMap.projection, theme: Descartes._getScriptLocation() + '../theme/descartes.css'},
		size: new OpenLayers.Size(150,90),
		title: "Déplacer le rectangle ou la croix pour naviguer dans la carte",
		layers: [overviewLayer],
		minRatio: 1,
		maxRatio: 1000000000
    };
	var overview = new OpenLayers.Control.OverviewMap(options);
	map.addControl(overview);
	overview.maximizeDiv.title = "Cliquez pour ouvrir la mini-carte de navigation";
	overview.minimizeDiv.title = "Cliquez pour cacher la mini-carte de navigation";
	overview.maximizeControl();
    
	if (!map.getCenter()) map.zoomToExtent(initBounds);

	map.events.register("moveend", map, changeBounds);

	// initialisations applicatives

	// ----------------------------------------------------------------
	// Creation des controles Descartes
	// ----------------------------------------------------------------
	var panelHeight = $('map').style.height.split("px")[0] - 28;
	var myAccordion = new Rico.Accordion( $('controlesAccordion') , {panelHeight:'auto', expandedBg:'#6CA30A', hoverBg:'#6CA30A', collapsedBg:'#7EA23E'} );
	
	// Parametrage du controle des couches
	myLayerControl = new Descartes.LayerControl($('themes'), null);
	
	// Parametrage de la legende
	myLegendControl = new Descartes.LegendControl($('legende'), null);
	
	// Parametrage et affection des couches OpenLayers dans la collection de couches Descartes
	myGroupsList = new Descartes.GroupsList(myLayerControl, myLegendControl);
	
	descartesMap.groups.each(
		function(groupData) {
			var group = new Descartes.LayersGroup(groupData.title, {visible:groupData.visible, orphan:groupData.orphan, opened:groupData.opened});
			groupData.layers.each(
				function(layerIndex) {
					var layer = descartesMap.layers[layerIndex];
					group.addLayer(descartesLayers[layerIndex], {visible:layer.visible,
																alwaysVisible:layer.alwaysVisible,
																queryable:descartesMap.queriesAllowed && layer.queryable,
																activeToQuery:true,
																sheetable:descartesMap.sheetsAllowed && layer.sheetable,
																legend:layer.legend,
																minScale:layer.minScale,
																maxScale:layer.maxScale,
																opacity:layer.opacity,
																opacityMax:layer.opacityMax,
																metadataURL:layer.metadataURL,
																cartelieLayer:layer.cartelieLayer
																}
									);
				}
			);
			myGroupsList.addGroup(group);
		}
	);

	// Parametrage des informations geographiques
	myInfos = new Descartes.InfosControls(map,
						{position: $('position'), dimensions: $('dimensions'), echelle: $('echelle'), scaleBar: true}
					);
	
	// Parametrage de la localisation administrative
	var gazetterLevels = [];
	if (descartesMap.gazetterLevel <= 0) {
		gazetterLevels.push({value:0, message:"Choisissez une région"});
		descartesMap.gazetterValue = '';
	}
	if (descartesMap.gazetterLevel <= 1) {
		gazetterLevels.push({value:1, message:"Choisissez un département"});
	}
	if (descartesMap.gazetterLevel <= 2) {
		gazetterLevels.push({value:2, message:"Choisissez une commune"});
	}
	if (descartesMap.gazetterExtended) {
		gazetterLevels.push({value:3, message:"Choisissez une section cadastrale", error:"Aucune section cadastrale pour cette commune"});
		gazetterLevels.push({value:4, message:"Choisissez une parcelle", error:"Aucune parcelle pour cette section cadastrale"});
	}
	if (gazetterLevels.length !=0) {
		if (descartesMap.gazetterLocal == true) {
			new Descartes.Gazetter($('gazetter'), map, descartesMap.projection, descartesMap.gazetterValue, {levels:gazetterLevels});
		} else {
			var gazetterService = new Descartes.GazetterService("localize", "niveau", "projection", "parent");
			new Descartes.Gazetter($('gazetter'), map, descartesMap.projection, descartesMap.gazetterValue, {service:gazetterService, levels:gazetterLevels});
		}
	}

	var myRequestManager = new Descartes.RequestManager(map, $('requetes'));
	descartesMap.requests.each(
		function(requestData) {
			var request = new Descartes.Request(descartesLayers[requestData.layer], descartesMap.layers[requestData.layer], requestData.title, requestData.geometryType);
			requestData.members.each(
				function(member) {
					request.addMember(new Descartes.RequestMember(member.title, member.field, member.operator, member.values, member.visible));
				}
			);
			myRequestManager.addRequest(request);
		}
	);

	// Gestionnaire des tailles de la carte
	var mySizeSelector = new Descartes.SizeSelector($('tailles'), map, sizes , defaultSize, {globalContainer:$('globalContainer')});
	
	// Gestionnaire des echelles
	var minScale = OpenLayers.Util.getScaleFromResolution(map.getMaxResolution(), map.baseLayer.units);
	new Descartes.ScaleSelector($('echelles'), map);
	
	// Gestionnaire des vues
	new Descartes.BookmarksManager($('bookmarks'), descartesMap.mapName + "_" + descartesMap.auteur, myGroupsList, map , {sizeSelector:mySizeSelector});

	// Gestionnaire des infos-bulles
	if (descartesMap.queriesAllowed) {
		var hasToolTip = false;
		var toolTipLayers = [];
		for (var indexLayer=0 ; indexLayer<descartesMap.layers.length ; indexLayer++) {
			var layer = descartesMap.layers[indexLayer];
			if (layer.fields != null && layer.fields.length !=0) {
				toolTipLayers.push({"OL_layer":descartesLayers[indexLayer], "fields":layer.fields});
				hasToolTip = true;
			}
		}
		if (hasToolTip) {
			new OpenLayers.Control.ToolTip(map, $('toolTip'), toolTipLayers, myGroupsList);
		}
	}
	
	var tabToOpen = descartesMap.accordionTab;
	// masquage des volets inutiles
	if (gazetterLevels.length ==0 && descartesMap.requests.length==0) {
		$('recherchesPanel').style.display = 'none';
		if (tabToOpen == 2) {
			tabToOpen = 1;
		}
	}
	if (showLegend == false) {
		$('legendePanel').style.display = 'none';
		if (tabToOpen == 0) {
			tabToOpen = 1;
		}
	}
	
	// actualisation de la taille de l'accordeon
	myAccordion.showTabByIndex(tabToOpen);
	
	// ----------------------------------------------------------------
	// Actualisation des controles Descartes
	// ----------------------------------------------------------------
	contextLayers = descartesMap.contextLayers;
	if (contextLayers != null) {
		// prise en compte des paramètres de contexte
		var layers = contextLayers.split(",");
		for (var iLayer=0; iLayer<layers.length ; iLayer++) {
			var numLayer = 0;
			for (var indexGroup=0 ; indexGroup<myGroupsList.layerControl.groups.length ; indexGroup++) {
				for (var indexLayer=0 ; indexLayer<myGroupsList.layerControl.groups[indexGroup].layers.length ; indexLayer ++) {
					if ((numLayer)== iLayer) {
						if (layers[iLayer] == 0) {
							myGroupsList.layerControl.groups[indexGroup].layers[indexLayer].visible = false;
						} else {
							myGroupsList.layerControl.groups[indexGroup].layers[indexLayer].visible = true;
							myGroupsList.layerControl.groups[indexGroup].layers[indexLayer].changeOpacity(parseFloat(layers[iLayer]));
						}
					}
					numLayer++;
				}
			}
		}
	}
	changeBounds();

	// Parametrage de la barre d'outils
	myExtraTools = [];
	if (descartesMap.queriesAllowed) {
		myExtraTools.push(["OpenLayers.GetFeatureInfo", "Cliquez sur la carte pour interroger les couches choisies dans les thèmes"]);
		myExtraTools.push(["OpenLayers.PolygonSelection", "Dessinez un polygone pour interroger les couches choisies dans les thèmes"]);
	}
	if (descartesMap.exportsAllowed) {
		myExtraTools.push(["OpenLayers.ExportPNG", "Enregistrer la carte comme image PNG"]);
		myExtraTools.push(["OpenLayers.ExportPDF", "Télécharger la carte sous format PDF"]);
	}
	myToolBar = new Descartes.ToolBar(map, $('ButtonBar'), {isDefault:true, extraTools:myExtraTools, groupsList:myGroupsList, initBounds:initBounds});
	
	if (descartesMap.exportsAllowed) {
		myToolBar.exportPNGTool.setInfos( {
				title:descartesMap.title,
				copyright:descartesMap.copyright
				});
	
		myToolBar.exportPDFTool.setInfos( {
				title:descartesMap.title,
				auteur:descartesMap.auteur,
				copyright:descartesMap.copyright,
				description:descartesMap.description,
				production:descartesMap.production,
				createur:descartesMap.createur,
				logoFiles:descartesMap.logoFiles,
				logoURLs:descartesMap.logoURLs
				});
	}

}

function changeBounds() {
	myGroupsList.refreshControls();
	myInfos.refresh();
	Descartes.RequestManager.ResultLayer.refresh(map);
	// controles vis-a-vis des echelles mini et maxi
	var currentScale = Math.round(map.getScale());
	var maxScale = map.maxScale;
	var minScale = OpenLayers.Util.getScaleFromResolution(map.getMaxResolution(), map.baseLayer.units);
	if (currentScale<maxScale) {
		alert("L'échelle maximale 1/" + maxScale + " est atteinte");
	}
	if (currentScale>minScale) {
		alert("L'échelle minimale 1/" + minScale + " est atteinte");
	}
}

function zoomTo(xMin,yMin,xMax,yMax) {
	map.zoomToExtent(new OpenLayers.Bounds(xMin,yMin,xMax,yMax));
}

function centerTo(x,y, layerMinScale, layerMaxScale) {
	var maxBounds = map.maxExtent;
	// echelle de la vue avant positionnement 
	var currentScale = map.getScale();

	// valeurs de la vue apres positionnement
	var newCenter = new OpenLayers.LonLat(x, y);
	var newScale = currentScale;

	if (layerMinScale != null && layerMinScale < currentScale) {
		newScale = layerMinScale - 1;
	}
	if (layerMaxScale != null && layerMaxScale > currentScale) {
		newScale = layerMaxScale + 1;
	}
 
	// calcul des bounds suite au changement d'echelle et au recentrage
	var res = OpenLayers.Util.getResolutionFromScale(newScale, map.baseLayer.units);
	var newBounds = new OpenLayers.Bounds(	newCenter.lon - map.getSize().w * res / 2,
										newCenter.lat - map.getSize().h * res / 2,
										newCenter.lon + map.getSize().w * res / 2,
										newCenter.lat + map.getSize().h * res / 2);
	
	// les nouveaux Bounds sont-ils dans l'emprise maximale ?
	if (!map.maxExtent.containsBounds(newBounds)) {
		// il faut les retailler
		var deltaX = Math.min(Math.abs(maxBounds.left - newCenter.lon), Math.abs(maxBounds.right - newCenter.lon));
		var deltaY = Math.min(Math.abs(maxBounds.bottom - newCenter.lat), Math.abs(maxBounds.top - newCenter.lat));
		var mapRatio = map.getSize().w / map.getSize().h;
		var delta = Math.min(deltaX, deltaY * mapRatio )
		newBounds = new OpenLayers.Bounds(	newCenter.lon - delta,
											newCenter.lat - delta/mapRatio,
											newCenter.lon + delta,
											newCenter.lat + delta/mapRatio);
	}

	map.zoomToExtent(newBounds);
}

var couchesChargees = 0;
var couchesDemandees = 0;

function debutChargement() {
	var divMessage = $('waitingMessage');
	divMessage.style.display='block';
	divMessage.innerHTML = "Chargement en cours";
	var mapSize = map.getSize();
	var posX = map.viewPortDiv.offsetLeft + (mapSize.w - divMessage.clientWidth)/2;
	var posY = map.viewPortDiv.offsetTop + (mapSize.h - divMessage.clientHeight)/2;
	divMessage.style.left = posX.toString() + "px";
	divMessage.style.top = posY.toString() + "px";

	couchesDemandees ++;
}

function suiviChargement() {
	couchesChargees ++;
	if (couchesChargees == couchesDemandees) {
		var divMessage = $('waitingMessage');
		divMessage.style.display='none';
		couchesChargees = 0;
		couchesDemandees = 0;
	}
}
