//jz.Log('Start maputils')
//# expects jzGMap wrapper mostly gmap constructors ....
//#####################  Added for PathMap
//jzMap = jz.Module()
with(jzGMap){

importFrom(jz,'_ mapf dof Class superCls update append last indexOf super getCookie setCookie Log LogObj fn addOnLoadListener')
//importFrom(jzGMap,'*')

$.depreciated= function(){ alert('oups depreciated function') }

//######### ICONS 


	$.WaypointIcon = newIcon('Waypoint',{
		image : 	'/static/icon/info.png',
		hoverImage :	'/static/icon/info_focus.png',
		printImage :	'/static/icon/info.gif',
		iconAnchor:[8,8], infoWindowAnchor:[11,3]})
	$.LocationIcon = newIcon('Location',{
		image:		'/static/icon/favorite.png',
		printImage:	'/static/icon/favorite.gif',
		iconAnchor:[8,8], infoWindowAnchor:[11,3]})
	$.SquareIcon = newIcon('Square',{
		image:		'/static/icon/required.gif',
		hoverImage:	'/static/icon/required.gif',
		iconAnchor:[2,4], infoWindowAnchor:[5,2]})
	$.EndIcon = newIcon('End',{
		image:	'/static/icon/stop.png',
		shape:'right-top-box',
		fillColor: '#ff0000' , fillOpacity: 0.5, outlineWeight: 1, scale:0.5 },
		G_DEFAULT_ICON)
	$.StartIcon = newIcon('Start',{
		image:'/static/icon/start.png',
		shape:'left-top-box',
		fillColor: '#00ff00' , fillOpacity: 0.5, outlineWeight: 1, scale:0.5 },
		G_DEFAULT_ICON)
	$.WaypointN = newIcon('WaypointN',{
		image:'/static/marker/largeTDBlueIcons/blank.png'},
		G_DEFAULT_ICON)
	$.MidIcon = newIcon('Waypoint',{
		image : 	'/static/icon/yellowsml.png',
		hoverImage :	'/static/icon/redsml.png',
		printImage :	'/static/icon/yellowsml.gif',
		shadow :		'/static/icon/shadowsml.png',
		iconAnchor:[6,20], infoWindowAnchor:[6,0] })
	$.StartFlag = newIcon('StartFlag',{
		image : 	    '/static/icon/drapeau-vert-40x35.png',
		hoverImage :	'/static/icon/drapeau-vert-40x35.png',
		printImage :	'/static/icon/drapeau-vert-40x35.gif',
		shadow :		'/static/icon/drapeau-ombre-40x50.png',
		iconAnchor:[10,35], infoWindowAnchor:[20,0] })
	$.EndFlag = newIcon('StartFlag',{
		image : 	'/static/icon/drapeau-fin-40x35.png',
		hoverImage :	'/static/icon/drapeau-fin-40x35.png',
		printImage :	'/static/icon/drapeau-fin-40x35.gif',
		shadow :		'/static/icon/drapeau-ombre-40x50.png',
		iconAnchor:[10,35], infoWindowAnchor:[20,0] })
	$.LoopFlag = newIcon('StartFlag',{
		image : 	    '/static/icon/drapeau-vert-fin-40x35.png',
		hoverImage :	'/static/icon/drapeau-vert-fin-40x35.png',
		printImage :	'/static/icon/drapeau-vert-fin-40x35.gif',
		shadow :		'/static/icon/drapeau-ombre-40x50.png',
		iconAnchor:[10,35], infoWindowAnchor:[20,0] })
	$.smally = newIcon('Waypoint',{
		image : 	'/static/icon/yellowsml.png',
		hoverImage :	'/static/icon/redsml.png',
		printImage :	'/static/icon/yellowsml.gif',
		shadow :		'/static/icon/shadowsml.png',
		iconAnchor:[6,20], infoWindowAnchor:[6,0] })
	$.smallr = newIcon('Waypoint',{
		image : 	'/static/icon/redsml.png',
		hoverImage :	'/static/icon/yellowsml.png',
		printImage :	'/static/icon/redsml.gif',
		shadow :		'/static/icon/shadowsml.png',
		iconAnchor:[6,20], infoWindowAnchor:[6,0] })

	$.IconsAttraits={'Start':StartFlag,'Stop':EndFlag, 'Waypoint':WaypointIcon, 'WaypointN':WaypointN, '':smallr}

$._initIcons= function(){
	dof(100,function(i){
		IconsAttraits['Waypoint'+i]=newIcon('Waypoint'+i,{
			image:'/static/marker/largeTDBlueIcons/marker'+i+'.png',
			printImage:'/static/marker/largeTDBlueIcons/marker'+i+'.gif'
			},
			G_DEFAULT_ICON)
		})
	dof(100,function(i){
		IconsAttraits['Waypoint'+(100+i)]=newIcon('Waypoint'+(100+i),{
			image:'/static/marker/largeTDGreenIcons/marker'+i+'.png',
			printImage:'/static/marker/largeTDGreenIcons/marker'+i+'.gif'
			},
			G_DEFAULT_ICON)
		})

	IconsAttraits['Nature et Plein air'] = newIcon('Att-nature',{
		image:		'/static/icon/nature-pleinair-3-22x26.png',
		printImage:	'/static/icon/nature-pleinair-3-22x26.gif',
		hoverImage:	'/static/icon/nature-pleinair-3-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Attraits et Culture'] = newIcon('Att-culture',{
		image:		'/static/icon/attraits-culture-22x26.png',
		printImage:	'/static/icon/attraits-culture-22x26.gif',
		hoverImage:	'/static/icon/attraits-culture-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Agrotourisme'] = newIcon('Att-agro',{
		image:		'/static/icon/agrotourisme-22x26.png',
		printImage:	'/static/icon/agrotourisme-22x26.gif',
		hoverImage:	'/static/icon/agrotourisme-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Festivals et Événements'] = newIcon('Att-festival',{
		image:		'/static/icon/festivals-evenements-22x26.png',
		printImage:	'/static/icon/festivals-evenements-22x26.gif',
		hoverImage:	'/static/icon/festivals-evenements-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Municipalités'] = newIcon('Att-municipalite',{
		image:		'/static/icon/municipalite-22x26.png',
		printImage:	'/static/icon/municipalite-22x26.gif',
		hoverImage:	'/static/icon/municipalite-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Hébergements'] = newIcon('Att-hebergement',{
		image:		'/static/icon/hebergement-22x26.png',
		printImage:	'/static/icon/hebergement-22x26.gif',
		hoverImage:	'/static/icon/hebergement-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Restauration'] = newIcon('Att-restauration',{
		image:		'/static/icon/restauration-22x26.png',
		printImage:	'/static/icon/restauration-22x26.gif',
		hoverImage:	'/static/icon/restauration-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Essence'] = newIcon('Att-essence',{
		image:		'/static/icon/essence-22x26.png',
		printImage:	'/static/icon/essence-22x26.gif',
		hoverImage:	'/static/icon/essence-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Stationnement'] = newIcon('Att-stationnement',{
		image:		'/static/icon/stationnement-22x26.png',
		printImage:	'/static/icon/stationnement-22x26.gif',
		hoverImage:	'/static/icon/stationnement-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Halte'] = newIcon('Att-halte',{
		image:		'/static/icon/halte-22x26.png',
		printImage:	'/static/icon/halte-22x26.gif',
		hoverImage:	'/static/icon/halte-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})
		
	IconsAttraits['Relais'] = newIcon('Att-relais',{
		image:		'/static/icon/relais-22x26.png',
		printImage:	'/static/icon/relais-22x26.gif',
		hoverImage:	'/static/icon/relais-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})
		
	IconsAttraits['Halte vélo'] = IconsAttraits['Halte']
	IconsAttraits['Relais motoneige'] = IconsAttraits['Relais']
	IconsAttraits['Relais quad'] = IconsAttraits['Relais']

	IconsAttraits['(autres)'] = newIcon('Att-autres',{
		image:		'/static/icon/autres-22x26.png',
		printImage:	'/static/icon/autres-22x26.gif',
		hoverImage:	'/static/icon/autres-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Photos'] = newIcon('Att-photo',{
		image:		'/static/icon/photos-22x26.png',
		printImage:	'/static/icon/photos-22x26.gif',
		hoverImage:	'/static/icon/photos-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Avertissement'] = newIcon('Att-avertissement',{
		image:		'/static/icon/avertissement-22x26.png',
		printImage:	'/static/icon/avertissement-22x26.gif',
		hoverImage:	'/static/icon/avertissement-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Attention'] = newIcon('Att-attention',{
		image:		'/static/icon/avertissement-22x26.png',
		printImage:	'/static/icon/avertissement-22x26.gif',
		hoverImage:	'/static/icon/avertissement-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Aeroport'] = newIcon('Att-aeropport',{
		image:		'/static/icon/aeroport-22x26.png',
		printImage:	'/static/icon/aeroport-22x26.gif',
		hoverImage:	'/static/icon/aeroport-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Autobus'] = newIcon('Att-autobus',{
		image:		'/static/icon/autobus-22x26.png',
		printImage:	'/static/icon/autobus-22x26.gif',
		hoverImage:	'/static/icon/autobus-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Croisière'] = newIcon('Att-croisiere',{
		image:		'/static/icon/croisiere-22x26.png',
		printImage:	'/static/icon/croisiere-22x26.gif',
		hoverImage:	'/static/icon/croisiere-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Information touristique'] = newIcon('Att-information',{
		image:		'/static/icon/info-touristique-permanant-22x26.png',
		printImage:	'/static/icon/info-touristique-permanant-22x26.gif',
		hoverImage:	'/static/icon/info-touristique-permanant-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Train'] = newIcon('Att-train',{
		image:		'/static/icon/train-22x26.png',
		printImage:	'/static/icon/train-22x26.gif',
		hoverImage:	'/static/icon/train-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Traversier'] = newIcon('Att-traversier',{
		image:		'/static/icon/traversier-22x26.png',
		printImage:	'/static/icon/traversier-22x26.gif',
		hoverImage:	'/static/icon/traversier-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Motoneige'] = newIcon('Att-motoneige',{
		image:		'/static/icon/motoneige-22x26.png',
		printImage:	'/static/icon/motoneige-22x26.gif',
		hoverImage:	'/static/icon/motoneige-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Club motoneige']= IconsAttraits['Motoneige']
	IconsAttraits['Locateur motoneige']= IconsAttraits['Motoneige']
	IconsAttraits['Concessionnaire motoneige']= IconsAttraits['Motoneige']

	IconsAttraits['Quad'] = newIcon('Att-quard',{
		image:		'/static/icon/quad-22x26.png',
		printImage:	'/static/icon/quad-22x26.gif',
		hoverImage:	'/static/icon/quad-22x26-inv.png',
		iconAnchor:[11,13], infoWindowAnchor:[0,13]})

	IconsAttraits['Club quad']= IconsAttraits['Quad']

	IconsAttraits['smallr']= smallr
	IconsAttraits['smally']= smally
	IconsAttraits['smallmarker']= smallr
	IconsAttraits['stopicon']= EndIcon
	}
    
//$._initIcons()
addOnLoadListener(_initIcons,'first')

$.addOverlay = function(map,points){
	var outlineStyle = { opacity:.5,    color:'#0000ff', weight:3 };
	var gPoints=mapf(points, function(pt){return newLatLng(pt[0],pt[1])})
	if (gPoints.length>1) map.addOverlay(newPolyline(gPoints, outlineStyle))
	}


$.addOverlay2 = function(map,points){
	var outlineStyle = { opacity:1,    color:'#000000', weight:3 };
	var fillStyle =    { opacity:0.25, color:'#0000ff'};
	var gPoints=mapf(points, function(pt){return newLatLng(pt[0],pt[1])})
	if (gPoints.length>1) map.addOverlay(newPolygon(gPoints, outlineStyle, fillStyle))
	}
	

$.jzRect = function(points,href,title,dist) {
	return //Do nothinf for now
	title=title || ''
	var outlineStyle = { opacity:1,    color:'transparent', weight:0 };
	    var fillStyle =    { opacity:0.1, color:'#0080ff'};
	if (!points || points.length<2) return false
	var gPoints=mapf(points, function(pt){return newLatLng(pt[0],pt[1])})
	var rectBounds=newBounds(gPoints)
/*	if (mapDiv.bounds) {
		mapDiv.bounds.extend(rectBounds.getSouthWest())
		mapDiv.bounds.extend(rectBounds.getNorthEast())
		}*/
	//var poly=newPolygon(gPoints, outlineStyle, fillStyle)
	outlineStyle.hoverContent=_('<b>$titre</b><br />$dst',{titre:title||_('sansnom'), dist:unittxtk(dist||0)})
	var rect=newRectangle(rectBounds,outlineStyle)
	if (href) {
		rect.href=href
		//alert('set rect href to '+href)
		// GEvent.addListener(rect,'click',jzDoNavigate)
		}
	return rect
	}

$.jzRect2 = function(rectBounds,href,title,dist) {
	//copy of jzrect except points is bounds
	title=title || ''
	var outlineStyle = { opacity:1,    color:'transparent', weight:0 };
	var fillStyle =    { opacity:0.1, color:'#0080ff'};
	outlineStyle.hoverContent=_('<b>$titre</b><br />$dst',{titre:title||_('sansnom'), dist:unittxtk(dist||0)})
	var rect=newFocusRectangle(rectBounds,outlineStyle)
	if (href) {
		rect.href=href$
		//alert('set rect href to '+href)
		GEvent.addListener(rect,'click',doNavigate)
		}
	return rect
	}

$.jzRect3 = function(rectBounds,href,title,dist,z,description,style,photo) {
	//copy of jzrect except points is bounds
	title=title || ''
	//var outlineStyle = { opacity:1,    color:'transparent', weight:0 };
	//var fillStyle =    { opacity:0.1, color:'#0080ff'};
	//var rect=FocusRectangle(rectBounds,0,'transparent')
	var rect=FocusRectangle(rectBounds,0,'transparent')
	rect.path=rectBounds
	rect.title=title
	rect.distance=dist
	rect.description=description
	rect.type=style
	rect.photo=photo
	rect.hoverContent=jzPathHover
	rect._jzSetZ=z
	if (href) {
		rect.href=href
		//alert('set rect href to '+href)
		GEvent.addListener(rect,'click',doNavigate)
		}
	//Log('created rect z='+z+' rect.z='+rect._jzSetZ)
	return rect
	}


// function jzPathOld(points,href) {
// 	var outlineStyle = { opacity:.5,    color:'#0000ff', weight:3 };
// 	if (!points || points.length<2) return false
// 	var gPoints=mapf(points, function(pt){return newLatLng(pt[0],pt[1])})
// 	//alert('creating poly line size='+gPoints.length)
// //	var path =new XPolyline(gPoints, outlineStyle)
// 	var path =newPolyline(gPoints, outlineStyle)
// 	if (href) {
// 		path.href=href
// //		GEvent.addListener(path,'click',jzDoNavigate)	bounds.type=type

// 		}
// 	return path
// 	}


$._MaxJzPathPoints = 16
$.pathShouldShow    = function(cntxt){ return (this.dst/(cntxt.diagDst||1.0e-20))>0.005 }
$.attraitShouldShow = function(cntxt){ return (!cntxt.filtre) || (this.info[3] in cntxt.filtre) }

$.jzPath = function(boundsvect,points,href,style) {
	//return false
	var bounds
	//alert(' in jzPathbv='+boundsvect+', points='+points)
	bounds=newBounds([newLatLng(boundsvect[0],boundsvect[1]),newLatLng(boundsvect[2],boundsvect[3])])

	bounds.dst=bounds.getSouthWest().distanceFrom(bounds.getNorthEast())
	bounds.showable=pathShouldShow

	bounds.points=points
	bounds.href=href
	bounds.style=style
	bounds.makeOvl=jzMakePath
	return bounds
	}

$._CopyRightIDs = 99

$.jzTileOverlay = function(boundsvect, tileURL, copyright, gifOpacity, ctrl) {
	//Log('In jz maketileoverly')
	//return false
	var bounds, tileSet, copyrights, cpr, tileType
	//bounds=newBounds([newLatLng(boundsvect[0],boundsvect[1]),newLatLng(boundsvect[2],boundsvect[3])])
	//bounds= new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180))
	//copyrights = new GCopyrightCollection('Map data')
	//cpr=new GCopyright(_CopyRightIDs++,bounds, 0, 'mon copy right' )
	//copyrights.addCopyright(cpr)
			

	tileType = (jz.IE )?'gif':'png'  //(jz.IE && jz.IE<7)?'gif':'png'
	//tileSet = new GTileLayer() //copyrights, 0, 17)
	tileSet = new GTileLayer(copyrights, 0, 17)
	tileSet.getTileUrl = function(tile, zoom){
		return tileURL+'?x=' + tile.x + '&y=' + tile.y + '&zoom=' + (17 - zoom) + '&type='+tileType
		}
	tileSet.isPng = function() { return tileType=='png'  }
	
	gifOpacity=gifOpacity?gifOpacity:1.0
	tileSet.getOpacity = function() { return gifOpacity } //png control their opacity themseleves ...
	//tileSet.getCopyright= function(b,z){ alert('cp asking'+z+' '+b); return 'hi im the copy rigth' }
	//ctrl= false
	ovl=new GTileLayerOverlay(tileSet)
	if (ctrl){
		var name,div = mapDiv
		if (div.vMap.jzControls && div.vMap.jzControls['GOverviewMap']) name=ctrl+'2Control'
		else name = ctrl+'Control'
		if (div.lang == 'en') name+='_en'
		var ctl = (jzGMap && jzGMap[name]) || window[name]
		//alert('Lookup='+ctrl+' ='+name+' is '+ctl)
		if (ctl) div.vMap.addControl(new ctl())
		}
	//Log('...and out jz maketileoverly')
	return ovl
	}

$.jzMakePath = function(){
	if (this.overlayCache) return this.overlayCache
	var outlineStyle = { opacity:.5,    color:'#0000ff', weight:3 }
	var style=this.style
	if (style && MultiSegment.prototype.LineStyles[style]) outlineStyle=MultiSegment.prototype.LineStyles[style]

	var points=his.points
	
	if ( !points || ( points && points.length<2)) return false

	var path
	var points2

	if (points.length>2*_MaxJzPathPoints) { // reduce number of points
		points2=[]
		var step=Math.floor(points.length/_MaxJzPathPoints)
		for (i=0,len=points.length;i<len;i+=step) points2.push(points[i])
		if (i!=len-1) points2.push(points[len-1])
		}
	else points2=points
	var gPoints=mapf(points2, function(pt){return newLatLng(pt[0],pt[1])})
	//alert('creating poly line size='+gPoints.length)
//	var path =new XPolyline(gPoints, outlineStyle)
	var path =newPolyline(gPoints, outlineStyle)
	
	if (this.href) {
		path.href=this.href
//		GEvent.addListener(path,'click',jzDoNavigate)
		}
	//jzCleanup(path)
	return this.overlayCache=path
	}
$.UseEPathCache = false

$.jzMakeEPath = function(){
	if (this.overlayCache) return this.overlayCache
	var lineStyles= MultiSegment.prototype.LineStyles
	var defstyle = { opacity:.5, color:'#0000ff', weight:3 }
	//VAR deflinestyle=  lineStyles['defaultStyle']
	if (this.style in lineStyles)
		 var style= lineStyles[this.style]
	else var style= false

	paths=mapf(this.eoverlays, function(ovl){
			var segstyle= defstyle 
			if (style) segstyle=style
			else if (ovl[2] in lineStyles) segstyle= lineStyles[ovl[2]]
			return newEPolyline(ovl[0],ovl[1],segstyle,this._zi)})
	if (true || !this.nohover){
		var rect=jzRect3(this, this.href, this.title, this.distance, this._zi, this.description, this.style, this.photo)
		paths.push(rect)
		rect.id=this.id
		}
	if (UseEPathCache) this.overlayCache=paths
	return paths
	}

$.cntepath=0
$.EPath = jz.DomClasses['EPath']=jz.DelaiedFactory(jz.DomClasses.Data,function(ops){
	return jzEPath(ops.bounds, ops.data, ops.href, ops.type, ops.title, ops.distance, ops.description, ops.photo, ops.id,ops.nohover)
	} )


$.jzEPath = function(boundsvect,eoverlays,href,style,title,distance,description,photo,id,nohover) {
	//return false
	var bounds
	//cntepath+=1
	//if (cntepath<5) alert('epath '+title+' in '+boundsvect+' eovl='+eoverlays)
	bounds=newBounds([newLatLng(boundsvect[0],boundsvect[1]),newLatLng(boundsvect[2],boundsvect[3])])
	bounds.id=id

	bounds.dst=bounds.getSouthWest().distanceFrom(bounds.getNorthEast())
	bounds.showable=pathShouldShow
	bounds.removeable=function(){return true}

	bounds.eoverlays=eoverlays
	bounds.href=href
	bounds.style=style
	bounds.title=title
	bounds.distance=distance
	bounds.description=description
	bounds.photo=photo
	bounds._zi = (jzGMap)?jzGMap.Rectangle.prototype.currentZIndex--:1000
	bounds.makeOvl=jzMakeEPath
	bounds.nohover=nohover
	//bounds.rect=jzRect2(bounds,href,title,distance)
	//bounds.rect.path=bounds
	//mapDiv.vMap.addOverlay(bounds.rect)
	return bounds
	}


$.EMultiPath= jz.DomClasses['EMultiPath']= jz.DelaiedFactory(jz.DomClasses.Data,function(ops){
	return jzEMultiPath(ops)
	} )

$.jzEMultiPath= Class(GLatLngBounds,{
	jz_init: function(ops) {
		// boundsvect, eoverlays, href, style, title, distance, description, photo, id, nohover
		var boundsvect= ops.bounds
		this.extend(newLatLng(boundsvect[0],boundsvect[1]))
		this.extend(newLatLng(boundsvect[2],boundsvect[3]))
		this.dst=this.getSouthWest().distanceFrom(this.getNorthEast())
	
		this.id=		ops.id
		this.eoverlays=	ops.data
		this.href=		ops.href
		this.style=		ops.type
		this.title=		ops.title
		this.distance=	ops.distance
		this.description= ops.description
		this.photo=		ops.photo
		this.nohover=	ops.nohover
		this.focus=		ops.focus
		//bounds.rect=jzRect2(bounds,href,title,distance)
		//bounds.rect.path=bounds
		//mapDiv.vMap.addOverlay(bounds.rect)
		return this
		},

	showable: function(cntxt){ return (this.dst/(cntxt.diagDst||1.0e-20))>0.005 },
	removeable: function(){return true},
	
	makeFocusObj: function(){ return newEPolyline(this.focus[0],this.focus[1],FocusRectStyle) },

	doShowFocus : function(){
		if (!mapDiv) return
	 	mapDiv.vMap.getDragObject().setDraggableCursor("pointer"); 
		//if (mapDiv.home=='vx' && IE && IE>=7.) return //patch ie hover bug ...
		if (this.focus){
			if (!this.focusoverlay) this.focusoverlay=this.makeFocusObj()
			mapDiv.vMap.addOverlay(this.focusoverlay)
			if (this.href){
				var self=this, fclick=function(latlng){self.doNavigate()} 
				GEvent.addListener(this.focusoverlay,'click',fclick)
				}
			}
		showHover(this)
		},

	doShowFocusNew : function(){
		depreciated()
		if (!mapDiv) return
		if (!this.path ) return
		//Create overlay
		dof(this.path.overlayCache,function(ovl){
			var oldstyle
			if (!ovl.jz_oldStyle) oldstyle=ovl.jz_oldStyle={}  
			dof(FocusRectStyle,function(val,key){
				if (oldstyle) oldstyle[key]=ovl[key]
				ovl[key]=val
				})
			ovl.redraw(true)
			})
		},

	doHideFocus : function(){
		if (!mapDiv) return
		hideHover(this)
	 	mapDiv.vMap.getDragObject().setDraggableCursor("default"); 
		if (this.focusoverlay) mapDiv.vMap.removeOverlay(this.focusoverlay)
		this.focusoverlay=false
		},

	doHideFocusNew : function(){
		depreciated()
		if (!mapDiv) return
		if (!this.path ) return
		//Create overlay
		dof(this.path.overlayCache,function(ovl){
			if (!ovl.jz_oldStyle) return //continue
			update(ovl,ovl.jz_oldStyle)
			delete ovl.jz_oldStyle
			ovl.redraw(true)
			})
		},

	doNavigate: function(){
		if (!this.href) return
		var newhref= urlMerge(this.href)
		top.location= newhref
		},
	
	makeOvl: function(){
		depreciated()
		if (this.overlayCache) return this.overlayCache
		var lineStyles= MultiSegment.prototype.LineStyles
		var defstyle = { opacity:.5, color:'#0000ff', weight:3 }
		//VAR deflinestyle=  lineStyles['defaultStyle']
		if (this.style in lineStyles)
			var style= lineStyles[this.style]
		else var style= false
	
		paths=mapf(this.eoverlays, function(ovl){
				var segstyle= defstyle 
				if (style) segstyle=style
				else if (ovl[2] in lineStyles) segstyle= lineStyles[ovl[2]]
				return newEPolyline(ovl[0],ovl[1],segstyle)})
		if (!this.nohover){
			var target=this, over=function(e){target.doShowFocus()}, out= function(e){target.doHideFocus()}
			dof(paths,function(path){
				// click is seen by hover path GEvent.addListener(path,'click',function(){alert('tic')})
				GEvent.addListener(path,'mouseover',over)
				GEvent.addListener(path,'mouseout',out)
				})
			//var rect=jzRect3(this, this.href, this.title, this.distance, this._zi, this.description, this.style, this.photo)
			//paths.push(rect)
			//rect.id=this.id
			}
		if (UseEPathCache) this.overlayCache=paths
		return paths
		},
		
	makeOvlFunc: newEPolyline,

	makeManagedOvls: function(){
		var lineStyles= MultiSegment.prototype.LineStyles
		var defstyle = { opacity:.5, color:'#0000ff', weight:3 }
		//VAR deflinestyle=  lineStyles['defaultStyle']
		if (this.style in lineStyles)
			var style= lineStyles[this.style]
		else var style= false
	
		var target=this
		var events={
				mouseover:function(e){target.doShowFocus()},
				mouseout:function(e){target.doHideFocus()}
				}

		var ovlfunc= this.makeOvlFunc
		paths=mapf(this.eoverlays, function(ovl){
				var segstyle= defstyle 
				if (style) segstyle=style
				else if (ovl[2] in lineStyles) segstyle= lineStyles[ovl[2]]
				var pts= ovl[0]
				var levels= ovl[1]
				var bndArr= eval(ovl[3])
				//alert('  bndarr='+bndArr)
				
				var minZoom= Math.abs(levels.charCodeAt(0)-80)
				levels= 'P'+levels.substr(1,levels.length-2)+'P' //make it visible ...

				var mo
				mo= ManagedOverlay({
					minZoom:minZoom,
					makeovlfnc:ovlfunc,
					makeovlargs:[pts,levels,segstyle],
					ovlevents:events})
				var l1= newLatLng(bndArr[0],bndArr[1])
				var l2= newLatLng(bndArr[2],bndArr[3])
				//if (!window.xxx) xxx=0
				//if ((xxx+=1)<10) alert(' mo='+mo+ ' l1='+ l1+' l2='+l2+' bndArr='+bndArr+' t='+(typeof bndArr))
				mo.extend(l1)
				mo.extend(l2)
				if (!window.xxx) xxx=0
				//if ((xxx+=1)<10) alert(' mo='+mo+ ' l1='+ l1+' l2='+l2)
				return mo
				})
		//return [ ManagedOverlayContainer(paths) ]
		return paths
		},




	hoverContent: function(){
		//return '<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+this.title+'</div>'

		if (this.nohover) return ''
		
		var ret=''
		ret+='<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+this.title
		if (this.type || this.distance){
			ret+='<br/><span style="font-weight:normal;">'
			if (this.type) ret+=_(this.type)+' '
			if (this.distance)  ret+=unittxtk(this.distance)
			ret+='</span>'
			}
		ret+='</div>'
	
		if (this.photo) ret+='<div style="padding:0px; margin:2px 2px 2px; border:2px #888888 solid"><img style="width:100%" src="'+this.photo+'" /></div>'
		ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
		if (this.description && this.description!='None') {
			if (this.description.length < 220) ret+=this.description
			else ret+=this.description.substr(0,200) + ' [...]'
			}
		if (this.href) {
			ret+='<br/><a href="'+this.href+'" onclick="top.location=this.href"><b>'
			ret+=_('ClickerDetailParcours')
			ret+='</b></a>'
			} 
		ret+='</div>'
		return ret
		}


	})

$.jzEPolygon= Class(jzEMultiPath,{
    
	jz_init: function(ops){
		var ret= jz.superClsP(jzEPolygon).jz_init.call(this,ops)
		this.distance=0
		return ret
		},
		
    
	makeFocusObj: function(){ return newEPolygon(this.focus[0],this.focus[1],FocusZoneStyle) },
	
	makeOvlFunc: newEPolygon,
	
	hoverContent: function(){
		//return '<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+this.title+'</div>'

		if (this.nohover) return ''
		
		var ret=''
		ret+='<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+this.title
		if (this.type || this.distance){
			ret+='<br/><span style="font-weight:normal;">'
			if (this.type) ret+=_(this.type)+' '
			if (this.distance)  ret+=unittxtk(this.distance)
			ret+='</span>'
			}
		ret+='</div>'
	
		if (this.photo) ret+='<div style="padding:0px; margin:2px 2px 2px; border:2px #888888 solid"><img style="width:100%" src="'+this.photo+'" /></div>'
		ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
		if (this.description && this.description!='None') {
			if (this.description.length < 220) ret+=this.description
			else ret+=this.description.substr(0,200) + ' [...]'
			}
		if (this.href) {
			ret+='<br/><a href="'+this.href+'" onclick="top.location=this.href"><b>'
			ret+=_('Click zone for details')
			ret+='</b></a>'
			} 
		ret+='</div>'
		
		//patch bring hover closser
		if (mapDiv.hoverDiv){
			mapDiv.hoverDiv.mousePadding= 10
			mapDiv.hoverDiv.hoverWidth= 120
			}
		return ret
		}

	})

$.EPolygon= jz.DomClasses['EPolygon']= jz.DelaiedFactory(jz.DomClasses.Data,function(ops){
	return jzEPolygon(ops) // jzEMultiPath(ops)
	} )
//txt='bll oqwon enof jfwfh jwefj newfh  weh lfw fbbqwf  wfih lwef f pwf hwefh ihwfe i  wefi  iwf  ii wefi f i iwf ifeeh fh hhh feh h f hwfhhhjhwf h wfeh;pwf'
$._isval= function(v){ return (v && v!='None' && v!='none')?v:'' }
$._getDesc= function(obj){ 
    var desc=obj.description
    if (!_isval(desc)) return ''
    if ((desc.length < 220) || (obj.type=="Attention")) return desc
    else return desc.substr(0,200) + ' [...]'
    }

$.jzPointHover = function(){
	var info=this.info
	if (!info || !info[2]) return false
	var ret='',adr=''
	ret+='<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+info[2]+'</div>'
	if (_isval(info[5])) ret+='<img style="padding:0px; margin:2px; width:125px; float:left; border:2px #888888 solid" src="'+info[5]+'" />'
	
	if (_isval(info[6])) adr=info[6]
	if (_isval(info[7])) adr+=info[7]
	if (_isval(info[8])){
	    if (_isval(info[7])) adr+= '<br />'+info[8]
	    else adr+= info[8]
	    }
	if (adr) ret+= ('<div style="font-weight:normal; margin-left:2px; padding:2px; letter-spacing:-0.5px;">'+adr+'</div>')
	
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'

	//ret+= 'info[6]="'+info[6]+'"<br />'
	//ret+= 'info[7]="'+info[7]+'"<br />'
	//ret+= 'info[8]="'+info[8]+'"<br />'

	if (info[4] && info[4]!='None') {
		if ((info[4].length < 220)||(info[3]=='Attention')) ret+=info[4]
		else ret+=info[4].substr(0,200) + ' [...]'
		}
	//ret+= info[4]

	if (this.href) {
		ret+='<br/><a href="'+this.href+'" onclick="top.location=this.href"><b>'
		ret+=_('ClickerDetailAttrait')
		ret+='</b></a>'
		} 
	ret+='</div>'
	//alert('this= '+this+' href='+this.href+' photo='+info[5]+' info='+info)
	return ret
	}

$.jzWayPointHover = function(){
	var info=this.info
	if (!info || !info[2]) return false
	var ret='',adr
	//background-color:#dddddd;
	ret+='<div style="font-weight:bold; background-color:#ddd;; margin:2px; padding-left:2px">'+info[2]+'</div>'
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	ret+= info[4]
	ret+='<br />'
	//ret+=mapf(info,function(v,i){ return i+'='+v}).join(' ')
	ret+='</div>'
	if (this.info[7]) {
		ret+=_('<iframe src="$url" class="hovermap"></iframe>',{url:this.info[7]})
		} 
	//alert('this= '+this+' href='+this.href+' photo='+info[5]+' info='+info)
	return ret
	}

// [0.latitude, 1.longitude, 2.title, 3.type, 4.description, 5.photo, 6.address, 7.carte ]
$.jzPointHover2 = function(fromProxy){
	var obj=this.obj
	if (!obj || !obj.title) return false
	if (!fromProxy){
	  var lst= findNear(obj)
	  if (lst) {	
		jzProxyHover(lst)
		return
		}
	  }
	//else alert('got a no proxy on '+obj.id)
	var ret='',adr=''
	ret+=_('<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">$title</div>',obj)
	if (_isval(obj.photo)) ret+=_('<img style="padding:0px; margin:2px; width:125px; float:left; border:2px #888888 solid" src="$photo" />',obj)
	
	if (_isval(obj.address)) adr=obj.address
	if (_isval(obj.carte)) adr+=obj.carte
	//if (_isval(info[8])){
	//    if (_isval(info[7])) adr+= '<br />'+info[8]
	//    else adr+= info[8]
	//    }
	if (adr) ret+= _('<div style="font-weight:normal; margin-left:2px; padding:2px; letter-spacing:-0.5px;">$adr</div>',{adr:adr})
	
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	//if (info[4] && info[4]!='None') {
	//	if (info[4].length < 220) ret+=info[4]
	//	else ret+=info[4].substr(0,200) + ' [...]'
	//	}
	//ret+= 'info[6]="'+info[6]+'"<br />'
	//ret+= 'info[7]="'+info[7]+'"<br />'
	//ret+= 'info[8]="'+info[8]+'"<br />'
	ret+= _getDesc(obj)
	if (this.href) {
		ret+=_('<br/><a href="$href" onclick="top.location=this.href"><b>',this)
		ret+=_('ClickerDetailAttrait')
		ret+='</b></a>'
		} 
	ret+='</div>'
	//alert('this= '+this+' href='+this.href+' photo='+info[5]+' info='+info)
	return ret
	}

$.earthRadious=6378.137
$.earthCircum= 2*Math.PI*earthRadious

$.findNear= function(obj){
	if (!obj.proxy || obj.proxy.length==0) return false
	
	var lvl= mapDiv.vMap.getZoom()
	var pixelWidth= earthCircum/( Math.pow(2.,lvl) * 256 )
	var mindst= 13*pixelWidth

	lst= extractf(obj.proxy,function(i){ return i[1]<mindst })
	if (lst.length==0) return false
	lst.unshift([obj.id,0])
	return lst
	}

$.jzProxyHover= function(lst){
	
	var q="'"
	var ret= _('Pour plus d´infos, survolez une ligne')
	ret+='<div class="sectioncontent"><table style="">' // <column style="width:30px;"/><column style="width:22px;"/><column style="width:100%;"/>'
	dof(lst,function(info,k){
	  var obj= LocationLookup[info[0]],dst=Math.round(info[1])
	  if (!obj) return //this is a continue in dof

	  //if (obj.photo) 
	  //  ret+= _('<tr><td><img src="$photo" style="width:40px;" /></td><td><img src="$iconimg" /></td><td>$title</td></tr>',obj)
	  //else 
	  //  ret+= _('<tr><td></td><td><img src="$iconimg" /></td><td>$title</td></tr>',obj)

	  ret+= _('<tr onmouseover="jzGMap.doproxyitemshowhover(\'$id\',event||window.event)" onmouseout="jzGMap.doproxyitemhidehover(\'$id\')" onclick="jzGMap.doproxyitemclick(\'$id\')" ><td><img src="$iconimg" /></td><td>${dst}km</td><td>$title</td></tr>',obj,{dst:dst,id:info[0]})
	  })
	ret+='</table></div>'
	ret+= _('+ zommez pour mieux visualiser')

	showMenu(ret)
	return
	}

$.doproxyitemshowhover= function(id,e){
	var obj= LocationLookup[id]
	//alert('item hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	if (!obj || !obj.overlayCache ){
	    //alert('item no hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	    return
	    }
	pos=[e.clientX,e.clientY]
	showHover(obj.overlayCache,false,1,pos) // no proxy hover
	}

$.doproxyitemhidehover= function(id){
	var obj= LocationLookup[id]
	//alert('item hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	if (!obj || !obj.overlayCache ){
	    //alert('item no hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	    return
	    }
	hideHover(obj.overlayCache,false,1) // no proxy hover
	}

$.doproxyitemclick= function(id){
	var obj= LocationLookup[id]
	//alert('item hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	if (!obj || !obj.overlayCache ){
	    //alert('item no hover '+id+' obj='+obj+' cache='+obj.overlayCache)
	    return
	    }
	doNavigate(obj.overlayCache)
	}


$.jzWayPointHover = function(){
	var info=this.info
	if (!info || !info[2]) return false
	var ret='',adr
	//background-color:#dddddd;
	ret+='<div style="font-weight:bold; background-color:#ddd;; margin:2px; padding-left:2px">'+info[2]+'</div>'
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	ret+= info[4]
	ret+='<br />'
	//ret+=mapf(info,function(v,i){ return i+'='+v}).join(' ')
	ret+='</div>'
	if (this.info[7]) {
		ret+=_('<iframe src="$url" class="hovermap"></iframe>',{url:this.info[7]})
		} 
	//alert('this= '+this+' href='+this.href+' photo='+info[5]+' info='+info)
	return ret
	}

$.jzPhotoHover = function(){
	var info=this.info
	if (!info || !info[2]) return false
	var ret='',adr
	ret+='<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+info[2]+'</div>'
	if (info[5] && info[5]!='None') ret+='<div style="padding:0px; margin:2px 2px 2px; border:2px #888888 solid"><img style="width:100%" src="'+info[5]+'" /></div>'
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	if (info[4] && info[4]!='None') {
		if (info[4].length < 220) ret+=info[4]
		else ret+=info[4].substr(0,200) + ' [...]'
		}
	if (this.href) {
		ret+='<br/><b href="'+this.href+'" onclick="top.location=this.href">'
		ret+=_('ClickerDetailPhoto')
		ret+='</b>'
		} 
	ret+='</div>'
	return ret
	}

// [0.latitude, 1.longitude, 2.title, 3.type, 4.description, 5.photo, 6.address, 7.carte ]
$.jzPhotoHover2 = function(fromProxy){
	var obj=this.obj
	if (!obj || !obj.title) return false
	if (!fromProxy){
	  var lst= findNear(obj)
	  if (lst) {	
		jzProxyHover(lst)
		return
		}
	  }
	var ret='',adr
	ret+=_('<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">$title</div>',obj)
	if (_isval(obj.photo)) ret+=_('<div style="padding:0px; margin:2px 2px 2px; border:2px #888888 solid"><img style="width:100%" src="$photo" /></div>',obj)
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	if (_isval(obj.description)) ret+= _getDesc(obj)
	if (this.href) {
		ret+=_('<br/><b href="$href" onclick="top.location=this.href">',this)
		ret+=_('ClickerDetailPhoto')
		ret+='</b>'
		} 
	ret+='</div>'
	return ret
	}



$.jzPathHover = function(){
	var ret=''
	ret+='<div style="font-weight:bold; background-color:#dddddd; margin:2px; padding-left:2px">'+this.title
	if (this.type || this.distance){
		ret+='<br/><span style="font-weight:normal;">'
		if (this.type) ret+=_(this.type)+' '
		if (this.distance)  ret+=unittxtk(this.distance)
		ret+='</span>'
		}
	ret+='</div>'

	if (this.photo) ret+='<div style="padding:0px; margin:2px 2px 2px; border:2px #888888 solid"><img style="width:100%" src="'+this.photo+'" /></div>'
	ret+='<div style="clear:left; font-weight:200; font-size:8pt; padding:2px;" >'
	if (this.description && this.description!='None') {
		if (this.description.length < 220) ret+=this.description
		else ret+=this.description.substr(0,200) + ' [...]'
		}
	if (this.href) {
		ret+='<br/><a href="'+this.href+'" onclick="top.location=this.href"><b>'
		ret+=_('ClickerDetailParcours')
		ret+='</b></a>'
		} 
	ret+='</div>'
	return ret
	}


jz.DomClasses['Location']=jz.DelaiedFactory(jz.DomClasses.Data,function(ops){
	//alert('location for '+ops)
	var a=[ops.latitude, ops.longitude, ops.title, ops.type, ops.description, ops.photo, ops.address, ops.carte ]
	return jzPoint (a ,ops.href ,ops.id) })

$.jzPoint = function(info,href,id){
	//alert('make point info='+info+' href='+href)
	if (!info) return false
	//Log('In jz make point '+info[2])
	var pt=newLatLng(info[0],info[1])
	pt.id=id
	pt.info=info
	pt.href=href
	pt.makeOvl=jzMakeAttrait
	pt.showable=attraitShouldShow
	//Log('...and out make point '+info[2])
	return pt
	}

$.LocationLookup={}
$.jzPoint2 = function(ops){
	//alert('make point info='+info+' href='+href)
	if (!ops) return false
	//Log('In jz make point '+info[2])
	var pt=newLatLng(ops.latitude,ops.longitude)
	delete ops.latitude
	delete ops.longitude
	update(pt,ops)
	LocationLookup[pt.id]= pt
	pt.makeOvl=jzMakeAttrait2
	pt.showable=attraitShouldShow
	//Log('...and out make point '+info[2])
	return pt
	}

jz.DomClasses['Location2']=jz.DelaiedFactory(jz.DomClasses.Data,jzPoint2 )

$.jzMakeAttrait = function() {
	//Log('In jz make attrait this='+this+' this.icon='+this.info[3]+' this.info='+this.info)
	if (this.overlayCache) return this.overlayCache
	if (!this.info) return false
	var icon=this.info[3]
	if (icon) icon=IconsAttraits[icon]
	if (!icon) icon=IconsAttraits['']
	var newM
	var atype= this.info[3]
	if (atype=='Photos')
		 newM= newMarker(this,{icon:icon, href:this.href, hoverContent:jzPhotoHover})
	else if (atype.substr(0,8)=='Waypoint' || atype == 'Start' || atype == 'Stop' ) {
		 newM= newMarker(this,{icon:icon, href:this.href, hoverContent:jzWayPointHover})
		}
	else newM=newMarker(this,{icon:icon, href:this.href, hoverContent:jzPointHover})
	newM.id=this.id
	newM.info=this.info
	//Log('jzMakeAttrait returning '+newM)
	//**** PATCH pour hreftarget a mieux penser ....
	newM.hreftarget= mapDiv.jzhreftarget
	return this.overlayCache=newM
	}

$.jzMakeAttrait2 = function() {
	//Log('In jz make attrait this='+this+' this.icon='+this.info[3]+' this.info='+this.info)
	if (this.overlayCache) return this.overlayCache
	var icon=this.type
	if (icon) icon=IconsAttraits[icon]
	if (!icon) icon=IconsAttraits['']
	this.icon= icon
	this.iconimg= icon.image
	var newM
	var atype= this.type
	if (atype=='Photos')
		 newM= newMarker(this,{icon:icon, href:this.href, hoverContent:jzPhotoHover2})
	else if (atype.substr(0,8)=='Waypoint' || atype == 'Start' || atype == 'Stop' ) {
		 newM= newMarker(this,{icon:icon, href:this.href, hoverContent:jzWayPointHover2})
		}
	else newM=newMarker(this,{icon:icon, href:this.href, hoverContent:jzPointHover2})
	newM.id=this.id
	newM.obj=this
	//Log('jzMakeAttrait returning '+newM)
	//**** PATCH pour hreftarget a mieux penser ....
	newM.hreftarget= mapDiv.jzhreftarget2
	return this.overlayCache=newM
	}

//#####################  Added for PointMap
			

/**********************************/
//** Segemented Array
//jz.Log('..Start Class MultiArray')

$.MultiArray = Class(Object,{
	
	length : 0,
	maxSegSize :32,
	SPLIT_NOTREQUIRED : new Object(),

	jz_init : function(){ 
		this.segments = [[]] //mutable object need a fresh copy for each instance ..
		//Log('in MultiArray jz_init this=')
		//jz.LogObj(this)
		},
	
	lastSegment : function(){return last(this.segments)},
	
	push : function(obj){with(this){
		if (lastSegment().length>=maxSegSize) _addSegment()
		lastSegment().push(obj)
		return length++
		}},
	
	_addSegment : function(){ this.segments.push([]) },
	
	pop : function(){with(this){
		var obj=lastSegment().pop()
		if (lastSegment().length<=0 && segments.length>1) _removeSegment()
		if (length>0) length--
		return obj
		}},

	_removeSegment : function(){this.segments.pop() },
		
	_convertIdx : function(idx){with(this){
		// var mod; return [(idx-(mod=idx % maxSegSize))/maxSegSiz,mod] // works if no splits
		// dont test for idx higher than length becuase rare case ...works any ways
		if (idx<0)  idx+=length // access by the end, if still negative convert will return false
		for (var seg=0,len=segments.length; seg<len && idx>=segments[seg].length;idx-=segments[seg++].length) { }
		if (seg<len) return [seg,idx]
		else return false
		}},

	jz_at : function(idx){with(this){
		var pos=_convertIdx(idx), ret
		if (pos) ret=segments[pos[0]][pos[1]]
		else ret=undefined
		return ret
		}},
	
	put : function(idx,val){with(this){
		var pos=_convertIdx(idx)
		if (pos) return segments[pos[0]][pos[1]]=val
		// else, probable farther than length
		if (idx<0) return undefined // reverse acces past the begining ....should through index error
		// else OK this is a grow...
		jz_append(new Array(idx-length-1)) // could be optimized to avoid looping on Array
		push(val)
		return val
		}},

	_splitAt : function(idx){with(this){ // split segment so that idx is in position 0 of a segment
		var pos=_convertIdx(idx)
		if (!pos) return false // cant split
		var segPos=pos[0], segIdx=pos[1], seg=segments[segPos]
		if (segIdx==0) return SPLIT_NOTREQUIRED // idx is pos 0 of segment at segPos
		segments.splice(segPos+1,0,seg.splice(segIdx,length-segIdx)) // split segment at segIdx and insert after
		return segPos+1
		}},

	jz_dof :function(func) { 
		for (var idx=0,pos; (pos=this._convertIdx(idx)); idx++) func(this.segments[pos[0]][pos[1]],idx)
		},

	jz_append : function(seq) { var self=this; dof(seq,function(val,key) { self.push(val);return this  })},

	jz_last : function() { return last(this.lastSegment()) }

	})//End class Multi Array
//jz.Log('..end Class MultiArray')

var defStyle = Class({color: '#404040', weight:4, opacity: 0.5})
var terre={pattern:[20,6]}
var projet={color:'#000000', weight:1,  opacity: 0.5}

//jz.Log('..Start Class MultiSegment')

// MultiSegment is based on MultiArray but it has an update function that is called when ever the last segment is modified
$.MultiSegment = Class(MultiArray,{
	LineStyles : {
		defaultStyle  : defStyle(),
		PisteAsphalte : defStyle({ opacity:0.7,   color: '#008000' }),
		PisteTerre    : defStyle({ opacity:0.7,   color: '#00ff00' }),
		PisteProjet   : [ defStyle({ opacity:0.7, color: '#00ff00' }), projet ],

	//Piste balisée 
		BaliseeChausseeDesignee : defStyle({color:'#0000ff'}),
		BaliseeBande 		: defStyle({color:'#00ff80',opacity:0.5}),
		BaliseeAccotement 	: defStyle({color:'#ff8000',opacity:0.6}),
		BaliseeProjet		: [ defStyle({color:'#81d2fe'}), projet ],

	//Piste non balisée
		VoieAsphalte 		: defStyle({ color: '#404040',opacity:0.5 }),
		VoieTerre 		: defStyle({color:'#702000',opacity:0.5}),
	//Autres	
		NavetteTerre 		: defStyle({color:'#ff8000'}),
		NavetteEau 		: defStyle({color:'#ffff00'}),
		Train 			: defStyle({color:'#ff80ff'}),

		PisteCyclable		: {color:'#00ff00', opacity:0.7, weight:3},
		CircuitRoutier 		: {color:'#4040ff', opacity:0.6, weight:3 },
		Hybride 		: {color:'#20A0B0', opacity:0.8, weight:3 },
		SansSoustype 		: {color:'#4040ff', opacity:0.8, weight:3 },
		motoneige		: {color:'#ffff00', opacity:0.4, weight:12 },
		zone 			: {color:'#ffffff', opacity:0.001,  weight:1 },
		gourmande		: {color:'#ff0000', opacity:0.5, weight:8 }
		},

	
	push : function(obj){with(this){
		var ret=superCls(this,'push').call(this,obj) // call push of super class
		updateAdded([obj])
		updateSegment(lastSegment())
		return ret
		}},

	put : function(idx,val){with(this){
		var ret=superCls(this,'put').call(this,idx,val) // call put of super class
		var pos=_convertIdx(idx)
		updateSegment(segments[pos[0]]) //should also do a updateRemoved and Added on oldVal and (new)val
		if (pos[1]===0 && pos[0]) {// first elemnt of segement but not in first segement 
			// thenrember last elemtn is copie of first element of next segment ...
			var beforeSeg=segments[pos[0]-1]
			beforeSeg[beforeSeg.length-1]=val
			updateSegment(beforeSeg)
			}
		return ret // but for now only used on same marker so not really necessairy ... 
		}},

	_addSegment : function(){with(this){
		var repVal=jz_last()
		segments.push([repVal]) //repeat last element of previous segement
		}},

	pop : function(){with(this){
		var val=superCls(this,'pop').call(this) // call pop of super class
		updateRemoved([val])
		updateSegment(lastSegment())
		if (lastSegment().length<=1 && segments.length>1) {
			_removeSegment() //avoids a pop and segemnt of lenght 1
			}
		return val
		}},

	//Ok in append we dont want an update at each push
	jz_append : function(seq) {//with(this){
		while (seq.length>0){
			if (this.lastSegment().length>=this.maxSegSize) this._addSegment()
			
			//find break point
			var breakPoint=this.maxSegSize-this.lastSegment().length,stop=false
			dof(breakPoint, function(idx){ if (!stop &&  seq[idx] && seq[idx].type ) { //idx!=0 &&
				breakPoint=idx,stop=true
				}})
			var subSeq=seq.splice(0,breakPoint+1)
			//checkif subsegment requires a split ...
			append(this.lastSegment(), subSeq)
			this.length+=subSeq.length
			this.updateAdded(subSeq)
			this.updateSegment(this.lastSegment())
			if (seq.length>0) this._addSegment()
			}
		return this
		},

	updateRemoved	: function(vals) {/* lastSegment has changed */},
	updateAdded	: function(vals) {/* lastSegment has changed */},
	updateSegment	: function(segment) {/* lastSegment has changed */},
	updateSegmentList : function(pos) {with(this){//special case ...
		// alert('doing update segment list starting at '+pos)
		 do {updateSegment(segments[pos])} while (segments.length>++pos && !(segments[pos][0].type))
		 }},
	
	_convertIdx	: function(idx){with(this){
		// var mod; return [(idx-(mod=idx % maxSegSize))/maxSegSiz,mod] // works if no splits
		// rember in multi segment end value is repeated a begining of next segment
		for (var seg=0,len=segments.length; seg<len && idx>=segments[seg].length;idx-=(segments[seg++].length-1)) { } // if not last segment then end is a duplicate
		if (seg>=len) return false
		// else
		if ( (segments[seg].length==idx+1) && (segments[seg+1]) ) { // if this is a split duplicate
			return [seg+1,0]
			}
		else return [seg,idx]
		}},

	_splitAt	: function(idx){with(this){ // split segment so that idx is in position 0 of a segment
		var segPos=superCls(this,'_splitAt').call(this,idx) // call pop of super class

		if (!segPos) return false // cant split
		if (segPos==SPLIT_NOTREQUIRED) { // even if split did not occure send updates becuse something was changed ....
			var segIdx=_convertIdx(idx)[0]
			}
		else { // we did a split duplicate last value
			segments[segPos-1].push(segments[segPos][0]) // duplicate last value
			updateSegment(segments[segPos-1]) // segment was shortened
			var segIdx=segPos
			}
		return segPos
		}},
	
	getStyle : function(seg){ return this.LineStyles[ this.getType(seg) || 'defaultStyle' ] },
	getType	: function(seg){ 
		var type=seg[0].type
		if (type) return type
		//else
		for (var pos=indexOf(this.segments,seg);(0<=--pos)&& !(type=this.segments[pos][0].type);){}
		return type
		}
	
	})//End MutliSegment Class
//jz.Log('..end Class MultiArray')


$.typePisteInfo = { 
	none:{titre:'(sans changement)', group:''},
	/*group:'Piste-cyclable'*/
		PisteAsphalte:	{ titre:_('Asphaltée'),		group:_('Piste-cyclable'),	color: '#008000'},
		PisteTerre:	{ titre:_('Poussière de pierre'),group:_('Piste-cyclable'),	color: '#00ff00'},
		PisteProjet:	{ titre:_('Projet'),		group:_('Piste-cyclable'),	color: '#000000'},
	/*Balisée sur route'*/
		BaliseeChausseeDesignee: { titre:_('Chaussée désignée asphaltée'), group:_('Balisée sur route'), color: '#0000ff'},
		BaliseeBande:	{ titre:_('Bande cyclable'),	group:_('Balisée sur route'),	color:'#00ff80' },
		BaliseeAccotement:{titre:_('Accotement asphalté'),group:_('Balisée sur route'),	color: '#ff8000'},
		BaliseeProjet:	{ titre:_('Projet'),		group:_('Balisée sur route'),	color: '#000000'},
	/*Non balisée sur route*/
		VoieAsphalte:	{ titre:_('Chaussée pavée'),	group:_('Non balisée sur route'), color: '#808080'},
		VoieTerre:	{ titre:_('Chaussée non pavée'),group:_('Non balisée sur route'), color: '#702000'},
	/*group:'Autres',*/
		NavetteTerre:	{ titre:_('Navette terrestre'),	group:_('Autres'), color: '#ff8000'},
		NavetteEau:	{ titre:_('Navette fluviale'),	group:_('Autres'), color: '#ffff00'},
		Train:		{ titre:_('Train'),		group:_('Autres'), color: '#ff80ff'}
	}


$.typeTitre  = function(obj){
	var typeInfo= typePisteInfo[obj['type']] || typePisteInfo['none']
	return '"'+typeInfo.group+' - '+typeInfo.titre+'"'//+' '+typeInfo.group.toLowerCase()
	}

$.getPositionCookie = function(name){
	var ret = getPositionCookie2(name)
	//alert('get pos cook name = '+name+' val='+ret)
	return ret
	}

$.getPositionCookie2 = function(name) {
	var pos=getCookie(name)
	if (!pos) return false
	pos = pos.split(',')
	if (pos.length!=3) return false
	var lat=parseFloat(pos[0])
	var lng=parseFloat(pos[1])
	var zoom=parseInt(pos[2])
	if (!(lat && lng && zoom)) return false
	return [lat,lng,zoom]
	}

$.setPositionCookie = function(name,lat,lng,zoom) { 
	//alert('doing set pos cook to '+[lat,lng,zoom])
	setCookie(name,[lat,lng,zoom]) }

$.wordconverter = {
	'H\xc3\xa9bergements' :'Hébergements',
	'Municipalit\xc3\xa9s':'Municipalités',
	'Festivals et \xC3\x89v\xc3\xa9nements' : 'Festivals et Événements'
	}


// TODO: Generlize this remove dependencie on word converter see comment in jz.js about this function
$.updateChecksFor = function(field,name){

	var href = unescape(window.location.href)
	var pos = href.indexOf(field)
	var params={} //default value {}=none false=all
	if (pos>-1){
		pos+= 1+field.length
		var end = href.indexOf('&',pos)
		if (end<pos) end = href.length 
		var paramstr=href.substring(pos,end)
		if (paramstr=='*') params=false
		else {
			params={}
			dof(paramstr.split(','),function(word){
				if (word in wordconverter) word=wordconverter[word]
				params[word]=true
				})
			}
		}
	//var paramdump=''
	//jz.dof(params,function(v,k){paramdump+=k+'='+v+'\n'})
	//alert('update checks pos='+pos+' end='+end+' field='+field+'\n paramstr='+paramstr+'\n params='+params+'\n paramdump='+paramdump)
	var elems=document.getElementsByName(name)
	for (var i=0,elem; elem=elems[i]; i++) {
		//alert('elem val='+elem.value+' param='+params[elem.value])
		if ((!params || elem.value in params) != elem.checked) {
			//alert('changing '+name+'.'+elem.id+' from '+elem.checked+' to '+(!elem.checked)+' params='+params)
			// elem.checked=!elem.checked //only set if required ...
			}
//		if (!params || elem.value in params) elem.checked=true
//		else elem.checked=false
		}
	}
window.updateChecksFor = updateChecksFor


$.printNback = function(){
	setTimeout(function(){print()},2000) //IE expects a function not a build in (i think)
	//setTimeout(function() {history.back()},2000)
	}

jz.DomClasses['printNback']=printNback

$.createTracker= function(elem){
    if (!( 'mapDiv' in window)){
	setTimeout(function(){ createTracker(elem)},2000)
	return
	}
    var map= mapDiv.vMap
    GEvent.addListener(map,'mousemove',function(pos){
	elem.innerHTML=pos.lat()+','+pos.lng()
	})
    }
    
jz.DomClasses['mapMouseTracker']= createTracker

$.createClickTracker= function(elem){
    if (!( 'mapDiv' in window)){
	setTimeout(function(){ createClickTracker(elem)},2000)
	return
	}
    var map= mapDiv.vMap
    GEvent.addListener(map,'click',function(ovl,pos,ovlpos){
	pos = pos || ovlpos
	if (!pos) return
	elem.innerHTML=pos.lat()+','+pos.lng()
	})
    }
    
jz.DomClasses['mapClickTracker']= createClickTracker

} //End jzGMap name space uasage

