'''
Copyright 2022 Martin Zurowietz and Torben Möller
Released under the CRAPL license (CRAPL-LICENSE.txt), see also:
https://matt.might.net/articles/crapl/
'''

import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import maximum_bipartite_matching

def parse_points(points, convert=False):
    points = np.array(points.strip('[]').split(','), dtype=float)
    if (not convert):
        return points[:2], points[2]

    points = points.reshape(-1, 2)
    min_x = points[:, 0].min()
    max_x = points[:, 0].max()
    min_y = points[:, 1].min()
    max_y = points[:, 1].max()
    width = max_x - min_x
    height = max_y - min_y
    radius = max(width, height) / 2

    return np.array([min_x + width / 2, min_y + height / 2]), radius

def annotations_match(a, b):
    # Annotations match if one contains the center of the other.
    distance = np.linalg.norm(a[0] - b[0])

    return distance <= a[1] or distance <= b[1]

def parse_report_row(row):
    point, radius = parse_points(row[13], int(row[11]) != 4)

    return row[8], point, radius, row[1], row[2]

def parse_db_dump_row(row):
    point, radius = parse_points(row[1])

    return row[2], point, radius, row[3]

def generate_mm(gs, pr):
    adjacency = np.zeros((len(gs), len(pr)), dtype=bool)
    for i, gsa in enumerate(gs):
        for j, pra in enumerate(pr):
            adjacency[i, j] = annotations_match(gsa, pra)

    return maximum_bipartite_matching(csr_matrix(adjacency))
