B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=12.2
@EndOfDesignText@
Sub Class_Globals
	Private Root As B4XView 'ignore
	Private xui As XUI 'ignore
	Dim q_buscar As String
'	Dim skmt As SQL
	Dim entro As String
	Dim c As Cursor
	Dim c2 As Cursor
	Dim ListView1 As ListView
'	Dim gest As Button
	Dim lfila As Label
	Dim busca As EditText
	Private p_colonia As Panel
'	Dim distList As List
'	Dim distMap As Map
	Dim laRuta As String
	Private b_GetDirs As Button
	Private distOrderedMap, clientesMapaO As B4XOrderedMap
	Private img_getDirs As ImageView
	Private l_rutaInfo As Label
	Private b_getRutaInfo As Button
	Private conMapa As Boolean = False
	Dim listaWayPoints As List
	Dim lv1Top As String
	Private b_limpiarRuta As Button
	Dim rutaGenerada As Boolean = False
	Dim rutaacambiar As String
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
	Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
	Root = Root1
	'load the layout to Root
	Root.LoadLayout("clientes")
	entro ="2"
	lv1Top = ListView1.Top
	clientesMapaO.Initialize
	Starter.skmt.ExecNonQuery("delete from waypoints")
	Log("Coordenadas del almacen: " & Starter.cedisLocation.Longitude & "," & Starter.cedisLocation.Latitude)
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Sub B4XPage_Appear
	busca.Text = ""
	b_GetDirs.Visible = False
'	skmt.Initialize(Starter.ruta,"kmt.db", True)
	entro ="2"
	' esto es para rutas se quito por colonia
	'SE COMENTA EL SIGUIENTE CODIGO PARA QUE TODAS LAS TIENDAS APAREZCAN.
	'c=skmt.ExecQuery("select CAT_CL_COLONIA, count(*) as cuantos from kmt_info where gestion = 0 group by CAT_CL_COLONIA order by CAT_CL_COLONIA asc")
	p_colonia.Width = Root.Width
	p_colonia.Height = Root.Height
	p_colonia.Top = 0
	p_colonia.Left = 0
	Subs.centraListView(ListView1, p_colonia.Width)
	ListView1.Height = p_colonia.Height * 0.75
	Subs.SetDivider(ListView1, Colors.LightGray, 2)
	If Not(l_rutaInfo.Visible) Then
		ListView1.Top = lv1Top
	Else
		ListView1.Top = lv1Top + 100
	End If
	c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
	If c.RowCount > 0 Then 'Ya hay waypoints en la base de datos
		c.Position = 0
'		Log("Ya hay waypoints.")
		conMapa = True
'		Private t1 As Map
		ListView1.Clear
		Dim cs, cs2 As CSBuilder
		entro = 3
'		Log("Generamos ListView1 en Activity_Resume")
		For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
			c.Position=i
			cs.Initialize
			cs2.Initialize
'			t1 = Starter.waypointsOrdered.Get(k)
'			c.GetString("codigo")
'			Log(c.GetString("indice"))
			ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
		Next
	Else
		generaListViewRutas
	End If
	c.Close
	p_colonia.Width = Root.Width
	p_colonia.Height = Root.Height
	Subs.centraEtiqueta(l_rutaInfo, Root.Width)
	Subs.centraListView(ListView1, p_colonia.Width)
	ListView1.Height = p_colonia.Height * 0.70
	Subs.centraEtiqueta(lfila, Root.Width)
	b_getRutaInfo.Visible = True
	b_getRutaInfo.BringToFront
	If Starter.cedisLocation.Latitude = "0" Then
		Private x As Cursor = Starter.skmt.ExecQuery("select * from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'COORDS_ALMACEN'")
		If x.RowCount > 0 Then
			x.Position = 0
			Private y() As String
			Starter.cedisLocation.Latitude = Regex.Split(",", x.GetString("CAT_VA_VALOR"))(1)
			Starter.cedisLocation.Longitude = Regex.Split(",", x.GetString("CAT_VA_VALOR"))(0)
		End If
	End If
	Log(Starter.cedisLocation)
End Sub


Private Sub B4XPage_CloseRequest As ResumableSub
	' BACK key pressed
	'Return True to close, False to cancel
	Log(entro)
	If rutaGenerada Or entro = 3 Then ' Si ya generamos el ruteo o entramos a una de las rutas, nos regresamos!
		b_limpiarRuta_Click
		l_rutaInfo.Text = ""
		rutaGenerada = False
	else if entro = 2 Then ' Si estamos mostrando las rutas, nos regresamos a la principal.
		B4XPages.ShowPage("Principal")
	End If
	Return False
End Sub

Sub ListView1_ItemClick (Position As Int, Value As Object)
'	Log($"Entro= ${entro}"$)
	Log(Value)
	ListView1.Clear
	Sleep(50)
	Subs.SetDivider(ListView1, Colors.LightGray, 2)
	If Not(l_rutaInfo.Visible) Then
		ListView1.Top = lv1Top
	Else
		ListView1.Top = lv1Top + 100
	End If
	l_rutaInfo.Visible = False
	b_GetDirs.Visible = False
	If entro = "2" Then
'		b_GetDirs.Visible = True
'		img_getDirs.Visible = True
'		b_getRutaInfo.Visible = False
		Private lrt As String
		lrt = Value
		laRuta = lrt.SubString(6) 'Quitamos el texto "Ruta: " para obtener el numero de la ruta.
		Log($"Original: ${Value} - Mod: |${lrt.SubString(6)}| - laRuta: ${laRuta}"$)
		rutaacambiar = laRuta
		c2 = Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_NOMBRE ", Array As String(laRuta))
		Private thisLoc As Location
		Private label1 As Label
		Private label2 As Label
		label1 = ListView1.TwoLinesLayout.Label
		label1.TextSize = 15
		label1.TextColor = Colors.black
		label2 = ListView1.TwoLinesLayout.SecondLabel
		label2.TextSize = 15
		label2.TextColor = Colors.black
		label2.Height = 57dip
		thisLoc.Initialize
		If entro = 2 Then ListView1.TwoLinesLayout.ItemHeight = 90dip
		lfila.text = "Nombre y Calle"
		distOrderedMap.Initialize
		If c2.RowCount > 0 Then
			For i = 0 To c2.RowCount -1 'Generamos mapa de clientes
				c2.Position = i
				thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
				thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
'				Log(Tracker.UUGCoords)
				Private distancia As Int = Tracker.UUGCoords.DistanceTo(thisLoc) 'Calculamos la distancia de la posicion ACTUAL a la tienda.
				Private esteCliente As Map = CreateMap("distancia": distancia, "ubicacion": thisLoc.Longitude&","&thisLoc.Latitude, "codigo": c2.GetString("CAT_CL_CODIGO"), "nomDirDist": $"${c2.GetString("CAT_CL_NOMBRE")} CALLE: ${c2.GetString("CAT_CL_CALLE")} ${CRLF}Distancia: $1.1{(distancia/1000)} kms"$)
				distOrderedMap.Put(distancia, esteCliente)
			Next
			distOrderedMap.Keys.Sort(True) 'Ordenamos la mapa de clientes por distancia.
			ListView1.Clear
			Private m1 As Map
			For Each k As Object In distOrderedMap.Keys  'Generamos el listView con el mapa ordenada.
				m1 = distOrderedMap.Get(k)
				m1.Get("codigo")
'				Log(m1.Get("nomDirDist"))
				ListView1.AddTwoLines(m1.Get("codigo"), m1.Get("nomDirDist"))
			Next
		End If
		c2.Close
		entro = "3"
	Else If entro = "3" Then
'		LogColor("Guardamos CLIENTE " & Value, Colors.red)
		Starter.skmt.ExecNonQuery("delete from CUENTAA")
		Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
		B4XPages.ShowPage("Cliente")
	End If
End Sub

'Genera el listview que muestra las rutas y clientes a visitar por ruta.
Sub generaListViewRutas
	ListView1.Clear
	Sleep(110)
	lfila.Text = "RUTA PREVENTA"
	Dim label1 As Label
	label1 = ListView1.TwoLinesLayout.Label
	label1.TextSize = 15
	label1.TextColor = Colors.Black
	Dim label2 As Label
	label2 = ListView1.TwoLinesLayout.SecondLabel
	label2.TextSize = 15
	label2.TextColor = Colors.Black
	ListView1.TwoLinesLayout.ItemHeight = 60dip
	c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0 AND CAT_CL_RUTA <> 1000 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
	If c.RowCount>0 Then
		ListView1.Clear
		For i=0 To c.RowCount -1
			c.Position=i
			ListView1.AddTwoLines("Ruta: " & c.GetString("CAT_CL_RUTA"), "Por visitar:  " & c.GetString("cuantos"))
		Next
	End If
	c.Close
End Sub

Sub Activity_KeyPress (key As Int) As Boolean 'ignore
	' BACK key pressed
	If key=KeyCodes.KEYCODE_BACK Then
		If entro = 3 And Not(conMapa) Then
			b_GetDirs.Visible = False
'			StartActivity(Activity_Create(False))
			B4XPage_Created(Root)
			Return True
		End If
		B4XPages.ShowPage("Principal")
		Return False
		'End If
	End If
	' Returning False signals the system to handle the key
End Sub

Sub BUSCA_TextChanged (Old As String, New As String)
	q_buscar = "%" & busca.Text & "%"
	c2=Starter.skmt.ExecQuery2("select  CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO from kmt_info where CAT_CL_NOMBRE like ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_CODIGO ", Array As String(q_buscar))
	ListView1.Clear
	lfila.text = "Nombre y Calle"
	Subs.SetDivider(ListView1, Colors.LightGray, 2)
	If c2.RowCount>0 Then
		For i=0 To c2.RowCount -1
			c2.Position=i
			Dim label1 As Label
			label1 = ListView1.TwoLinesLayout.Label
			label1.TextSize = 15
			label1.TextColor = Colors.Black
			Dim label2 As Label
			label2 = ListView1.TwoLinesLayout.SecondLabel
			label2.TextSize = 15
			label2.TextColor = Colors.Black
			ListView1.AddTwoLines(c2.GetString("CAT_CL_CODIGO"), c2.GetString("CAT_CL_NOMBRE") &" CALLE:  "& c2.GetString("CAT_CL_CALLE"))
		Next
	End If
	entro = "3"
	c2.Close
End Sub

'Regresa la distancia y tiempo de la ruta entre dos puntos, usa el API del projecto OSRM. (Parte de la funcionalidad OSRM)
'Para mas información ir a esta liga:
'http://project-osrm.org/docs/v5.24.0/api/?language=cURL#route-service
Sub distanciaEntreCoords(id As String, coords1 As String, coords2 As String) As ResumableSub 'ignore
	Sleep(1050)
	Private distanciaTotal As String = "0"
	Private tiempo As String = "0"
	Dim j As HttpJob
	j.Initialize("", Me)
	j.Download("https://router.project-osrm.org/route/v1/driving/"&coords1&";"&coords2&"?overview=false")
	Wait For (j) JobDone(j As HttpJob)
	If j.Success Then
		Dim jp As JSONParser
		jp.Initialize(j.GetString)
		Dim m As Map = jp.NextObject
		Log($"Respuesta: ${m.Get("code")}"$)
		If m.Get("code") = "Ok" Then
'			Log(m)
			Dim rutas As List = m.Get("routes")
			Dim rutas2 As Map = rutas.Get(0)
'			Log(rutas2)
'			Dim legs As List = rutas2.Get("legs")
'			Log(legs)
			distanciaTotal = rutas2.Get("distance")
			tiempo = rutas2.Get("duration")
			Log($"Distancia total: ${distanciaTotal}, Tiempo: ${tiempo}"$ )
		End If
	Else
		Log("Error!")
	End If
	j.Release
	Private r As List
	r.Initialize
	r.Add(id)
	r.Add(distanciaTotal)
	r.Add(tiempo)
	Return r
End Sub

'Regresa la distancia y tiempo estimado de la ruta del repartidor, utiliza el API del projecto OSRM
'para calcular la distancia y tiempo de la ruta de un mapa de coordenadas a visitar dado. (Parte de la funcionalidad OSRM)
Sub traeRutaDia(aVisitar As B4XOrderedMap)
	Private coordsInicio As String = $"${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$
	Log($"Coordenadas de inicio: ${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$)
	Private rutaCompleta As String = coordsInicio
	Private preRuta As String = coordsInicio
	Private distanciaTotal, distanciaTotal0, tiempo0,  tiempo As Double
	Private masDe100 As Boolean
	Private m4 As Map
	Private visitaActual As Int = 0
	Private cuantosAntes As Int = 0
	listaWayPoints.Initialize
	If aVisitar.Keys.Size > 98 Then 'Si los clientes a visitar son mas de 100 entonces hacemos 2 rutas, una inicial con pocas visitas (las que pasen de 100) y la final con el resto ...
		cuantosAntes = aVisitar.Keys.Size - 98 'Definimos de cuantos clientes va a ser la ruta inicial.
		preRuta = coordsInicio 'Ponemos las coordenadas de inicio (Las del CEDIS).
		rutaCompleta = ""
		masDe100 = True
	End If
	Log($"a visitar: ${aVisitar.Keys.Size}"$)
	For Each k As Object In aVisitar.Keys
		visitaActual = visitaActual + 1
		m4 = aVisitar.Get(k)
'		Log($"visitaActual: ${visitaActual} - cuantosAntes: ${cuantosAntes}"$)
		If visitaActual < cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta inicial las agregamos ...
			preRuta = preRuta & ";" & m4.Get("coords")
'			LogColor($"PreRuta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")}"$, Colors.Magenta)
		End If
		If visitaActual >= cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta final las agregamos ...
			rutaCompleta = rutaCompleta & ";" & m4.Get("coords")
'			LogColor($"RutaCompleta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")} - testRuta Size: ${testRutaCompleta.size}"$, Colors.Green)
		End If
	Next
	rutaCompleta = rutaCompleta & ";" & coordsInicio 'Agregamos las coordenadas del CEDIS al final para que sea viaje ida y vuelta.
'	rutaCompleta = rutaCompleta & ";" & coordsInicio
	If rutaCompleta.StartsWith(";") Then rutaCompleta = rutaCompleta.SubString(1) 'Si las cooredenadas tienen ";" al principio se lo quitamos.
'	LogColor(preRuta, Colors.magenta)
'	LogColor(rutaCompleta, Colors.Green)
	ProgressDialogShow2("Calculando distancia y tiempo, un momento por favor.", False)
	Private tiempoVisitas As Double 'TIMEPO DE 4 MINUTOS PROMEDIO POR TIENDA ESTO SE CAMBIA SEGUN EL CLIENTE
	tiempoVisitas = aVisitar.Keys.Size * 4 * 60 'Aqui se calcula el tiempo que duran las visitas x 4 mins cada una en segundos.
	tiempo0 = 0
	distanciaTotal0 = 0
	If masDe100 Then 'Si son mas de 100, entonces primero calculamos la ruta inicial.
		Dim j0 As HttpJob
		j0.Initialize("trip0", Me)
		j0.Download("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
'		LogColor("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Magenta)
		Wait For (j0) JobDone(j0 As HttpJob)
		If j0.Success Then
			Dim jp0 As JSONParser
			jp0.Initialize(j0.GetString)
			Dim m0 As Map = jp0.NextObject
			If m0.Get("code") = "Ok" Then
				Dim puntos0 As List = m0.Get("waypoints")
				Private esteWayPoint0 As Map
				For p = 0 To puntos0.Size -1
					esteWayPoint0 = puntos0.Get(p)
'					LogColor("WP:" & esteWayPoint0, Colors.magenta)
'					LogColor("WP: " & esteWayPoint0.Get("waypoint_index") & ", loc: " & esteWayPoint0.Get("location") & ", name: " & esteWayPoint0.Get("name"), Colors.Magenta)
					esteWayPoint0.Remove("hint")
					esteWayPoint0.Remove("distance")
					esteWayPoint0.Remove("trips_index")
					listaWayPoints.Add(esteWayPoint0)
'					LogColor("estewaypoint: "&esteWayPoint0, Colors.Magenta)
				Next
				Dim rutas0 As List = m0.Get("trips")
				Dim rutas20 As Map = rutas0.Get(0)
'				Dim geometry0 As Map = rutas20.Get("geometry")
'				Private coords0 As List = geometry0.Get("coordinates")
				distanciaTotal0 = rutas20.Get("distance")
				tiempo0 = rutas20.Get("duration")
				tiempo0 = ((tiempo0 * 2) ) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico).
				Log($"Distancia total ruta inicial: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60} mins. ($1.1{tiempo0/60/60} hrs)"$)
'				l_rutaInfo.Text = $"Distancia total: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60/60} hrs"$
			End If
		Else
			Log("Error!")
		End If
		j0.Release
	End If
	
	Dim j As HttpJob
	j.Initialize("trip", Me) 'Calculamos el resto de la ruta.
	j.Download("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
'	LogColor("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Green)
	Wait For (j) JobDone(j As HttpJob)
	If j.Success Then
		Dim jp As JSONParser
		jp.Initialize(j.GetString)
		Dim m As Map = jp.NextObject
		If m.Get("code") = "Ok" Then
			Dim puntos As List = m.Get("waypoints")
			Private esteWayPoint As Map
			Dim twpi As Int
			For p = 0 To puntos.Size -1
				esteWayPoint = puntos.Get(p)
'				LogColor("WP:" & esteWayPoint, Colors.green)
'				LogColor("WP: " & esteWayPoint.Get("waypoint_index") & ", loc: " & esteWayPoint.Get("location") & ", name: " & esteWayPoint.Get("name"), Colors.Green)
				esteWayPoint.Remove("hint")
				esteWayPoint.Remove("distance")
				esteWayPoint.Remove("trips_index")
				twpi = esteWayPoint.Get("waypoint_index")
				esteWayPoint.Remove("waypoint_index")
				esteWayPoint.Put("waypoint_index", (twpi + cuantosAntes + 2))
				listaWayPoints.Add(esteWayPoint)
'				LogColor("estewaypoint: "&esteWayPoint, Colors.Green)
			Next
			Dim rutas As List = m.Get("trips")
			Dim rutas2 As Map = rutas.Get(0)
			distanciaTotal = rutas2.Get("distance")
			Log("distancia ruta 2:" & (distanciaTotal) & "|" & rutas2.Get("distance"))
			distanciaTotal = distanciaTotal + distanciaTotal0
			tiempo = rutas2.Get("duration")
			tiempo = (((tiempo + tiempo0) * 2) + tiempoVisitas) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico) + tiempoVisitas.
			Log($"Distancia total: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60} mins. ($1.1{tiempo/60/60} hrs)"$)
			l_rutaInfo.Text = $"Distancia: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60/60} hrs${CRLF}Visitas restantes: ${aVisitar.Keys.Size}"$
			l_rutaInfo.Width = Root.Width * 0.9
			Subs.centraEtiqueta(l_rutaInfo, Root.Width)
			l_rutaInfo.Visible = True
			l_rutaInfo.BringToFront
			ListView1.Top = lv1Top + 100
		End If
	Else
		LogColor("****************  Error!  ******************", Colors.red)
	End If
	j.Release
	ProgressDialogHide
'	LogColor("clientesMapaO size: " & clientesMapaO.Size & "|" & listaWayPoints.Size, Colors.Blue)
	Private r As Int = 1
	Private r1, wps As Map
	Starter.skmt.ExecNonQuery("delete from waypoints")
	Log("BORRAMOS WAYPOINTS")
	For Each k As Object In clientesMapaO.Keys 'Guardamos en la BD el orden de los waypoints para luego generar el listview.
		If listaWayPoints.Size > 0 Then
			r1 = clientesMapaO.Get(k)
			r1.Get("codigo")
			Log(listaWayPoints.Get(r) & "|" & r1.Get("coords") & "|" & r1.Get("calle"))
			wps = listaWayPoints.Get(r)
			Starter.skmt.ExecNonQuery($"update kmt_info set SECUENCIA = ${wps.get("waypoint_index")} where CAT_CL_CODIGO = '${r1.Get("codigo")}'"$)
			Starter.skmt.ExecNonQuery2("insert into waypoints values (?,?)", Array As Object(r1.Get("codigo"), wps.get("waypoint_index")))
			r = r + 1
		End If
	Next
	ListView1.Clear
	Sleep(100)
	Dim label2 As Label
	label2 = ListView1.TwoLinesLayout.SecondLabel
	label2.TextSize = 15
	label2.Height = 100dip
	ListView1.TwoLinesLayout.ItemHeight = 70dip
	Dim cs, cs2 As CSBuilder
	entro = 3
	Log("Generamos ListView1 en traeRutaDia")
	'Traemos las visitas restantes ordenadas por el indice de waypoints (este indice nos indica el orden en la ruta calculada).
	c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from  waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
	If c.RowCount > 0 Then
		For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
			c.Position=i
			cs.Initialize
			cs2.Initialize
			ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
		Next
	End If
	c.Close
End Sub

'Calcula distancia y tiempo de la ubicacion ACTUAL a las 8 primeras tiendas de la lista usando el API de OSRM. (Parte de la funcionalidad OSRM)
Private Sub b_GetDirs_Click
	ProgressDialogShow("Calculando distancias y tiempos ...")
	Private m2 As Map
	Private f As Int = 0
	For Each k As Object In distOrderedMap.Keys 'Traemos la distancia y tiempo desde OSRM (2 puntos)
		m2 = distOrderedMap.Get(k)
		Private distancia2 As String = m2.Get("distancia")
		Private thisLoc1 As String = m2.Get("ubicacion")
		Private locActual As String = Tracker.UUGCoords.Longitude&","&Tracker.UUGCoords.Latitude
		If locActual = "0,0" Then 'Si no tenemos ubicacion actual de GPS, buscamos la ultima guardada en la base de datos.
			c = Starter.skmt.ExecQuery("select * from hist_gps")
			If c.RowCount > 0 Then
				c.Position = 0
				locActual = c.GetString("hglon") & "," & c.GetString("hglat")
			End If
			c.Close
		End If
		f = f+1
		If f < 8 Then
			If locActual = "0,0" Then 'Si todavia no tenemos ubicacion actual, entonces avisamos.
				ToastMessageShow("No se pudo obtener la ubicacion actual!!", True)
				f = 8
			End If
			Log($"locActual: ${locActual}, thisLoc1: ${thisLoc1}"$)
			Wait For(distanciaEntreCoords(distancia2, locActual, thisLoc1)) Complete (r As List)
			LogColor($"R: ${r.Get(0)} - ${r.Get(1)} - ${r.Get(2)}"$, Colors.Green)
			Private tId As Int = r.Get(0)
			Private tMap As Map = distOrderedMap.Get(tId)
			LogColor("|" & tId & "| - " &distOrderedMap.Get(tId), Colors.Blue)
			Private tempNDD As String = tMap.Get("nomDirDist")
			Private indexD As Int = tempNDD.IndexOf("Distancia:")
			If indexD > -1 Then tempNDD = tempNDD.SubString2(0, indexD)
			Log(tempNDD)
			tempNDD = tempNDD & $"Dist: $1.1{(r.Get(1)/1000)} kms, Tiempo aprox: $1.0{((r.Get(2)*2)/60)} min."$  'Multiplicamos el tiempo X 2 porque el tiempo estimado siempre es muy corto, X2 es mucho mas real con trafico.
			Private esteCliente As Map = CreateMap("distancia": distancia2, "ubicacion": tMap.Get("ubicacion"), "codigo": tMap.Get("codigo"), "nomDirDist": tempNDD)
			distOrderedMap.Put(tId, esteCliente)
			ListView1.Clear
			Private m3 As Map
			For Each k As Object In distOrderedMap.Keys  'Generamos el listView con la lista ordenada.
				m3 = distOrderedMap.Get(k)
				m3.Get("codigo")
				ListView1.AddTwoLines(m3.Get("codigo"), m3.Get("nomDirDist"))
			Next
		End If
	Next
	ProgressDialogHide
End Sub

'Regresa un mapa (B4XOrderedMap) con todos los clientes que tiene que visitar el repartidor. (Parte de la funcionalidad OSRM)
Sub traeTodosAVisitar As B4XOrderedMap 'ignore
	Log("Iniciamos traeTodosAVisitar")
'	If Starter.waypointsOrdered.isInitialized Then Log(Starter.waypointsOrdered.Size)
'	Private rutaCompleta As String = ""
	Private thisLoc, ubicacionInicial As Location
	ubicacionInicial = Starter.cedisLocation
	LogColor(ubicacionInicial, Colors.Gray)
	c=Starter.skmt.ExecQuery("select sum(gestion) as hayVisitados from kmt_info")
	If c.RowCount > 0 Then
		c.Position = 0
'		Log(c.GetString("hayVisitados"))
		If c.GetString("hayVisitados") > 0 Then ubicacionInicial = Tracker.UUGCoords 'Si ya hay clientes visitados, entonces ya no estamos en el CEDIS y la ubicacion inicial debe de ser la ACTUAL.
	End If
	c.Close
	LogColor(ubicacionInicial, Colors.Red)
	thisLoc.Initialize
	clientesMapaO.Clear
	'Traemos las rutas asignadas al repartidor.
	c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0  AND CAT_CL_RUTA <> 1000 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
	If c.RowCount>0 Then
		'Traemos los clientes de cada ruta.
		For i=0 To c.RowCount -1
			c.Position=i
'			Log($"Renglones ruta: ${c.RowCount} - i=${i} - Ruta: ${c.GetString("CAT_CL_RUTA")}"$)
			c2=Starter.skmt.ExecQuery2("select  CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_NOMBRE ", Array As String(c.GetString("CAT_CL_RUTA")))
			If c2.RowCount>0 Then
				For j=0 To c2.RowCount -1 'Generamos lista de clientes
					c2.Position=j
'					Log($"Renglones clientes: ${c2.RowCount} - j=${j} - Ruta: ${c2.GetString("CAT_CL_CODIGO")}"$)
					thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
					thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
					If Not(thisLoc.Latitude = 0.0) And Not(thisLoc.Latitude = 0) Then 'Este IF es para que si las coordenadas no son válidas, entonces no las agregue al mapeo, porque el API de OSRM nos manda error.
						Private distancia As Int = ubicacionInicial.DistanceTo(thisLoc) 'Calculamos la distancia del cedis a la tienda.
						If clientesMapaO.ContainsKey(distancia) Then distancia = distancia + 1 'Si por alguna extraña razon hay dos tiendas a la misma distancia del CEDIS, le sumamos 1 para que sea diferente.
						Private esteCliente As Map = CreateMap("distancia": distancia, "ordenDist": j, "coords": c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT"), "codigo": c2.GetString("CAT_CL_CODIGO"), "nombre": c2.GetString("CAT_CL_NOMBRE"), "calle": c2.GetString("CAT_CL_CALLE"))
						clientesMapaO.Put(distancia, esteCliente)
					Else
						ToastMessageShow("Hay tiendas SIN coordenadas, fueron excluidas!!", False)
					End If
'					Log($"${thisLoc}"$)
'					rutaCompleta = rutaCompleta & ";" & c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT")
				Next
			End If
		Next
	End If
	clientesMapaO.Keys.Sort(True) 'Ordenamos la lista de clientes por distancia.
	c.Close
	c2.Close
	Log(c.RowCount & " rutas, " & clientesMapaO.Size & " clientes")
'	LogColor(rutaCompleta, Colors.Magenta)
'	Log(clientesMapaO)
	Return clientesMapaO
End Sub

'Traemos la ruta de visitas via el API de OSRM usando el sub "traeRutaDia(traeTodosAVisitar)".
Private Sub b_getRutaInfo_Click
'	traeRutaDia(traeTodosAVisitar)
	caculaRutaGPS(todosAVisitar)
End Sub

'Mostramos u ocultamos el boton para borrar los waypoints de la ruta.
Private Sub b_getRutaInfo_LongClick
	If b_limpiarRuta.Visible Then
		b_limpiarRuta.Visible = False
	Else
		b_limpiarRuta.Visible = True
	End If
End Sub

'Borramos los waypoints de la ruta.
Private Sub b_limpiarRuta_Click
	Starter.skmt.ExecNonQuery("delete from waypoints")
	b_limpiarRuta.Visible = False
	B4XPage_Appear
End Sub

Sub caculaRutaGPS(coords As List)
	Private tmpList As List
	Dim cs, cs2 As CSBuilder
	tmpList.Initialize
	tmpList.AddAll(Array As String("ACTUAL", Tracker.UUGCoords.Longitude, Tracker.UUGCoords.Latitude))
	coords.InsertAt(0,tmpList)
	Log("=================================")
'	Log(coords)
	Private coordsStr As String = ""
	For Each tienda As List In coords
'		Log(tienda)
		If coordsStr = "" Then
			coordsStr = $"${tienda.get(0)},${tienda.get(1)},${tienda.get(2)}"$
		Else
			coordsStr = $"${coordsStr};${tienda.get(0)},${tienda.get(1)},${tienda.get(2)}"$
		End If
	Next
	Log(coordsStr)
	ProgressDialogShow2("Calculando distancia y tiempo, un momento por favor.", False)
	Dim j As HttpJob
	j.Initialize("trip", Me) 'Calculamos el resto de la ruta.
	j.Download($"http://keymon.lat:9002/ruteador?m=OSRM&r=${Subs.traeRutaReparto}&a=${Subs.traeAlmacen}&f=CEDIS,${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}&c=${coordsStr}"$)
	Log($"http://keymon.lat:9002/ruteador?m=OSRM&r=${Subs.traeRutaReparto}&a=${Subs.traeAlmacen}&f=CEDIS,${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}&c=${coordsStr}"$)
	Wait For (j) JobDone(j As HttpJob)
	If j.Success Then
		Dim jp As JSONParser
		jp.Initialize(j.GetString)
		Dim m As Map = jp.NextObject
		Log(m)
		If m.Get("code") = "OK" Then
			Log("=====   OK")
			rutaGenerada = True
			Dim puntos As Int = m.Get("puntos")
			Private coords As List = m.Get("coords")
			Private duration As String = m.Get("duration")
			Private distance As String = m.Get("distance")
			Private mensaje As String = m.Get("mensaje")
			Starter.skmt.ExecNonQuery("delete from waypoints")
			Starter.skmt.ExecNonQuery("update kmt_info set SECUENCIA = 0")
			For i = 0 To coords.Size - 1
				Private ti As Map = coords.Get(i)
				Starter.skmt.ExecNonQuery($"update kmt_info set SECUENCIA = ${ti.Get("pos")} where CAT_CL_CODIGO = '${ti.Get("id").As(String).SubString(1)}'"$) ' Ponemos la secuencia con el orden del ruteo para poder verla en el mapa.
				Starter.skmt.ExecNonQuery($"insert into waypoints (codigo, indice) values ('${ti.Get("id").As(String).SubString(1)}', '${ti.Get("pos")}')"$)	
			Next
			c = Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
			If c.RowCount > 0 Then 'Ya hay waypoints en la base de datos.
				c.Position = 0
				conMapa = True
				ListView1.Clear
				Dim cs, cs2 As CSBuilder
				entro = 3
				For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
					c.Position = i
					cs.Initialize
					cs2.Initialize
					ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
				Next
			End If
			c.Close
			Log($"Distancia total: $1.1{distance/1000} kms, tiempo aprox: $1.1{duration/60} mins. ($1.1{duration/60/60} hrs)"$)
			l_rutaInfo.Text = $"Distancia: $1.1{distance/1000} kms, tiempo aprox: $1.1{duration/60/60} hrs${CRLF}Visitas restantes: ${puntos - 1}"$
			l_rutaInfo.Width = Root.Width * 0.9
			Subs.centraEtiqueta(l_rutaInfo, Root.Width)
			l_rutaInfo.Visible = True
			l_rutaInfo.BringToFront
			ListView1.Top = lv1Top + 100
		End If
	Else
		LogColor("****************  Error!  ******************", Colors.red)
	End If
	j.Release
	ProgressDialogHide
End Sub

'Regresa lista de los clientes a visitar y sus coordenadas, iniciando con el cedis.
Sub todosAVisitar As List
	Log(laRuta)
	Log(entro)
	Private sqlDeRuta As String = ""
	If entro = 3 Then sqlDeRuta = $"and CAT_CL_RUTA = '${laRuta}'"$
	Private aVisitar, tmpList As List
	aVisitar.Initialize
	Private coords As ResultSet = Starter.skmt.ExecQuery($"select CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where gestion = 0 AND CAT_CL_RUTA <> 500 ${sqlDeRuta}"$)
	Do While coords.NextRow
		tmpList.Initialize
		tmpList.AddAll(Array As String(coords.GetString("CAT_CL_CODIGO"), coords.GetString("CAT_CL_LONG"), coords.GetString("CAT_CL_LAT")))
		aVisitar.Add(tmpList)
	Loop
	Log(aVisitar)
	Return aVisitar
End Sub
