/**
 * Oggetti di tipo Layer. Questi oggetti rappresentano livelli di mappa. Ne esistono di
 * vari tipi (raster/vettoriali semplici/vettoriali tiled/...), ognuno con le proprie 
 * caratteristiche e comportamenti. I comportamenti comuni vengono realizzati dai metodi
 * Layer_...
 */

function Layer_getAttributes(id) {
	var shapes=this.getShape(id);
	if(shapes.length>0) {
		var shape=shapes[0];
		return this.implementation.getAttributes(shape);
	} else
		return null;
}

function Layer_setRenderingManager(manager,feature) {
	if(!feature)
		this.renderingManager=manager;
	else
		this.renderingManagers[feature]=manager;
}

function Layer_getRenderingManager(feature) {
	if(this.renderingManager)
		return this.renderingManager;
	else if(this.renderingManagers)
		return this.renderingManagers[feature];
	else
		return null;
}

function Layer_setBasePath(basePath){
	this.basePath = basePath;
}

function Layer_setMapObjName(MapObjName){
	this.mapObjName = MapObjName;
}

function Layer_setMapName(MapName){
	this.mapName = MapName;
}

function Layer_init()
{
	return '<div id="div'+this.name+'" style="position:absolute;top:0px;left:0px;z-index: '+this.priority+';visibility:hidden"></div>';
}

function Layer_setFunction(func,featureName) {
	if(!featureName)
		featureName='mainLayer';
	this.interactiveFunctions[featureName]=func;
}

function Layer_hasFunction(func,featureName) {
	
	if(this.interactiveFunctions) {
		if(!featureName)
			featureName='mainLayer';
		if(this.interactiveFunctions[featureName]) {
			var funcArr=this.interactiveFunctions[featureName].split('*');
		for(var pos in funcArr) {
				if(funcArr[pos].indexOf('=')!=-1) {
					
					var funcName=funcArr[pos].substring(0,funcArr[pos].indexOf('='));
					
					var funcValue=funcArr[pos].substring(funcArr[pos].indexOf('=')+1);
					
					if(funcName.toLowerCase()==func.toLowerCase())
						return funcValue;
				} else {
			if(funcArr[pos].toLowerCase()==func.toLowerCase())
				return true;
		}
				
			}
	}
	}
	return false;
}

/**
 * Invocato in seguito al click su una forma del layer (se il layer è interattivo).
 */
function Layer_onClick(shape,id,evt) {
	this.onClickHandler(this.name,shape,id,evt);	
}

/**
 * Invocato al passaggio su una forma del layer (se il layer è interattivo).
 */
function Layer_onMouseOver(shape,id,tooltip,evt) {
	this.onMouseOverHandler(this.name,shape,id,tooltip,evt,this.hasFunction('highlight'));	
}

/**
 * Invocato all'uscita da una forma del layer (se il layer è interattivo).
 */
function Layer_onMouseOut(shape,id,evt) {
	this.onMouseOutHandler(this.name,shape,id,evt,this.hasFunction('highlight'));	
}

/**
 * Invocato dal movimento su una forma del layer (se il layer è interattivo).
 */
function Layer_onMouseMove(shape,id,evt) {
	this.onMouseMoveHandler(this.name,shape,id,evt);	
}
/**
 * Verifica se un layer è visibile ad una data scala.
 */
function Layer_visibleInScale(scale,feature) {
	if(feature)
		return scale>=this.minScales[feature] && scale<=this.maxScales[feature];
	else
		return scale>=this.minScale && scale<=this.maxScale;
}

/**
 * Rende visibile un layer.
 */
function Layer_show() {
	if(this.loaded && !this.reallyVisible) {
		document.getElementById('div'+this.name).style.visibility='visible';	
		this.reallyVisible=true;	
	}
	
}

/**
 * Nasconde un layer.
 */
function Layer_hide() {
	if(this.reallyVisible) {
		document.getElementById('div'+this.name).style.visibility='hidden';	
		this.reallyVisible=false;
		/*if(this.thematism && this.thematism.applied)
			this.thematism.applied=false;*/
	}
}

function Layer_endOpening() {
	if(this.renderingManager)
		this.renderingManager.changed=false;
	if(this.renderingManagers) {
		for(var feature in this.renderingManagers)
			this.renderingManagers[feature].changed=false;
	}
}

/**
 * Verifica se il layer necessita di essere aggiornato, in base a nuovi parametri di mappa.
 */
function Layer_hasToBeUpdated(oldRange,currRange,originalRange,realRange) {
	var scale=currRange.getScale(originalRange);
	var renderingChanged=false;
	
	if(this.renderingManager) {
		this.visible=this.renderingManager.getProperty('visibility');
		this.opacity=this.renderingManager.getProperty('opacity');
		renderingChanged=this.renderingManager.hasChanged();
		
	} else if(this.renderingManagers) {
		
		this.visible=false;
		for(var feature in this.renderingManagers) {
			
			if(this.renderingManagers[feature].getProperty('visibility'))
				this.visible=true;
			if(this.renderingManagers[feature].hasChanged())
				renderingChanged=true;
		}
		
	}
	if(this.visible) {
		if(this.visibleInScale(scale) && renderingChanged) {
			
			return true;
			
		}
		
		if((!oldRange.equals(currRange) && this.visibleInScale(scale)) || (this.reallyVisible && !this.visibleInScale(scale))) {
			return true;
		}
	} else {
		if(this.loaded)
			return true;
	}
	return false;
}

/**
 * Aggiorna lo stato di un layer in base allo stato attuale della mappa.
 * Lo stato della mappa viene rappresentato dai parametri currRange, originalRange, realRange.
 * La coppia endObjectHandler e endHandler definiscono un oggetto ed un metodo che verrà richiamato al
 * termine dell'operazione di update. In questo modo il sistema ha modo di sapere quando il
 * layer termina il proprio aggiornamento (che avviene in modo asincrono).
 */
function Layer_update(currRange,originalRange,realRange,endObjectHandler,endHandler,maxRange) {
	
	var scale=currRange.getScale(originalRange);
	this.endObjectHandler=endObjectHandler;
	this.endHandler=endHandler;
	
	this.currRange=currRange;
	this.maxRange=maxRange;

	this.originalRange=originalRange;
	this.realRange=realRange;
	
	if(this.visible && this.visibleInScale(scale)) {

		if(!this.loaded) {
			
			this.load(currRange,originalRange,realRange,maxRange);

		}
		else
		{
			
			this.updateRange(currRange,originalRange,realRange,maxRange);

		}
	} else {

		
		if(this.loaded) {
			this.hide();
			this.unload();
		}
		with (endObjectHandler) eval(endHandler+'(\''+this.name+'\')');
	}
}

function Layer_isItYou(layerName) {
	return layerName==this.name;
}

function Layer_addFeature(featureName,minScale,maxScale,interactiveFunctions) {
	this.features.push(featureName);
	if(minScale) {
		this.minScales[featureName]=minScale;
		if(minScale<this.minScale)
			this.minScale=minScale;
	} 
	if(maxScale) {
		this.maxScales[featureName]=maxScale;
		if(maxScale>this.maxScale)
			this.maxScale=maxScale;
	}
	this.setFunction(interactiveFunctions,featureName);
}

function Layer_removeFeature(featureName) {
	for(var count in this.features) {
		if(this.features[count]==featureName)
			delete this.features[count];
	}
}

/**
 * Oggetto RasterLayer. Rappresenta un layer raster.
 */


function RasterLayer_load(currRange,originalRange,realRange) {
	if(!this.loaded) {		
		document.getElementById('div'+this.name).innerHTML='<img src="" width='+mapWidth+' height='+mapHeight+' id="rasterimg'+this.name+'"/>';
		this.loaded=true;
		this.updateRange(this.currRange,this.originalRange,this.realRange);
	}
}

/**
 * Scarica un layer Raster.
 */
function RasterLayer_unload() {
	if(this.loaded) {
		document.getElementById('div'+this.name).innerHTML='';		
		this.loaded=false;
	}
}


/**
 * Aggiorna il range di visualizzazione del layer ECW.
 */
function RasterLayer_updateRange(currRange,originalRange,realRange) {
	
	if(this.features.length==0)
		engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth,mapHeight,this.name,'raster',map.realRange.minX,map.realRange.maxX,map.realRange.minY,map.realRange.maxY,this.format,this.quality);
	else {
		var visibleFeatures=new Array();
		
		var scale=currRange.getScale(originalRange);
		this.opacity=100;
		for(var pos in this.features) {
			var feature=this.features[pos];
			var renderingManager=this.renderingManagers[feature];
			var featOpacity=renderingManager.getProperty('opacity');
			if(featOpacity<this.opacity)
				this.opacity=featOpacity
			if(renderingManager.getProperty('visibility') && this.visibleInScale(scale,feature))
				visibleFeatures.push(feature);
		}
		if(visibleFeatures.length>0)
			engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth,mapHeight,visibleFeatures.join('*'),'raster',map.realRange.minX,map.realRange.maxX,map.realRange.minY,map.realRange.maxY,this.format,this.quality);
		else {
			this.unload();
			with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
		}
	}
	
	var div=document.getElementById('div'+this.name);
	div.style.filter='alpha(opacity='+this.opacity+')';
}

// OBSOLETO: usare RenderingManager
function RasterLayer_setOpacity(opacity) {
	this.opacity=opacity;
	var div=document.getElementById('div'+this.name);
	div.style.filter='alpha(opacity='+opacity+')';
}

function RasterLayer_responseFromGenerator(retrow) {
	
	/*var serverName=mapInfo.getProperty('serverName');
	var start=retrow.indexOf('//');
	start+=2;
	var stop=retrow.indexOf('/',start);
	var retName=retrow.substring(start,stop);
	retrow=retrow.replace(retName,serverName);
	*/
	
	var img=document.getElementById('rasterimg'+this.name);
	img.onload=new Function('rasterWaitImage(\''+this.name+'\')');
	img.src=retrow;
		
	//setTimeout('rasterWaitImage(\''+this.name+'\')',500);
}

function rasterWaitImage(rasterName) {
	
	var raster=map.getLayer(rasterName);
	var img=document.getElementById('rasterimg'+raster.name);
	if(!img.complete)
		setTimeout('rasterWaitImage(\''+rasterName+'\')',500);
	else
		with (raster.endObjectHandler) eval(raster.endHandler+'(\''+raster.name+'\')');
}

/**
 * Costruttore.
 * name               =	nome del layer
 * priority			  = ordine di visualizzazione rispetto agli altri layer
 * minScale			  = scala minima di visualizzazione (1= quadro, >1= zoom in)
 * maxScale			  = scala massima di visualizzazione (1= quadro, >1= zoom in)
 * onMouseOutHandler  = funzione di gestione dell'uscita da una forma interattiva
 * onMouseOverHandler = funzione di gestione dell'ingresso su una forma interattiva
 * onClickHandler     = funzione di gestione del click su una forma interattiva
 */
function RasterLayer(name,priority,minScale,maxScale,interactiveFunctions,format,quality) {
	this.basePath=null;
	this.mapObjName=null;
	this.mapName=null;
	this.name=name;
	
	this.type='raster';
	this.priority=priority;
	this.minScale=minScale;
	this.maxScale=maxScale;
	this.interactiveFunctions=new Array();
	this.interactiveFunctions['mainLayer']=interactiveFunctions;
	

	this.visible=false;
	this.reallyVisible=false;
	this.loaded=false;
	this.endObjectHandler=null;
	this.endHandler=null;
	this.currRange=null;
	this.originalRange=null;
	this.realRange=null;
	this.opacity=100;
	this.renderingManager=null;
	this.renderingManagers=new Array();
	this.features=new Array();
	this.minScales=new Array();
	this.maxScales=new Array();
	this.format=format;
	this.quality=quality;
}

RasterLayer.prototype.hasToBeUpdated=Layer_hasToBeUpdated;
RasterLayer.prototype.update=Layer_update;
RasterLayer.prototype.visibleInScale=Layer_visibleInScale;
RasterLayer.prototype.show=Layer_show;
RasterLayer.prototype.hide=Layer_hide;
RasterLayer.prototype.onMouseOver=Layer_onMouseOver;
RasterLayer.prototype.onMouseOut=Layer_onMouseOut;
RasterLayer.prototype.onClick=Layer_onClick;
RasterLayer.prototype.init=Layer_init;
RasterLayer.prototype.setBasePath=Layer_setBasePath;
RasterLayer.prototype.setMapObjName=Layer_setMapObjName;
RasterLayer.prototype.setMapName=Layer_setMapName;
RasterLayer.prototype.endOpening=Layer_endOpening;
RasterLayer.prototype.hasFunction=Layer_hasFunction;
RasterLayer.prototype.setFunction=Layer_setFunction;

RasterLayer.prototype.setOpacity=RasterLayer_setOpacity;
RasterLayer.prototype.setRenderingManager=Layer_setRenderingManager;
RasterLayer.prototype.getRenderingManager=Layer_getRenderingManager;
RasterLayer.prototype.load=RasterLayer_load;
RasterLayer.prototype.responseFromGenerator=RasterLayer_responseFromGenerator;
RasterLayer.prototype.unload=RasterLayer_unload;
RasterLayer.prototype.updateRange=RasterLayer_updateRange;
RasterLayer.prototype.isItYou=Layer_isItYou;
RasterLayer.prototype.addFeature=Layer_addFeature;
RasterLayer.prototype.removeFeature=Layer_removeFeature;

function DynamicSVGLayer_select(id) {
	this.deselect();
	this.selections=new Array();
	
	var SVGDocument=document.getElementById('emb'+this.name).getSvgDocument();
	var shape=SVGDocument.getElementById(id);
		
	if(shape) {
					
		var oldColor=shape.getAttribute('stroke');
		this.selections.push(new Array(shape,oldColor));
		shape.setAttribute('stroke','#FF00FF');
			
	}
}

/**
 * TODO: implementare l'evidenziazione delle shape.
 */
function DynamicSVGLayer_deselect() {
	for(var pos in this.selections) {
		var selection=this.selections[pos];
		var shape=selection[0];
		var color=selection[1];
		shape.setAttribute('stroke',color);
	}
	this.selections=null;
}

// OBSOLETO: usare RenderingManager
function DynamicSVGLayer_setOpacity(opacity) {
	this.opacity=opacity;
	var SVGDocument=this.getDocument();
	var top=this.implementation.getTopElement(SVGDocument);
	top.setAttribute('opacity',opacity/100.0);	
}

function DynamicSVGLayer_getDocument(layerName) {
	var svgDoc=document.getElementById('emb'+this.name).getSvgDocument();
	return svgDoc;
}

function DynamicSVGLayer_getWindow(layerName) {
	var win=document.getElementById('emb'+this.name).getWindow();
	return win;
}

function DynamicSVGLayer_getBBox(id) {

	var SVGDocument=document.getElementById('emb'+this.name).getSVGDocument();
	var win=document.getElementById('emb'+this.name).getWindow();
	var shape=SVGDocument.getElementById(id);
	
	if(shape) {
		return this.implementation.getBoundingBox(new Array(shape),SVGDocument,win);
	}
	return null;
	
}

function DynamicSVGLayer_getShape(id) {
	if(this.getDocument())
		return new Array(this.getDocument().getElementById(this.featureName+','+id));
	return null;
}

/**
 * Carica un layer SVG.
 */
function DynamicSVGLayer_load(currRange,originalRange,realRange,maxRange) {
	this.updateRange(currRange,originalRange,realRange,maxRange);
}

/**
 * Gestisce la risposta del motore java che genera il layer. Inserisce il layer nella pagina.
 */
function DynamicSVGLayer_responseFromGenerator(result) {
	if(result=='*ERROR*') {
		alert('Errore nella generazione della mappa');
		this.invalid=true;
		with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	} else if(result!='OK') {
		if(result.indexOf(',')==-1)
			this.fileName=result;
		else {
			var resArr=result.split(',');
			this.fileName=resArr[0];
			
			var minX=parseFloat(resArr[1]);
			var minY=parseFloat(resArr[2]);
			var maxX=parseFloat(resArr[3]);
			var maxY=parseFloat(resArr[4]);
			this.boundingRange=new Range(minX,maxX,minY,maxY);
		}
	}
	
	document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	/*if(this.dynamic)
		document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	else
		document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';	*/
}

/**
 * Scarica un layer SVG.
 */
function DynamicSVGLayer_unload() {

	document.getElementById('div'+this.name).innerHTML='';
	this.loaded=false;
}

/**
 * Aggiorna il layer al cambiamento del rettangolo spaziale della mappa.
 */
function DynamicSVGLayer_updateRange(currRange,originalRange,realRange,maxRange) {
	
	var wmsQuery='';
	for(var name in this.layers) {
		var layerName='';
		var featureName='';
		if(name.indexOf('.')!=-1) {
			var layerArr=name.split('.');
			layerName=layerArr[0];
			featureName=layerArr[1];
		} else
			layerName=name;

		
		var layer=map.getLayer(layerName);
		var scale=map.getScale();
		
		if(layer.visible && layer.visibleInScale(scale)) {
			if(featureName) {
				if(layer.getRenderingManager(featureName).getProperty('visibility') && layer.visibleInScale(scale,featureName) && layer.hasFunction('tooltiplayer',featureName)) {
					//var style=decodeBase64(this.layers[name]);
					var style=this.layers[name].replace(/\\/g,'');
					wmsQuery+=style;
				}
			} else {
				//var style=decodeBase64(this.layers[name]);
				var style=this.layers[name].replace(/\\/g,'');
				wmsQuery+=style;
			}
		}
		
	}
	
	if(wmsQuery!='')
		engine.sendMsg('mapQuery',this,'responseFromGenerator','',wmsQuery,this.name,'',1,map.realRange);
	else {
		document.getElementById('div'+this.name).innerHTML='';
		with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	}

	/*var SVGDocument=this.getDocument();
	var internalRange=this.implementation.getInternalRange(SVGDocument);
	var scaleFactor=internalRange.getDeltaX()/mapWidth;
	
	var scale=currRange.getScale(originalRange);
	this.implementation.preUpdate(SVGDocument,currRange,originalRange,realRange,maxRange);
	
	if(this.implementation.hasShapes(SVGDocument,this.name)) {
		
		if(this.renderingManager)
			this.renderingManager.draw(this,SVGDocument);
					
		this.implementation.postUpdate(SVGDocument,this.name);				
	}
	
	var x=-currRange.minX*scaleFactor;
	var y=-currRange.minY*scaleFactor;
		
	var top=this.implementation.getTopElement(SVGDocument);
	
	top.setAttribute('opacity',this.opacity/100.0);	
	top.setAttribute('transform','scale('+scale+','+scale+') translate('+x+','+y+')');	
	with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');*/
	
}

function DynamicSVGLayer_getLoadedIds()
{
	var result=new Array();
	for(var id in this.idList) {
		var idArr=this.idList[id];
		for(var pos in idArr)
			result.push(idArr[pos]);
	}
	return result;
	//return this.idsPerTiles;
}
/**
 * Invocato al termine del caricamento del layer.
 */
function DynamicSVGLayer_setLoaded(layerName,idList) {
	
	var idArr=idList.split(',');
	
	this.idsPerTiles=idArr;

	this.loaded=true;
	var SVGDocument=this.getDocument();

	/*this.idList=this.implementation.postLoad(SVGDocument,this.name,this.renderingManager.getPointerEvents());
	
	if(this.idList=='*ERROR*') {
		// TODO: togliere da qui
		
		alert('Nessun oggetto da inserire in mappa');
		this.invalid=true;
		
	} else
		this.updateRange(this.currRange,this.originalRange,null,this.maxRange);*/
	var SVGDocument=this.getDocument();
	var top=this.implementation.getTopElement(SVGDocument);
	top.setAttribute('opacity',this.opacity/100.0);	
	with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	
}

/**
 * TODO: rivedere
 */
function DynamicSVGLayer_updateTematism() {
	var SVGDocument=this.getDocument();
	this.implementation.updateTematism(SVGDocument,this.name);
}

function DynamicSVGLayer_clone() {
	var result=new SVGLayer(this.name,this.featureName,this.priority,this.withEvents,this.minScale,this.maxScale,this.onMouseOutHandler,this.onMouseOverHandler,this.onClickHandler,this.onMouseMoveHandler,this.interactiveFunctions,this.rolloverEffect);
	result.resolution=this.resolution;
	result.featureType=this.featureType;
	return result;
}

function DynamicSVGLayer_addLayer(layer,featureName,style) {
	if(featureName)
		this.layers[layer+'.'+featureName]=style;
	else
		this.layers[layer]=style;
}

function DynamicSVGLayer_hasToBeUpdated() {
	if(this.renderingManager) {
		this.visible=this.renderingManager.getProperty('visibility');
		this.opacity=this.renderingManager.getProperty('opacity');	
	}
	return true;
}

/**
 * Costruttore. 
 * name               =	nome del layer
 * featureName		  = nome della feature (da passare al motore java) associata al layer
 * priority			  = ordine di visualizzazione rispetto agli altri layer
 * withEvents		  = indica se il layer è interattivo o meno
 * minScale			  = scala minima di visualizzazione (1= quadro, >1= zoom in)
 * maxScale			  = scala massima di visualizzazione (1= quadro, >1= zoom in)
 * onMouseOutHandler  = funzione di gestione dell'uscita da una forma interattiva
 * onMouseOverHandler = funzione di gestione dell'ingresso su una forma interattiva
 * onClickHandler     = funzione di gestione del click su una forma interattiva
 */
function DynamicSVGLayer(name,featureName,priority,withEvents,minScale,maxScale,onMouseOutHandler,onMouseOverHandler,onClickHandler,onMouseMoveHandler,interactiveFunctions,rolloverEffect) {
	this.basePath=null;
	this.mapObjName=null;
	this.mapName=null;
	
	this.name=name;
	this.featureName=featureName;
	this.type='dynamicsvg';
	this.withEvents=withEvents;
	this.priority=priority;
	this.minScale=minScale;
	this.maxScale=maxScale;
	this.onMouseMoveHandler=onMouseMoveHandler;
	this.onMouseOutHandler=onMouseOutHandler;
	this.onMouseOverHandler=onMouseOverHandler;
	this.onClickHandler=onClickHandler;
	this.interactiveFunctions=new Array();
	this.interactiveFunctions['mainLayer']=interactiveFunctions;
	this.rolloverEffect = rolloverEffect;
	this.visible=false;
	this.reallyVisible=false;
	this.loaded=false;
	this.endObjectHandler=null;
	this.endHandler=null;
	this.currRange=null;
	this.originalRange=null;
	this.realRange=null;
	this.thematism= null;
	this.xSlice = 0;
	this.ySlice = 0;
	this.idsPerTiles=null;
	this.dynamic=false;
	this.fileName=this.name+'.svg';
	this.dynamicCall=null;
	this.dynamicCallArgs=null;
	this.renderingManager=null;
	this.implementation=this;
	this.boundingRange=null;
	this.opacity=100;

	if(DynamicSVGLayer.implementation)
		this.implementation=DynamicSVGLayer.implementation.newInstance(this);
	this.resolution=10;
	this.idList=new Array();
	this.layers=new Array();
}

DynamicSVGLayer.implementation=null;



DynamicSVGLayer.prototype.setOpacity=DynamicSVGLayer_setOpacity;

DynamicSVGLayer.prototype.setRenderingManager=Layer_setRenderingManager;
DynamicSVGLayer.prototype.hasFunction=Layer_hasFunction;
DynamicSVGLayer.prototype.setFunction=Layer_setFunction;
DynamicSVGLayer.prototype.getShape=DynamicSVGLayer_getShape;
DynamicSVGLayer.prototype.getBBox=DynamicSVGLayer_getBBox;
DynamicSVGLayer.prototype.getDocument=DynamicSVGLayer_getDocument;
DynamicSVGLayer.prototype.hasToBeUpdated=DynamicSVGLayer_hasToBeUpdated;
DynamicSVGLayer.prototype.visibleInScale=Layer_visibleInScale;
DynamicSVGLayer.prototype.show=Layer_show;
DynamicSVGLayer.prototype.hide=Layer_hide;
DynamicSVGLayer.prototype.update=Layer_update;
DynamicSVGLayer.prototype.getLoadedIds=DynamicSVGLayer_getLoadedIds;
DynamicSVGLayer.prototype.load=DynamicSVGLayer_load;
DynamicSVGLayer.prototype.unload=DynamicSVGLayer_unload;
DynamicSVGLayer.prototype.updateRange=DynamicSVGLayer_updateRange;
DynamicSVGLayer.prototype.setLoaded=DynamicSVGLayer_setLoaded;
DynamicSVGLayer.prototype.responseFromGenerator=DynamicSVGLayer_responseFromGenerator;
DynamicSVGLayer.prototype.onMouseMove=Layer_onMouseMove;
DynamicSVGLayer.prototype.onMouseOver=Layer_onMouseOver;
DynamicSVGLayer.prototype.onMouseOut=Layer_onMouseOut;
DynamicSVGLayer.prototype.onClick=Layer_onClick;
DynamicSVGLayer.prototype.init=Layer_init;
DynamicSVGLayer.prototype.setBasePath=Layer_setBasePath;
DynamicSVGLayer.prototype.setMapObjName=Layer_setMapObjName;
DynamicSVGLayer.prototype.addLayer=DynamicSVGLayer_addLayer;
DynamicSVGLayer.prototype.setMapName=Layer_setMapName;
DynamicSVGLayer.prototype.endOpening=Layer_endOpening;
DynamicSVGLayer.prototype.getAttributes=Layer_getAttributes;
DynamicSVGLayer.prototype.getRenderingManager=Layer_getRenderingManager;

DynamicSVGLayer.prototype.clone=DynamicSVGLayer_clone;
DynamicSVGLayer.prototype.updateTematism=DynamicSVGLayer_updateTematism;
DynamicSVGLayer.prototype.select=DynamicSVGLayer_select;
DynamicSVGLayer.prototype.deselect=DynamicSVGLayer_deselect;
DynamicSVGLayer.prototype.isItYou=Layer_isItYou;
DynamicSVGLayer.prototype.getWindow=DynamicSVGLayer_getWindow;

function SVGLayer_getTopElement() {
	alert('getTopElement not implemented');
	return null;
}

function SVGLayer_setColor(SVGDocument,color) {
	alert('setColor not implemented');
}

function SVGLayer_setFill(SVGDocument,color) {
	alert('setFill not implemented');
}

function SVGLayer_setStroke(SVGDocument,stroke) {
	alert('setStroke not implemented');
}

function SVGLayer_getColor(SVGDocument) {
	alert('getColor not implemented');
	return null;
}

function SVGLayer_getFill(SVGDocument) {
	alert('getFill not implemented');
	return null;
}

function SVGLayer_getStroke(SVGDocument) {
	alert('getStroke not implemented');
	return null;
}

function SVGLayer_hasShapes(SVGDocument,name) {
	alert('hasShapes not implemented');
	return false;
}

function SVGLayer_preUpdate(SVGDocument) {
	alert('preUpdate not implemented');
}

function SVGLayer_postUpdate(SVGDocument,name) {
	alert('postUpdate not implemented');
}

function SVGLayer_getScaleFactor(SVGDocument) {
	alert('getScaleFactor not implemented');
	return null;
}

function SVGLayer_getBoundingBox(shapes,SVGDocument,win) {
	alert('getBoundingBox not implemented');
	return null;
}

function SVGLayer_getInternalRange(SVGDocument) {
	alert('getInternalRange not implemented');
	return null;
}

/**
 * Oggetto SVGLayer. Rappresenta un livello vettoriale SVG.
 */

/**
 * TODO: implementare l'evidenziazione delle shape.
 */
function SVGLayer_select(id) {
	this.deselect();
	this.selections=new Array();
	
	var SVGDocument=document.getElementById('emb'+this.name).getSvgDocument();
	var shape=SVGDocument.getElementById(id);
		
	if(shape) {
					
		var oldColor=shape.getAttribute('stroke');
		this.selections.push(new Array(shape,oldColor));
		shape.setAttribute('stroke','#FF00FF');
			
	}
}

/**
 * TODO: implementare l'evidenziazione delle shape.
 */
function SVGLayer_deselect() {
	for(var pos in this.selections) {
		var selection=this.selections[pos];
		var shape=selection[0];
		var color=selection[1];
		shape.setAttribute('stroke',color);
	}
	this.selections=null;
}

// OBSOLETO: usare RenderingManager
function SVGLayer_setOpacity(opacity) {
	this.opacity=opacity;
	var SVGDocument=this.getDocument();
	var top=this.implementation.getTopElement(SVGDocument);
	top.setAttribute('opacity',opacity/100.0);	
}

function SVGLayer_getDocument(layerName) {
	var svgDoc=document.getElementById('emb'+this.name).getSvgDocument();
	return svgDoc;
}

function SVGLayer_getWindow(layerName) {
	var win=document.getElementById('emb'+this.name).getWindow();
	return win;
}

function SVGLayer_getBBox(id) {

	var SVGDocument=document.getElementById('emb'+this.name).getSVGDocument();
	var win=document.getElementById('emb'+this.name).getWindow();
	var shape=SVGDocument.getElementById(id);
	
	if(shape) {
		return this.implementation.getBoundingBox(new Array(shape),SVGDocument,win);
	}
	return null;
	
}

function SVGLayer_getShape(id) {
	if(this.getDocument())
		return new Array(this.getDocument().getElementById(this.featureName+','+id));
	return null;
}

/**
 * Carica un layer SVG.
 */
function SVGLayer_load(currRange,originalRange,realRange,maxRange) {
	if(!this.loaded) {
		if(this.dynamic) {
			mapInfo.setProperty('alternativeLayer',this.featureName.toLowerCase()+','+this.name);
			if(this.dynamicCall)				
				eval('engine.sendMsg(\''+this.dynamicCall+'\',this,\'responseFromGenerator\','+this.dynamicCallArgs+')');
			else
				engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth*this.resolution,mapHeight*this.resolution,this.featureName,'svg',this.featureName,guiVersion,this.mapObjName,this.withEvents,1,1);
		} else {
			mapInfo.setProperty('alternativeLayer',null);
			engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth*this.resolution,mapHeight*this.resolution,this.featureName,'svg',this.name,guiVersion,this.mapObjName,this.withEvents,1,1);
		}
	}
}

/**
 * Gestisce la risposta del motore java che genera il layer. Inserisce il layer nella pagina.
 */
function SVGLayer_responseFromGenerator(result) {
	if(result=='*ERROR*') {
		alert('Errore nella generazione della mappa');
		this.invalid=true;
		with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	} else if(result!='OK') {
		if(result.indexOf(',')==-1)
			this.fileName=result;
		else {
			var resArr=result.split(',');
			this.fileName=resArr[0];
			
			var minX=parseFloat(resArr[1]);
			var minY=parseFloat(resArr[2]);
			var maxX=parseFloat(resArr[3]);
			var maxY=parseFloat(resArr[4]);
			this.boundingRange=new Range(minX,maxX,minY,maxY);
		}
	}
	
	document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	/*if(this.dynamic)
		document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	else
		document.getElementById('div'+this.name).innerHTML='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'" NAME="emb'+this.name+'" id="SVGEmbed" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';	*/
}

/**
 * Scarica un layer SVG.
 */
function SVGLayer_unload() {

	document.getElementById('div'+this.name).innerHTML='';
	this.loaded=false;
}

/**
 * Aggiorna il layer al cambiamento del rettangolo spaziale della mappa.
 */
function SVGLayer_updateRange(currRange,originalRange,realRange,maxRange) {
	
	var SVGDocument=this.getDocument();
	var internalRange=this.implementation.getInternalRange(SVGDocument);
	var scaleFactor=internalRange.getDeltaX()/mapWidth;
	
	var scale=currRange.getScale(originalRange);
	this.implementation.preUpdate(SVGDocument,currRange,originalRange,realRange,maxRange);
	
	if(this.implementation.hasShapes(SVGDocument,this.name)) {
		
		if(this.renderingManager)
			this.renderingManager.draw(this,SVGDocument);
					
		this.implementation.postUpdate(SVGDocument,this.name);				
	}
	
	var x=-currRange.minX*scaleFactor;
	var y=-currRange.minY*scaleFactor;
		
	var top=this.implementation.getTopElement(SVGDocument);
	
	top.setAttribute('opacity',this.opacity/100.0);	
	top.setAttribute('transform','scale('+scale+','+scale+') translate('+x+','+y+')');	
	with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	
}

function SVGLayer_getLoadedIds()
{
	var result=new Array();
	for(var id in this.idList) {
		var idArr=this.idList[id];
		for(var pos in idArr)
			result.push(idArr[pos]);
	}
	return result;
	//return this.idsPerTiles;
}
/**
 * Invocato al termine del caricamento del layer.
 */
function SVGLayer_setLoaded(layerName,idList) {
	
	var idArr=idList.split(',');
	
	this.idsPerTiles=idArr;

	this.loaded=true;
	var SVGDocument=this.getDocument();

	this.idList=this.implementation.postLoad(SVGDocument,this.name,this.renderingManager.getPointerEvents());
	
	if(this.idList=='*ERROR*') {
		// TODO: togliere da qui
		
		alert('Nessun oggetto da inserire in mappa');
		this.invalid=true;
		with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
	} else
		this.updateRange(this.currRange,this.originalRange,null,this.maxRange);
	
}

/**
 * TODO: rivedere
 */
function SVGLayer_updateTematism() {
	var SVGDocument=this.getDocument();
	this.implementation.updateTematism(SVGDocument,this.name);
}

function SVGLayer_clone() {
	var result=new SVGLayer(this.name,this.featureName,this.priority,this.withEvents,this.minScale,this.maxScale,this.onMouseOutHandler,this.onMouseOverHandler,this.onClickHandler,this.onMouseMoveHandler,this.interactiveFunctions,this.rolloverEffect);
	result.resolution=this.resolution;
	result.featureType=this.featureType;
	return result;
}

/**
 * Costruttore. 
 * name               =	nome del layer
 * featureName		  = nome della feature (da passare al motore java) associata al layer
 * priority			  = ordine di visualizzazione rispetto agli altri layer
 * withEvents		  = indica se il layer è interattivo o meno
 * minScale			  = scala minima di visualizzazione (1= quadro, >1= zoom in)
 * maxScale			  = scala massima di visualizzazione (1= quadro, >1= zoom in)
 * onMouseOutHandler  = funzione di gestione dell'uscita da una forma interattiva
 * onMouseOverHandler = funzione di gestione dell'ingresso su una forma interattiva
 * onClickHandler     = funzione di gestione del click su una forma interattiva
 */
function SVGLayer(name,featureName,priority,withEvents,minScale,maxScale,onMouseOutHandler,onMouseOverHandler,onClickHandler,onMouseMoveHandler,interactiveFunctions,rolloverEffect) {
	this.basePath=null;
	this.mapObjName=null;
	this.mapName=null;
	
	this.name=name;
	this.featureName=featureName;
	this.type='svg';
	this.withEvents=withEvents;
	this.priority=priority;
	this.minScale=minScale;
	this.maxScale=maxScale;
	this.onMouseMoveHandler=onMouseMoveHandler;
	this.onMouseOutHandler=onMouseOutHandler;
	this.onMouseOverHandler=onMouseOverHandler;
	this.onClickHandler=onClickHandler;
	this.interactiveFunctions=new Array();
	this.interactiveFunctions['mainLayer']=interactiveFunctions;
	this.rolloverEffect = rolloverEffect;
	this.visible=false;
	this.reallyVisible=false;
	this.loaded=false;
	this.endObjectHandler=null;
	this.endHandler=null;
	this.currRange=null;
	this.originalRange=null;
	this.realRange=null;
	this.thematism= null;
	this.xSlice = 0;
	this.ySlice = 0;
	this.idsPerTiles=null;
	this.dynamic=false;
	this.fileName=this.name+'.svg';
	this.dynamicCall=null;
	this.dynamicCallArgs=null;
	this.renderingManager=null;
	this.implementation=this;
	this.boundingRange=null;
	this.opacity=100;

	if(SVGLayer.implementation)
		this.implementation=SVGLayer.implementation.newInstance(this);
	this.resolution=10;
	this.idList=new Array();
}

SVGLayer.implementation=null;

SVGLayer.prototype.getTopElement=SVGLayer_getTopElement;
SVGLayer.prototype.getScaleFactor=SVGLayer_getScaleFactor;
SVGLayer.prototype.preUpdate=SVGLayer_preUpdate;
SVGLayer.prototype.postUpdate=SVGLayer_postUpdate;
SVGLayer.prototype.hasShapes=SVGLayer_hasShapes;
SVGLayer.prototype.setColor=SVGLayer_setColor;
SVGLayer.prototype.setStroke=SVGLayer_setStroke;
SVGLayer.prototype.getColor=SVGLayer_getColor;
SVGLayer.prototype.getStroke=SVGLayer_getStroke;
SVGLayer.prototype.setFill=SVGLayer_setFill;
SVGLayer.prototype.getFill=SVGLayer_getFill;

SVGLayer.prototype.setOpacity=SVGLayer_setOpacity;

SVGLayer.prototype.setRenderingManager=Layer_setRenderingManager;
SVGLayer.prototype.hasFunction=Layer_hasFunction;
SVGLayer.prototype.setFunction=Layer_setFunction;
SVGLayer.prototype.getShape=SVGLayer_getShape;
SVGLayer.prototype.getBBox=SVGLayer_getBBox;
SVGLayer.prototype.getDocument=SVGLayer_getDocument;
SVGLayer.prototype.hasToBeUpdated=Layer_hasToBeUpdated;
SVGLayer.prototype.visibleInScale=Layer_visibleInScale;
SVGLayer.prototype.show=Layer_show;
SVGLayer.prototype.hide=Layer_hide;
SVGLayer.prototype.update=Layer_update;
SVGLayer.prototype.getLoadedIds=SVGLayer_getLoadedIds;
SVGLayer.prototype.load=SVGLayer_load;
SVGLayer.prototype.unload=SVGLayer_unload;
SVGLayer.prototype.updateRange=SVGLayer_updateRange;
SVGLayer.prototype.setLoaded=SVGLayer_setLoaded;
SVGLayer.prototype.responseFromGenerator=SVGLayer_responseFromGenerator;
SVGLayer.prototype.onMouseMove=Layer_onMouseMove;
SVGLayer.prototype.onMouseOver=Layer_onMouseOver;
SVGLayer.prototype.onMouseOut=Layer_onMouseOut;
SVGLayer.prototype.onClick=Layer_onClick;
SVGLayer.prototype.init=Layer_init;
SVGLayer.prototype.setBasePath=Layer_setBasePath;
SVGLayer.prototype.setMapObjName=Layer_setMapObjName;
SVGLayer.prototype.setMapName=Layer_setMapName;
SVGLayer.prototype.endOpening=Layer_endOpening;
SVGLayer.prototype.getAttributes=Layer_getAttributes;
SVGLayer.prototype.getRenderingManager=Layer_getRenderingManager;

SVGLayer.prototype.clone=SVGLayer_clone;
SVGLayer.prototype.updateTematism=SVGLayer_updateTematism;
SVGLayer.prototype.select=SVGLayer_select;
SVGLayer.prototype.deselect=SVGLayer_deselect;
SVGLayer.prototype.isItYou=Layer_isItYou;
SVGLayer.prototype.getWindow=SVGLayer_getWindow;


/**
 * Oggetto TiledSVGLayer. Rappresenta un livello vettoriale SVG, suddiviso in riquadri.
 * Il rettangolo spaziale complessivo viene diviso in n parti orizzontalmente ed m verticalmente,
 * ottenendo in questo modo un puzzle da comporre a piacere in base alla scala di visualizzazione.
 * Ad ogni scala vengono mantenuti in memoria solo i tile effettivamente visualizzati.
 * Ogni tile viene individuato da una coppia di coordinate, x ed y, che vanno da 0 a n-1 (per x) e 
 * da 0 ad m-1 (per y). La direzione di crescita di x è verso destra, di y è verso l'alto.
 * I tile hanno anche un nome simbolico, x-y (x trattino y).
 */

function TiledSVGLayer_getBBox(id) {
	for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				var SVGDocument=document.getElementById('emb'+this.name+xSlice+'-'+ySlice).getSVGDocument();
				var win=document.getElementById('emb'+this.name+xSlice+'-'+ySlice).getWindow();
				var shape=SVGDocument.getElementById(id);
				
				if(shape)
					return this.implementation.getBoundingBox(new Array(shape),SVGDocument,win);
					
			}
		}
	}
	
	return null;
	
}

function TiledSVGLayer_isItYou(layerName) {
	if(layerName.indexOf('-')!=-1) {
		var realLayerName=layerName.substring(0,layerName.indexOf('-'));
		return realLayerName==this.name;
	} else
		return this.name==layerName;
}

function TiledSVGLayer_getTopElement() {
	alert('getTopElement not implemented');
	return null;
}

function TiledSVGLayer_setColor(SVGDocument,color) {
	alert('setColor not implemented');
}

function TiledSVGLayer_setStroke(SVGDocument,stroke) {
	alert('setStroke not implemented');
}

function TiledSVGLayer_getColor(SVGDocument) {
	alert('getColor not implemented');
	return null;
}

function TiledSVGLayer_getStroke(SVGDocument) {
	alert('getStroke not implemented');
	return null;
}

function TiledSVGLayer_setFill(SVGDocument,color) {
	alert('setFill not implemented');
}


function TiledSVGLayer_getFill(SVGDocument) {
	alert('getFill not implemented');
	return null;
}

function TiledSVGLayer_hasShapes(SVGDocument,name) {
	alert('hasShapes not implemented');
	return false;
}

function TiledSVGLayer_preUpdate(SVGDocument) {
	alert('preUpdate not implemented');
}

function TiledSVGLayer_postUpdate(SVGDocument,name) {
	alert('postUpdate not implemented');
}

function TiledSVGLayer_getScaleFactor(SVGDocument) {
	alert('getScaleFactor not implemented');
	return null;
}

function TiledSVGLayer_getBoundingBox(shapes,SVGDocument,win) {
	alert('getBoundingBox not implemented');
	return null;
}

function TiledSVGLayer_getInternalRange(SVGDocument) {
	alert('getInternalRange not implemented');
	return null;
}

// OBSOLETO: usare RenderingManager
function TiledSVGLayer_setOpacity(opacity) {
	this.opacity=opacity;
	for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				var SVGDocument=this.getDocument(this.name+'-'+xSlice+'-'+ySlice);
				var top=this.implementation.getTopElement(SVGDocument);
				top.setAttribute('opacity',opacity/100.0);
			}
		}
	}

}

/**
 * Implementare evidenziazione delle forme.
 */
function TiledSVGLayer_select(id) {
	
	var idPieces=id.split('.');
	var mainId=id;
	if(idPieces.length==2)
		mainId=idPieces[0];
	
	this.deselect();
	this.selections=new Array();
	
	for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				var idArr=this.idsGrouping[mainId];
				for(var pos in idArr) {
					var currentId;
					if(idPieces.length==2)
						currentId=mainId+'.'+idArr[pos];
					else
						currentId=idArr[pos];
					var SVGDocument=document.getElementById('emb'+this.name+xSlice+'-'+ySlice).getSVGDocument();
					var shape=SVGDocument.getElementById(currentId);
				
					if(shape) {
					
						var oldColor=shape.getAttribute('stroke');
						
						var selectedShape=this.implementation.select(shape);
						this.selections.push(new Array(selectedShape,oldColor));
						/*shape.setAttribute('stroke','#FF00FF');
						if(this.renderingManager.hasManageableProperty('fill'))
							shape.setAttribute('fill','#FF00FF');*/
					}
				}
			}
		}
	}
}

/**
 * Implementare evidenziazione delle forme.
 */
function TiledSVGLayer_deselect() {
	for(var pos in this.selections) {
		var selection=this.selections[pos];
		var shape=selection[0];
		var color=selection[1];
		
		this.implementation.deselect(shape,this.renderingManager.getProperty('color'));
		/*shape.setAttribute('stroke','none');
		if(this.renderingManager.hasManageableProperty('fill'))
			shape.setAttribute('fill','none');*/
		
	}
	this.selections=null;
}

function TiledSVGLayer_visibleTileInRange(x,y,range,originalRange,maxRange) {
	
	var tileSizeX=maxRange.getDeltaX()/this.ntilesX;
	var tileSizeY=maxRange.getDeltaY()/this.ntilesY;
	var tileRange=new Range(x*tileSizeX,x*tileSizeX+tileSizeX,y*tileSizeY,y*tileSizeY+tileSizeY);
	return tileRange.intersects(range);
}

/**
 * Verifica se un tile è caricato.
 */
function TiledSVGLayer_loadedTile(tile) {
	return this.loadedTiles[tile]==1;
}

/**
 * Carica in memoria un tile.
 */
function TiledSVGLayer_loadTile(tileName) {
	
	var tile;
	if (this.dynamic)
	{
		tile=document.getElementById('div'+this.name+'-tile'+tileName);
		
		var html='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'-'+tileName+'.svg" NAME="emb'+this.name+tileName+'" id="SVGEmbed'+this.name+tileName+'" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	}
	else
	{
		tile=document.getElementById('div'+this.name+'-tile'+tileName);
		
		var html='<EMBED DefaultAntialias="0" wmode="transparent" SRC="'+this.fileName+'-'+tileName+'.svg" NAME="emb'+this.name+tileName+'" id="SVGEmbed'+this.name+tileName+'" HEIGHT="'+mapHeight+'" WIDTH="'+mapWidth+'" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">';
	}
	tile.innerHTML=html;
	
}

/**
 * Elimina un tile dalla memoria.
 */
function TiledSVGLayer_unloadTile(tileName) {
	
	var idArr=this.idsPerTiles[tileName];

	if(idArr) {
		for(var count=0;count<idArr.length;count++) {
			var id=idArr[count];
			var tiles=this.idsLoaded[id];
			var newTiles=new Array();
			if(tiles) {
				for(var count2=0;count2<tiles.length;count2++) {
					var tileName2=tiles[count2];
					if(tileName2!=tileName)
						newTiles.push(tileName2);
				}
			}
			if(newTiles.length>0)
				this.idsLoaded[id]=newTiles;
			else
				delete this.idsLoaded[id];
		}
	}
	this.idsPerTiles[tileName]=null;
	var tile=document.getElementById('div'+this.name+'-tile'+tileName);
	this.loadedTiles[tileName]=undefined;
	tile.innerHTML='';
}

/**
 * Aggiorna il livello in base alla scala di visualizzazione.
 * In questo metodo vengono individuati:
 * 1) i tile da caricare, perchè visualizzazibili e non già caricati.
 * 2) i tile da scaricare, perchè non più da visualizzare.
 */
function TiledSVGLayer_updateRange(currRange,originalRange,realRange,maxRange) {
	
	this.tilesToLoad=new Array();
	this.tilesLoaded=new Array();
	for(ySlice=0;ySlice<this.ntilesY;ySlice++) {					
		for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
			if(this.visibleTileInRange(xSlice,ySlice,currRange,originalRange,maxRange)) {

				if(!this.loadedTile(xSlice+'-'+ySlice))
					this.tilesToLoad.push(xSlice+'-'+ySlice);
					
			} else {
				if(this.loadedTile(xSlice+'-'+ySlice)) {

					this.unloadTile(xSlice+'-'+ySlice);
				}
			}
		}
	}
	if(this.tilesToLoad.length==0) {
		this.updateTilesRange(currRange,originalRange,realRange,maxRange);
	} else {
		this.newIdsLoaded=new Array();
		for(var tile in this.tilesToLoad) {
			
			this.loadTile(this.tilesToLoad[tile]);
		}
	}

	
}

/**
 * Riceve la risposta dal motore java, di layer generato.
 * Inserisce nella pagina una DIV per ogni tile.
 */
function TiledSVGLayer_responseFromGenerator(result) {
	
	if(result!='OK')
		this.fileName=result;
	
	var html='';
	if (this.dynamic)
	{
		for(ySlice=this.ntilesY-1;ySlice>=0;ySlice--) {					
			for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
				
				html+='<div id="div'+this.name+'-tile'+xSlice+'-'+ySlice+'" style="position:absolute; left:0px; top:0px;width:'+mapWidth+'px;height:'+mapHeight+'px">';
				//html+='<EMBED wmode="transparent" SRC="'+basePath+"\\"+this.name+'-'+xSlice+'-'+ySlice+'.svg" NAME="emb'+this.name+xSlice+'-'+ySlice+'" id="SVGEmbed" HEIGHT="400" WIDTH="400" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">'
				html+='</div>';
							
			}
		}
	}
	else
	{
		for(ySlice=this.ntilesY-1;ySlice>=0;ySlice--) {					
			for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
				
				html+='<div id="div'+this.name+'-tile'+xSlice+'-'+ySlice+'" style="position:absolute; left:0px; top:0px;width:'+mapWidth+'px;height:'+mapHeight+'px">';
				//html+='<EMBED wmode="transparent" SRC="'+basePath+"\\"+this.name+'-'+xSlice+'-'+ySlice+'.svg" NAME="emb'+this.name+xSlice+'-'+ySlice+'" id="SVGEmbed" HEIGHT="400" WIDTH="400" TYPE="image/svg-xml" PLUGINSPAGE="http://www.adobe.com/svg/viewer/install/">'
				html+='</div>';
							
			}
		}
	}

	this.loaded=true;			
	document.getElementById('div'+this.name).innerHTML=html;
	this.updateRange(this.currRange,this.originalRange,null,this.maxRange);
}

/**
 * Elimina dalla memoria il layer.
 */
function TiledSVGLayer_unload() {

	document.getElementById('div'+this.name).innerHTML='';
	this.loadedTiles=new Array();
	this.loaded=false;
	this.idsLoaded=new Array();
	this.idsPerTiles=new Array();
}

/**
 * Carica il layer, invocando il motore java.
 */
function TiledSVGLayer_load(currRange,originalRange,realRange,maxRange) {
	if(!this.loaded) {
		
		if (this.dynamic)
		{	
			if(!this.noAlternativeLayer)
				mapInfo.setProperty('alternativeLayer',this.name.toLowerCase()+','+this.name);
			else
				mapInfo.setProperty('alternativeLayer',null);

			engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth*this.resolution,mapHeight*this.resolution,this.featureName,'tiledsvg',this.name,guiVersion,this.mapObjName,this.withEvents,this.ntilesX,this.ntilesY);
		}
		else
		{
			mapInfo.setProperty('alternativeLayer',null);
			var path=(mapInfo.getProperty('applicationArguments'))['application'];
			if(this.features.length>0)
				engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth*this.resolution,mapHeight*this.resolution,this.features.join('*'),'tiledsvg',this.name,path,this.mapObjName,this.withEvents,this.ntilesX,this.ntilesY);
			else
				engine.sendMsg('renderMap',this,'responseFromGenerator',this.mapName,mapWidth*this.resolution,mapHeight*this.resolution,this.name,'tiledsvg',this.name,path,this.mapObjName,this.withEvents,this.ntilesX,this.ntilesY);
		}
	}
}

function TiledSVGLayer_getLoadedIds()
{
	var result=new Array();
	for(var id in this.idsLoaded) {
		
		result.push(id);
	}
	return result;
	/*var ret='';
	for(id in this.idsLoaded) 
	{	
		if (id)
			ret+=','+id;
		
	}
	
	if(ret.length>0)
		return ret.substring(1);
	return ret;*/

}


/**
 * Invocato quando un tile termina il proprio caricamento.
 * Viene verificato se tutti i tile sono stati caricati e in caso positivo si
 * procede con l'aggiornamento della mappa.
 */
function TiledSVGLayer_setLoaded(layerName,idList) {
	
	var tileName=layerName.substring(layerName.indexOf('-')+1);
	/*var idArr=idList.split(',');
	
	for(var count=0;count<idArr.length;count++) {
		var id=idArr[count];

		var curr=this.idsLoaded[idArr[count]];
		if(curr==null)
			this.idsLoaded[idArr[count]]=new Array(tileName);
		else curr.push(tileName);
		this.idsPerTiles[tileName]=idArr;
		if(idArr[count])
			this.newIdsLoaded.push(idArr[count]);
	}*/
	for(count=0;count<this.tilesToLoad.length;count++) {
		if(this.tilesToLoad[count]==tileName) {

			this.tilesLoaded.push(tileName);
			this.loadedTiles[tileName]=1;
		}
	}
	var SVGDocument=this.getDocument(this.name+'-'+tileName);
	var ids=this.implementation.postLoad(SVGDocument,this.name+'-'+tileName,this.renderingManager.getPointerEvents());
	this.idsPerTiles[tileName]=new Array();
	for(var groupById in ids) {
		var currGroup=this.idsGrouping[groupById];
		if(!currGroup)
			currGroup=new Array();
		
		var shapeIds=ids[groupById];
		//this.idsPerTiles[tileName].push(groupById);
		for(var pos in shapeIds) {
			currGroup.push(shapeIds[pos]);
			var curr=this.idsLoaded[shapeIds[pos]];
			if(curr==null)
				this.idsLoaded[shapeIds[pos]]=new Array(tileName);
			else
				curr.push(tileName);
			this.idsLoaded[shapeIds[pos]]=curr;
			if(shapeIds[pos])
				this.newIdsLoaded.push(shapeIds[pos]);
			this.idsPerTiles[tileName].push(shapeIds[pos]);
		}
		this.idsGrouping[groupById]=currGroup;
		
	}
	if(this.tilesToLoad.length==this.tilesLoaded.length) {
		/*if(this.renderingManager) {
			var SVGDocument=document.getElementById('emb'+this.name+tileName).getSVGDocument();
			this.renderingManager.setProperty('color',this.implementation.getColor(SVGDocument));
		}*/
		
		this.updateTilesRange(this.currRange,this.originalRange,null,this.maxRange);
	}


}

/**
 * Aggiorna i tile caricati in base al range corrente.
 */
function TiledSVGLayer_updateTilesRange(currRange,originalRange,realRange,maxRange) {
	var scaleX=currRange.getScaleX(originalRange)/this.ntilesX;
	var scaleY=currRange.getScaleY(originalRange)/this.ntilesY;
	var stroke=20;
	//var time=(new Date()).getTime();
	for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				
				var SVGDocument=this.getDocument(this.name+'-'+xSlice+'-'+ySlice);
				this.implementation.preUpdate(SVGDocument,currRange,originalRange,realRange,maxRange);
				if(this.implementation.hasShapes(SVGDocument,this.name+'-'+xSlice+'-'+ySlice)) {
					if(this.renderingManager)
						this.renderingManager.draw(this,SVGDocument);
					
					this.implementation.postUpdate(SVGDocument,this.name+'-'+xSlice+'-'+ySlice);
					
				}
				
				var scaleFactor=this.implementation.getScaleFactor(SVGDocument);

				var x=(-currRange.minX+xSlice*originalRange.getDeltaX()/this.ntilesX)*scaleFactor*this.ntilesX;
//				
				var maxY=maxRange.maxY/this.ntilesY;
				var deltaY=maxRange.getDeltaY()/this.ntilesY;
				var y=(-currRange.minY+ySlice*originalRange.getDeltaY()/this.ntilesY)*scaleFactor*this.ntilesY;
				
				var top=this.implementation.getTopElement(SVGDocument);
				top.setAttribute('opacity',this.opacity/100.0);
				
				top.setAttribute('transform','scale('+scaleX+','+scaleX+') translate('+x+','+y+')');		
				
			}
		}
	}
	//alert(this.name+': '+((new Date()).getTime()-time));
	//this.show();

	with (this.endObjectHandler) eval(this.endHandler+'(\''+this.name+'\')');
}


function TiledSVGLayer_clone() {
	var result=new TiledSVGLayer(this.name,this.featureName,this.priority,this.withEvents,this.ntilesX,this.ntilesY,this.minScale,this.maxScale,this.onMouseOutHandler,this.onMouseOverHandler,this.onClickHandler,this.onMouseMoveHandler, this.interactiveFunctions,this.rolloverEffect);
	result.resolution=this.resolution;
	result.featureType=this.featureType;
	return result;
}

/**
 * Costruttore. 
 * name               =	nome del layer
 * featureName		  = nome della feature (da passare al motore java) associata al layer
 * priority			  = ordine di visualizzazione rispetto agli altri layer
 * withEvents		  = indica se il layer è interattivo o meno
 * ntilesX			  = numero di tiles lungo l'asse X
 * ntilesY			  = numero di tiles lungo l'asse Y
 * minScale			  = scala minima di visualizzazione (1= quadro, >1= zoom in)
 * maxScale			  = scala massima di visualizzazione (1= quadro, >1= zoom in)
 * onMouseOutHandler  = funzione di gestione dell'uscita da una forma interattiva
 * onMouseOverHandler = funzione di gestione dell'ingresso su una forma interattiva
 * onClickHandler     = funzione di gestione del click su una forma interattiva
 */
function TiledSVGLayer(name,featureName,priority,withEvents,ntilesX,ntilesY,minScale,maxScale,onMouseOutHandler,onMouseOverHandler,onClickHandler,onMouseMoveHandler, interactiveFunctions,rolloverEffect) {
	this.basePath=null;
	this.mapObjName=null;
	this.mapName=null;
	this.name=name;
	this.featureName=featureName;
	this.type='tiledsvg';
	this.withEvents=withEvents;
	this.priority=priority;
	this.ntilesX=ntilesX;
	this.ntilesY=ntilesY;
	this.minScale=minScale;
	this.maxScale=maxScale;
	this.tilesToLoad=new Array();
	this.tilesLoaded=new Array();
	this.loadedTiles=new Array();
	this.idsLoaded=new Array();
	this.idsPerTiles=new Array();
	this.idsGrouping=new Array();
	this.onMouseOutHandler=onMouseOutHandler;
	this.onMouseOverHandler=onMouseOverHandler;
	this.onClickHandler=onClickHandler;
	this.onMouseMoveHandler=onMouseMoveHandler;
	this.interactiveFunctions=new Array();
	this.interactiveFunctions['mainLayer']=interactiveFunctions;
	this.rolloverEffect = rolloverEffect;

	this.newIdsLoaded=new Array();
	this.visible=false;
	this.reallyVisible=false;
	this.loaded=false;
	this.endObjectHandler=null;
	this.endHandler=null;
	this.currRange=null;
	this.originalRange=null;
	this.realRange=null;
	this.thematism= null;
	this.xSlice = 0;
	this.ySlice = 0;
	this.tooltipSql = '';
	this.dynamic=false;
	this.opacity=100;
	//this.changedProperty=false;
	this.renderingManager=null;
	this.renderingManagers=new Array();
	this.implementation=this;
	this.features=new Array();
		
	if(TiledSVGLayer.implementation)
		this.implementation=TiledSVGLayer.implementation.newInstance(this);
	this.resolution=1;

}

function TiledSVGLayer_getShape(id) {
	
	/*for(xSlice=0;xSlice<this.ntilesX;xSlice++) 
	{
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				var svgDoc=document.getElementById('emb'+this.name+xSlice+'-'+ySlice).getSVGDocument();
				var shape=svgDoc.getElementById(this.featureName+','+id);

				if (shape!=null)
				{
					this.xSlice = xSlice;
					this.ySlice = ySlice;
					return shape;
				}
			}
		}
	}
	
	return null;*/
	var shapes=new Array();
	for(xSlice=0;xSlice<this.ntilesX;xSlice++) {
		for(ySlice=0;ySlice<this.ntilesY;ySlice++) {
			
			if(this.loadedTile(xSlice+'-'+ySlice)) { // aggiorna solo i tile caricati
				var SVGDocument=document.getElementById('emb'+this.name+xSlice+'-'+ySlice).getSVGDocument();
				var shape=SVGDocument.getElementById(id);
				
				if(shape)
					shapes.push(shape);
					
			}
		}
	}
	return shapes;

}


function TiledSVGLayer_getDocument(layerN) {
	var pos=layerN.indexOf('-');
	var layerName=layerN.substring(0,pos);
	var layerTile=layerN.substring(pos+1,layerN.length);
	
	var svgDoc=document.getElementById('emb'+layerName+layerTile).getSvgDocument();
	return svgDoc;
}

TiledSVGLayer.implementation=null;

TiledSVGLayer.prototype.getTopElement=TiledSVGLayer_getTopElement;
TiledSVGLayer.prototype.getScaleFactor=TiledSVGLayer_getScaleFactor;
TiledSVGLayer.prototype.preUpdate=TiledSVGLayer_preUpdate;
TiledSVGLayer.prototype.postUpdate=TiledSVGLayer_postUpdate;
TiledSVGLayer.prototype.hasShapes=TiledSVGLayer_hasShapes;
TiledSVGLayer.prototype.setColor=TiledSVGLayer_setColor;
TiledSVGLayer.prototype.setStroke=TiledSVGLayer_setStroke;
TiledSVGLayer.prototype.getColor=TiledSVGLayer_getColor;
TiledSVGLayer.prototype.getStroke=TiledSVGLayer_getStroke;
TiledSVGLayer.prototype.setFill=TiledSVGLayer_setFill;
TiledSVGLayer.prototype.getFill=TiledSVGLayer_getFill;

TiledSVGLayer.prototype.getDocument=TiledSVGLayer_getDocument;

TiledSVGLayer.prototype.getShape=TiledSVGLayer_getShape;
TiledSVGLayer.prototype.hasToBeUpdated=Layer_hasToBeUpdated;
TiledSVGLayer.prototype.visibleInScale=Layer_visibleInScale;
TiledSVGLayer.prototype.setOpacity=TiledSVGLayer_setOpacity;
TiledSVGLayer.prototype.show=Layer_show;
TiledSVGLayer.prototype.hide=Layer_hide;
TiledSVGLayer.prototype.setRenderingManager=Layer_setRenderingManager;

TiledSVGLayer.prototype.hasFunction=Layer_hasFunction;
TiledSVGLayer.prototype.setFunction=Layer_setFunction;
TiledSVGLayer.prototype.update=Layer_update;
TiledSVGLayer.prototype.getLoadedIds=TiledSVGLayer_getLoadedIds;
TiledSVGLayer.prototype.unload=TiledSVGLayer_unload;
TiledSVGLayer.prototype.load=TiledSVGLayer_load;
TiledSVGLayer.prototype.updateRange=TiledSVGLayer_updateRange;
TiledSVGLayer.prototype.setLoaded=TiledSVGLayer_setLoaded;
TiledSVGLayer.prototype.responseFromGenerator=TiledSVGLayer_responseFromGenerator;
TiledSVGLayer.prototype.visibleTileInRange=TiledSVGLayer_visibleTileInRange;
TiledSVGLayer.prototype.loadedTile=TiledSVGLayer_loadedTile;
TiledSVGLayer.prototype.loadTile=TiledSVGLayer_loadTile;
TiledSVGLayer.prototype.unloadTile=TiledSVGLayer_unloadTile;
TiledSVGLayer.prototype.updateTilesRange=TiledSVGLayer_updateTilesRange;
TiledSVGLayer.prototype.onMouseOver=Layer_onMouseOver;
TiledSVGLayer.prototype.onMouseOut=Layer_onMouseOut;
TiledSVGLayer.prototype.onMouseMove=Layer_onMouseMove;
TiledSVGLayer.prototype.onClick=Layer_onClick;
TiledSVGLayer.prototype.init=Layer_init;
TiledSVGLayer.prototype.setBasePath=Layer_setBasePath;
TiledSVGLayer.prototype.setMapObjName=Layer_setMapObjName;
TiledSVGLayer.prototype.setMapName=Layer_setMapName;
TiledSVGLayer.prototype.addFeature=Layer_addFeature;
TiledSVGLayer.prototype.endOpening=Layer_endOpening;
TiledSVGLayer.prototype.getAttributes=Layer_getAttributes;
TiledSVGLayer.prototype.getRenderingManager=Layer_getRenderingManager;

TiledSVGLayer.prototype.getBBox=TiledSVGLayer_getBBox;

TiledSVGLayer.prototype.clone=TiledSVGLayer_clone;
TiledSVGLayer.prototype.select=TiledSVGLayer_select;
TiledSVGLayer.prototype.deselect=TiledSVGLayer_deselect;
TiledSVGLayer.prototype.isItYou=TiledSVGLayer_isItYou;

// TODO: rivedere i tematismi

/*function OnOffThematism(expression,color) {
	this.expression=expression;
	this.type='onoff';
	this.color=color;
	this.layer=null;
	this.applied=false;
}

OnOffThematism.prototype.setLayer=Thematism_setLayer;

function ScaleThematism(name,filter) {
	this.name=name;
	this.type='scale';
	this.filter=filter;
	this.layer=null;
	this.applied=false;
}

ScaleThematism.prototype.setLayer=Thematism_setLayer;



function Thematism_setLayer(layer) {
	this.layer=layer;
}*/

