 
//###########################################################
//### PathMap (and multi path map)			  ###
//###########################################################

with(jzGMap){ //Part of jzGMap
importFrom(jz,'_ jzonStr getElementsByNames')

//$.LogWH = function(elem)  { var s=elem.style;Log('..cw'+elem.clientWidth+' ch='+elem.clientHeight+' for '+elem)}

$.initPathMap = function(elem) { // Initialize the Map
	if (!GBrowserIsCompatible()) return 
	mapDiv=elem
	mapDiv.iframe = mapDiv.getAttribute('jz:iframe',false)
	if ( mapDiv.iframe && elem.style.height=='100%' ) {
		//IE 100% patch ...(jz.IE || jz.KONQ) && 
		//alert('doing height patch ch='+document.body.clientHeight+' oh='+document.body.offsetHeight)
		elem.style.height=document.body.clientHeight+'px'
		}
	
	//if (jz.offsetInfo) alert('offset info='+jz.offsetInfo(mapDiv))
	//else alert(' otop='+mapDiv.offsetTop+' oleft='+mapDiv.offsetLeft+' owidth='+mapDiv.offsetWidth+' oheight='+mapDiv.offsetHeight)
	setTimeout(initPathMapBis,100) // yeild process so browser can display overlay message, jz_scan can finish its work ...
	}

$.initPathMapBis = function() { // Initialize the Map executed after other onloads ...
	
	//jz.addListener(mapDiv,'contextmenu',jz.fn('alert("contect menu on "+self);jz.stopEvt(self)'))
	var id=mapDiv.id
	var mode=mapDiv.getAttribute('jz:InputMode') 
	mapDiv.inputMode=mode
	mapDiv.home = mapDiv.getAttribute('jz:home','')

	//patch TODO: revoir tout ca ...
	var jzhreftarget = mapDiv.getAttribute('jz:hrefcible','')
	if (jzhreftarget){
	    var pos= jzhreftarget.indexOf(',')
	    if (pos<0) pos= jzhreftarget.length
	    jzhreftarget=[jzhreftarget.substring(0,pos),jzhreftarget.substring(pos+1)]
	    }
	//alert('jzhreftarget='+jzhreftarget)
	mapDiv.jzhreftarget= jzhreftarget
	
	
	var ops= {}
	if (mode) ops={draggableCursor:'default', draggingCursor:'default'}
	
	var types= mapDiv.getAttribute('jz:maptypes')
	if (types) ops['mapTypes']= mapf(types.split(' '), function(tName){ return window['G_'+tName.toUpperCase()+'_MAP'] || 0 })

	var vMap =newMap(mapDiv,ops)
	mapDiv.vMap=vMap
	//vMap.enableContinuousZoom()
	//vMap.enableScrollWheelZoom()
	//vMap.enableDoubleClickZoom()
	//alert('hi')

	mapDiv.lang = mapDiv.getAttribute('jz:lang') || 'fr' 

	var name=id.slice(0,id.lastIndexOf('.')) //remove ._map
	//var formname=name.slice(0,name.lastIndexOf('.')) //remove 

	var controls=mapDiv.getAttribute('jz:mapcontrols'), overview=false
	if (!controls) controls='GLargeMap GMapType GScale GOverviewMap Logo'
	if (mapDiv.getAttribute('jz:router') && controls.indexOf('Directions')==-1) //auto add dicontrol
		controls+= ' Directions'
	vMap.jzControls={}
	dof(controls.split(' '), function(cName){ 
		//if (cName=='OverviewMap') return overview=true
		var name=cName+'Control'
		var ctl = (jzGMap && jzGMap[name]) || window[name]
		if (ctl) {
			var ictl= new ctl()
			vMap.addControl(ictl)
			vMap.jzControls[cName]= ictl
			}
		})
	var elem	
//	if (elem=document.getElementById(formname+'.id')) mapDiv.id=elem.value
//	else mapDiv.id=false
//	if (elem=document.getElementById(name+'._debuginfo')) mapDiv.debug=elem

	var pos=false


	if (mapDiv.id && !mapDiv.getAttribute('jz:nopos')) {
		if (mapDiv.getAttribute('jz:id')) pos=getPositionCookie(mapDiv.getAttribute('jz:id'))
		else pos=getPositionCookie(mapDiv.id)
		}
	if (!pos) { //try static pos
		var zm=mapDiv.getAttribute('jz:zoom')
		if (zm) zm=parseInt(zm)

		var lat=mapDiv.getAttribute('jz:lat')
		if (lat) lat=parseFloat(lat)

		var lng=mapDiv.getAttribute('jz:lng')
		if (lng) lng=parseFloat(lng)
		
		if (zm && lat && lng) pos=[lat,lng,zm]
		}

	if (pos) vMap.setCenter(newLatLng(pos[0],pos[1]),pos[2])
	else vMap.setCenter(newLatLng(46,-71),zm?zm:6)
	
	// retreve infoview html
	if (elem=document.getElementById(name+'._infoview')) {
		mapDiv.infoWindow=elem.parentNode.removeChild(elem)
		mapDiv.infoWindow.className='' // remove hidden class
		}
	else mapDiv.infoWindow=false

	//Update edit controls
	if (elem=document.getElementById(name+'._autoscroll')) mapDiv._autoscroll=elem
	mapDiv.autoscroll=function(){return mapDiv._autoscroll && mapDiv._autoscroll.checked}
	//if (elem=document.getElementById(name+'._inputMode')) mapDiv._inputMode=elem
	//mapDiv.inputMode=function(){return mapDiv._inputMode && mapDiv._inputMode.checked}

	if (elem=document.getElementById(name+'._showmarkers')) {
		mapDiv._showmarkers=elem
		jz.addListener(elem,'click',function(){ doMoveEnd(mapDiv,'force') })
		}
	mapDiv.showmarkers=function(){return mapDiv._showmarkers && mapDiv._showmarkers.checked}
	
	//LogObj(filtre)

	if (elem=document.getElementById(name+'._showattraits')) {
		mapDiv._showattraits=elem
		jz.addListener(elem,'click',function(){ doMoveEnd(mapDiv,'force') })
		//Log('show attraits checked = '+elem.checked+' value ='+elem.value)
		}
	mapDiv.showattraits=function(){return mapDiv._showattraits && mapDiv._showattraits.checked}
	//Log('show attraits is '+mapDiv.showattraits()+' CHECKED='+mapDiv._showattraits.checked)



	var infomode= mapDiv.getAttribute('jz:infomode')
	if (!infomode || infomode =='*' ) infomode= 'txt,type'
	if (infomode == '!') infomode= ''
	infomode=','+infomode.toLowerCase()+','
	pathinfotxt=  1+infomode.indexOf(',txt,') //true if present if not false (0)
	pathinfotype= 1+infomode.indexOf(',type,') //idem

	var data
	if (elem=document.getElementById(name+'._data')) {
		data=eval(elem.value)
		mapDiv._data=elem
		makeOvlSQ=function(){return newMarker(this,SquareMarkerInfo)}
	
		var points=mapDiv.points=new MultiSegment()
		points.maxSegSize=256
		points.updateAdded=updatePtAdd
		points.updateRemoved=updatePtRemove
		points.updateSegment=updateSegment
		var maps=mapf(data, function(pt,id){
			var gpoint=newLatLng(pt[0],pt[1])
			gpoint.id=id
			if (pt[2]) gpoint.txt=pt[2]
			if (pt[3]) gpoint.type=pt[3]
			gpoint.makeOvl=makeOvlSQ
			return gpoint
			})
		append(points,maps)
		if (!pos) autoZoom(zm)
		} 

	//var mask = jzTileOverlay([43., -70., 49., -67.],'/Members/gd/mask','copy right x y z',0.4)
	//vMap.addOverlay(mask)
	initHover(mapDiv)
	initOverlays(mapDiv)

	if (!data && !pos) { // auto zoom if no base path
		var bounds
		if (mapDiv.paths) bounds=newBounds(mapDiv.paths)
		if (bounds && !bounds.isEmpty()){
			var zoomLevel=zm?zm:Math.max(3,vMap.getBoundsZoomLevel(bounds))
			vMap.setCenter(bounds.getCenter(),zoomLevel)
			}
		}
	
	//############### Event listeners ########################
	// triggers moveend GEvent.addListener(vMap,'resize',function(){autoZoom();updateMarkers('resize')})
	// triggers moveend GEvent.addListener(vMap,'zoomend',function(){updateMarkers('zoomend')})

	mapDiv.jzClick= window.jz[mapDiv.getAttribute('jz:click')] || doPathMapClick
	if (mapDiv.jzClick) GEvent.addListener(vMap,'click', mapDiv.jzClick)
	GEvent.addListener(vMap,'dblclick',function(){}) //do nothing
	//GEvent.addListener(vMap,'dblclick',function(){alert('dblclick on map')})
	//GEvent.addListener(vMap,'contextmenu',function(){alert('contextmenu on map')})
	if (mapDiv.inputMode) {
		var tag=jz.getParentByTagName(mapDiv,'FORM')
		jz.addListener(tag,'submit',doPathPrepareData)
		jz.addListener(tag,'submit',function(){jz.warnUnload=false})
		}
	//mapDiv.jzGetParentByTagNAme('FORM').jzAddListener('submit',doPathPrepareData)
	//alert('doing clear')

	//alert('before shows')
	var route= mapDiv.getAttribute('jz:router')
	if (route){
		var target= mapDiv.getAttribute('jz:target')
		if (target){
			var ta= mapf(target.split(','),parseFloat)
			if (isNaN(ta[0]) || isNaN(ta[1]))
				 target= false
			else target= new GLatLng(ta[0],ta[1])
			}
		var routecls= jzGMap[route]
		var dirctrl= getId('DirectionsControl')
		var offsetTop= 100
		if (dirctrl) offsetTop+=dirctrl.offsetHeight
		if (routecls) vMap.router= routecls(vMap,{network:route, offset:[90,offsetTop], target:target}) // a doite offset:[-35,80], left of logo [240,45]
		else vMap.router= Router(vMap,{network:route, offset:[90,offsetTop], target:target})
		// init ctrl de directions
/*		var dirctrl= getId('DirectionsControl')
		if (dirctrl){
			var checked= getId('DirectionsControl.check').checked
			jzGMap.dodirectionscontrolchange(dirctrl,checked,'pathmap')
			}*/
		}

	doMoveEnd(mapDiv,'force')

	if (mapDiv.om) mapDiv.om.Clear()

	}


$.panAndZoomTo = function(dest,zoom){
	var map=mapDiv.vMap
	if (dest instanceof GLatLngBounds){
		if (zoom === undefined) zoom=map.getBoundsZoomLevel(dest)
		dest=dest.getCenter()
		}
	else { if (zoom=== undefined) zoom=10 }
	var cCenter=map.getCenter(), cZoom=map.getZoom()
	var zoomDif=zoom-cZoom
	if (zoomDif>0) { while (zoomDif-->0) map.zoomIn(dest,true,true) }
	else           { while (zoomDif++<0) map.zoomOut(dest,true,true) }
	map.panTo(dest) //Just pan and return
	}
jz.DomClasses['PathMap2']    = initPathMap
jz.DomClasses['PathMap']     = initPathMap
jz.DomClasses['MultiPathMap']= initPathMap

$.makeOvlSQ=function(){return newMarker(this,SquareMarkerInfo)}

$.autoZoom = function(zm) {
	if (!mapDiv || !mapDiv.points || !mapDiv.vMap || mapDiv.points.length<2) return
	// todo: case len=1
	var bounds=newBounds(mapDiv.points)
	var zoomLevel=zm?zm:mapDiv.vMap.getBoundsZoomLevel(bounds)
	mapDiv.vMap.setCenter(bounds.getCenter(),zoomLevel)
	return
	}


//##########################################################
//### Segemt control methods

$.retTrue = function()  { return true }
$.retFalse = function() { return false }


$.pathinfotxt= false	
$.pathinfotype= true

$.updatePtAdd = function(pts) {
	dof(pts, function(newGP){
		var newM=false
		if ( ( newGP.txt && pathinfotxt )  || ( newGP.type && pathinfotype) ) {//special marker
			//alert('creating a '+newGP.txt+' or '+newGP.type)
			newM=newMarker(newGP, WaypointMarkerBase({
				dragend:mapDiv.inputMode?doUpdateLatLng:false,
				click:doMarkerClick
				/*, debug:newGP.id||'marker'*/}))
			newGP.removeable=retFalse
			}
		else if ( mapDiv.inputMode &&  mapDiv.showmarkers() && mapDiv.bounds && mapDiv.bounds.contains(newGP) ) {
			newM=newMarker(newGP,SquareMarkerInfo/*.clone({ debug:newGP.id||'marker'}) */)
			}
		
		if (newM) {
			newM.forObj=newGP
			//if (newGP.marker) alert('marker overrun on '+newGP.id)
			newGP.overlay=newM
			mapDiv.vMap.addOverlay(newM)
			//if (mapDiv.inputMode) newM.enableDragging()
			}
		} )
	}


$.updatePtRemove = function(pts) {
	dof(pts, function(oldGP){
		if (oldGP.overlay) {
			mapDiv.vMap.removeOverlay(oldGP.overlay)
			oldGP.overlay.forObj=false
			oldGP.overlay=false
			}
		})
	}


$.updateSegment = function(seg) {
	//alert('in update for '+mapDiv.id+' points='+mapDiv.points)
	var vMap=mapDiv.vMap,segments=this.segments
	// Update end marker ?
	if ( seg==last(segments)) { // last segement update end marker, recenter (maybe)
		if (mapDiv.endMarker) {vMap.removeOverlay(mapDiv.endMarker);  mapDiv.endMarker.forObj=false; mapDiv.endMarker=false }
		if (this.length>1) {
			mapDiv.endMarker=newMarker(last(seg),EndMarkerBase({
				dragend:mapDiv.inputMode?doUpdateLatLng:false}))
			mapDiv.endMarker.forObj=last(seg)
			vMap.addOverlay(mapDiv.endMarker)
			}
		}
	// Update start marker ?
	if ( seg==segments[0]) { // first sgement update start marker
		if (mapDiv.startMarker) { vMap.removeOverlay(mapDiv.startMarker); mapDiv.startMarker=false }
		if (this.length>0) {
			mapDiv.startMarker=newMarker(seg[0],StartMarkerBase({
				dragend:mapDiv.inputMode?doUpdateLatLng:false}))
			mapDiv.startMarker.forObj=seg[0]
			vMap.addOverlay(mapDiv.startMarker)
			}
		}
	
	//update segment polyline
	if (seg.path) { vMap.removeOverlay(seg.path); seg.path=false}
	if (seg.paths) { dof(seg.paths, function(path){vMap.removeOverlay(seg.path)}); seg.paths=false}
	if (seg.length>1) {
		var lineStyle=this.getStyle(seg)
		if (lineStyle && lineStyle.length) {
			seg.paths=mapf(lineStyle, function(style){ return newPolyline(seg,style)})
			dof(seg.paths, function(path){vMap.addOverlay(path)})
			}
		else {
			vMap.addOverlay(seg.path=newPolyline(seg,(lineStyle && lineStyle.length)?lineStyle[0]:lineStyle))
			}
		}
	
	}

//###########################################################
//### PathMap Events (doX methods) and support functions  ###

$.addSQMarker = function(pt) { return newMarker(newLatLng(pt.lat(),pt.lng()),SquareMarkerInfo) }

$.doPathMapClick = function(overlay,point) {
	if (!mapDiv) return

	//# Is this beacuse polygone overlays dont get the click ? check if rect does
	if (overlay && overlay.href && !mapDiv.inputMode) return //doNavigate(overlay,point)
	if (overlay) return //#Let overlay take care of it itself
	if (!point) return 
	if (mapDiv.inputMode) {
		jz.warnUnload = _('Changements non sauvegargé')
		point.id = mapDiv.points.length
		point.makeOvl = makeOvlSQ
		point.intersects = intersects
		mapDiv.points.push(point)
		if (mapDiv.points._distances) mapDiv.points._distances = false
		if (mapDiv.autoscroll()) mapDiv.vMap.panTo(point)
		}
	//else mapDiv.vMap.panTo(point)
	}

$.doPathPrepareData = function() {
	if (!mapDiv._data) return true
	var res=[]
	dof(mapDiv.points.segments, function(seg,si){//alert('doing seg '+si);
		dof(seg, function(pt,i){ 
		if (i>0||si==0) { // skip over first elements except in first vector
			var vect=[pt.lat(),pt.lng()]
			if (pt.txt) vect[2]=pt.txt
			if (pt.type) vect[3]=pt.type
			res.push(vect)
			}
		})})
	var jzonstr=jzonStr(res)
	mapDiv._data.value=jzonstr
	return true
	}

//#############################################################
//### PathMap Marker and Overlay Events + support functions ###

$.doUpdateLatLng = function() { // Call Back for dragend event on a at lat lng marker
	//Log('in update kat kng')
	var marker=this
	if (!marker.forObj) return 
	var pathPt=marker.forObj, nwPathPt=marker.getPoint()
	var dist=nwPathPt.distanceFrom(pathPt)
	//Log('drag distance='+dist)
	if (dist<2) { //cancel drag
		marker.setPoint(pathPt)
		//Log('drag canceled')
		return
		}
	
	// Path point is a GLatLng, this class cant update lat n lng so must recreate
	nwPathPt.id	= pathPt.id
	nwPathPt.txt	= pathPt.txt
	nwPathPt.type	= pathPt.type
	nwPathPt.makeOvl = pathPt.makeOvl
	nwPathPt.intersects = pathPt.intersects

	marker.forObj=nwPathPt
	if (pathPt.overlay) {
		nwPathPt.overlay=pathPt.overlay
		if (marker!==pathPt.overlay) {
			// should be square but this could be start or end ...
			marker.forObj=nwPathPt
			marker.setPoint(nwPathPt)
			}
		}
	mapDiv.points.put(pathPt.id,nwPathPt)
	mapDiv.points._distances = false //clear distance cache
	//Log('end update kat kng')
	return
	}

//Marker hover functions
$.doHoverTxt = function(){ //this is overlay
	var waypoint=this.forObj, ret='', id=waypoint.id
	var d=distance(mapDiv.points,waypoint.id), dt=distance(mapDiv.points)
	if (this.title) ret=this.title
	else ret=_('Repère')
	if (mapDiv.inputMode) ret+=' point # '+id
	if (waypoint.txt) ret+='<br />'+waypoint.txt
	if (waypoint.type) ret+='<br /> '+_('début')+' '+typeTitre(waypoint)
	ret+=_('<br /> $before parcourus, $after à parcourir',{before:unittxtk(d), after:unittxtk(dt-d)})
	return ret
	}

$.doMarkerClick = function() {
	if (!mapDiv.inputMode) return
	var overlay=this
	var vMap=mapDiv.vMap
	if (!vMap) return
	var pathPoint=overlay.forObj
	if (!pathPoint|| !mapDiv.infoWindow) return
	var infoWindow=mapDiv.infoWindow.cloneNode(true)
	infoWindow.id="" // avoid 2 nodes with same id
	//var name=mapDiv.id.slice(0,-5) //remove .map
	//var nameW=name+'.waypoint._d.' //name to waypoint object attributes
	var elem
	//update the infowindow form

	jz.setChildContent(infoWindow,'pos',pathPoint.id)
	jz.setChildContent(infoWindow,'lat',pathPoint.x.toFixed(6))
	jz.setChildContent(infoWindow,'lng',pathPoint.y.toFixed(6))
	jz.setChildContent(infoWindow,'nom',pathPoint.txt||'',true)
	jz.setChildContent(infoWindow,'type',pathPoint.type||'noType')

	if (elem=jz.getElementsByNames(infoWindow,'container')) {
		overlay.infoWindow=elem[0] //overaly infowindow is contained element becuase that element 'ref' does not change .....
		}
	//overlay.openInfoWindow(infoWindow) //pass container becuase its 'ref' changes after append ...
	overlay.openInfoWindow(infoWindow)
	if (mapDiv.inputMode) GEvent.addListener(overlay,'infowindowclose',doMarkerInfowindowClose)
	}


$.doMarkerInfowindowClose = function(overlay,point) {
	//alert('got map click on '+mapDiv+' at: '+point)
	if (!mapDiv.inputMode) return
	var vMap=mapDiv.vMap
	if (!vMap||!overlay||!overlay.infoWindow ) return
	var pathPoint
	if (!(pathPoint=overlay.forObj)) return
	var infoWindow=overlay.infoWindow
	overlay.infoWindow=false
	//var name=mapDiv.id.slice(0,-5) //remove .map
	//var nameW=name+'.waypoint.'+mapDiv.id+'.' //name to waypoint object attributes
	var elem,changed=false
	// update nom  and change marker 
	if (elem=getElementsByNames(infoWindow,'nom')) {
		var value=elem[0].value||''
		if ((pathPoint.txt||'')!=value) {// value has changed change
			changed=true
			if (value=='') delete pathPoint.txt
			else pathPoint.txt = value 
			}
		}
	//update type
	if (elem=getElementsByNames(infoWindow,'type')) {
		var value=elem[0].value||''
		if ((pathPoint.type||'')!=value) {// value has changed change
			changed=true
			if (value==='') {
				delete pathPoint.type
				//alert('xdoing a update for id '+pathPoint.id+' at seg '+pos)
				}
			else {
				pathPoint.type = value
				//3alert('xdoing a split at '+pathPoint.id)
				mapDiv.points._splitAt(pathPoint.id)
				}
			var pos=mapDiv.points._convertIdx(pathPoint.id)[0]
			mapDiv.points.updateSegmentList(pos)
			}
		}
	if (changed){
		updatePtRemove([pathPoint])
		updatePtAdd([pathPoint])
		}
	}

$.doRemoveLastPoint = function() {
	if (!mapDiv.points || mapDiv.points.length==0) return
	mapDiv.points.pop()
	if (mapDiv.points._distances) mapDiv.points._distances.pop()
	if (mapDiv.autoscroll() && last(mapDiv.points))  mapDiv.vMap.panTo(last(mapDiv.points))
	}


//###########################################
//### Marker Bases

$.MarkerBase=Class({
	hoverContent:doHoverTxt,
	click:doMarkerClick,
	dblclick:doMarkerClick
	})

$.WaypointMarkerBase	= Class(MarkerBase, { icon:WaypointIcon })
$.SquareMarkerBase	= Class(MarkerBase, { icon:SquareIcon,
	dragstart : hideHover,
	dragend   : doUpdateLatLng,
	mouseover : function(){this.setImage('/static/icon/yellowsq.gif')},
	mouseout  : function(){this.setImage('/static/icon/required.gif')},
	jz_doRemoved  : function(){
		GEvent.clearInstanceListeners(this)
		this.jz_doRemoved = false //release closure 
		}
	})
//Just to be consitante
$.SquareMarkerInfo = SquareMarkerBase()
$.EndMarkerBase		= Class(MarkerBase, {
	icon:EndFlag,
	//mouseover: function(){this.setImage('/static/icon/yellow.png')},
	//mouseout : function(){this.setImage('/static/icon/stop.png')},
	title	 : _('fin piste')
	})
$.StartMarkerBase	= Class(MarkerBase, { icon:StartFlag, title:_('debut piste') })

}//End jzGMap name space

