package tiles

import (
	"github.com/paulmach/orb"
)

// GridId defines the position of a tile
// It follows the Valhalla way of handling tiles : https://github.com/Telenav/open-source-spec/blob/master/valhalla/doc/valhalla-tiles-basic.md
type GridId uint64

const tilesize float64 = 1.0

// PointGridId returns the id on the grid for a given point
func PointGridId(point orb.Point) GridId {
	width := int64(360 / tilesize)
	gridid := GridId(int64((point.Lat()+90)/tilesize)*width + int64((point.Lon()+180)/tilesize))
	return gridid
}

// LineStringGridIds returns the list of ids on the grid the linestring goes through.
// In some really specific cases on tile edges, this could be unaccurate if the polyline was too much simplified
func LineStringGridIds(linestring orb.LineString) []GridId {
	results := []GridId{}

	gidmap := map[int64]bool{}

	for _, p := range linestring {
		gid := PointGridId(p)
		if _, ok := gidmap[int64(gid)]; !ok {
			gidmap[int64(gid)] = true
			results = append(results, gid)
		}
	}

	return results
}