__all__ = ['geo', 'geo2tile', 'tile']

import json
import math
import re

re_geo2 = re.compile(r'([0-9.]+) ([0-9.]+)'), r'\1,\2'
re_geo3 = re.compile(r'([0-9.]+) ([0-9.]+) ([0-9.]+)'), r'\1,\2'
re_rd = re.compile(r'([0-9.]+)[, ]([0-9.]+)')

def tile(*xy, granularity=1):
    return ''.join(chr(70 + math.floor(a / 100_000)) for a in xy) + ''.join(
        str(int(a / d) % 10)
        for (_, d) in
        zip(range(granularity), (10_000, 1_000, 100, 10, 1))
        for a in xy
    )

def geo(data):
    match data:
        case {'punt':value}:
            return geo(value)
        case {'vlak':value}:
            return geo(value)
        case {'multivlak':value}:
            return geo(value)
        case {'Point':{'pos':value}}:
            return ','.join(value.split(' ')[0:2])
        case {'LineString':{'posList':value}}:
            return re.sub(*re_geo2, value)
        case {'Polygon':{'srsDimension':'3','exterior':{'LinearRing':{'posList':{'_':value}}}}}:
            return re.sub(*re_geo3, value)
        case {'Polygon':{'exterior':{'LinearRing':{'posList':{'_':value}}}}}:
            return re.sub(*re_geo2, value)
        case {'Polygon':{'exterior':{'LinearRing':{'posList':value}}}}:
            return re.sub(*re_geo2, value)
        case {'MultiSurface':{'surfaceMember':{'Polygon':{'exterior':{'LinearRing':{'posList':value}}}}}}:
            return re.sub(*re_geo2, value)
        case {'MultiSurface':{'surfaceMember':values}}:
            return ';'.join(geo(value) for value in values)
        case _:
            # MISSING
            return json.dumps(data, separators=(',', ':'))

def geo2tile(a, granularity=4):
    if match := re.search(re_rd, a):
        return tile(
            float(match[1]),
            float(match[2]),
            granularity=granularity
        )
