import os
import matplotlib.pyplot as plt
import numpy as np
from skimage.filters import threshold_otsu
from skimage.measure import label, regionprops
from collections import defaultdict


def filling_factor(arr):
    return np.sum(arr) / arr.size


def count_holes(arr):
    labeled = label(np.logical_not(arr))
    regions = regionprops(labeled)
    holes = 0
    for region in regions:
        coords = np.transpose(region.coords, (1, 0))
        ymin = np.min(coords[1])
        ymax = np.max(coords[1])
        xmin = np.min(coords[0])
        xmax = np.max(coords[0])
        if (
            ymin == 0
            or ymax == arr.shape[1] - 1
            or xmin == 0
            or xmax == arr.shape[0] - 1
        ):
            continue
        holes += 1
    return holes


def count_holes_rame(arr):
    labeled = label(np.logical_not(arr))
    return np.max(labeled)


def count_vline(arr):
    return np.sum(arr.mean(0) == 1)


def recognize(region):
    if filling_factor(region.image) == 1.0:
        return "-"
    else:
        holes = count_holes(region.image)
        if holes == 2:  # B or 8
            if count_vline(region.image) >= 3:
                return "B"
            else:
                return "8"
        elif holes == 1:  # A or 0
            if count_vline(region.image) >= 2:
                ecc = region.eccentricity
                if ecc < 0.65:
                    return "D"
                else:
                    return "P"
            else:
                if (
                    abs(
                        (region.local_centroid[0] / region.image.shape[0])
                        - (region.local_centroid[1] / region.image.shape[1])
                    )
                    > 0.02
                ):
                    return "A"
                else:
                    return "0"
        else:
            if count_vline(region.image) >= 1:
                return "1"
            else:
                ecc = region.eccentricity
                if ecc < 0.4:
                    return "*"
                match count_holes_rame(region.image):
                    case 2:
                        return "/"
                    case 4:
                        return "X"
                    case _:
                        return "W"


img = plt.imread("./symbols.png")

img = np.mean(img, axis=2)
thrash = threshold_otsu(img)
img[img > 0] = 1

regions = regionprops(label(img))

result = {}

path = "./res"
if not os.path.exists(path):
    os.mkdir(path)

for i, region in enumerate(regions):
    symbol = recognize(region)
    if symbol in ["P", "D"]:
        plt.clf()
        plt.title(f"{symbol}")
        plt.imshow(region.image)
        plt.savefig(f"{path}/{i}")
        if symbol not in result.keys():
            result[symbol] = 0
        result[symbol] += 1

print(result, sum(result.values()))
