"""
A simple cache for hit boxes calculated from texture.
Hit box calculations are normally done at load time
by inspecting the contents of a loaded image.

Depending on the hit box algorithm a hit box is calculated:
* None     : Simply a box around the whole texture. No caching needed.
* Simple   : Scanning the corners for the texture
* Detailed : fairly detailed hit box generated by pymunk with detail parameter
"""
import copy
import json
from pathlib import Path
from typing import Dict, Optional, Union

from arcade.arcade_types import PointList
from arcade.resources import resolve_resource_path


class HitBoxCache:
    """
    A simple cache for hit box points for textures.
    These are calculated when loading a texture
    depending on the selected hit box algorithm.
    """
    def __init__(self):
        self._entries: Dict[str, PointList] = {}

    def __len__(self) -> int:
        return len(self._entries)

    @classmethod
    def from_file(cls, path: Union[str, Path]):
        """Load a json file containing hit boxes"""
        path = resolve_resource_path(path)
        with open(path, mode="r") as fd:
            data = json.loads(fd.read())

        cache = cls()
        for key, value in data.items():
            cache.put(key, value)

    def get(self, name: str) -> Optional[PointList]:
        """
        Get the hit box points for a texture
        """
        points = self._entries.get(name)
        # NOTE: Safer to copy them for now
        if points:
            points = copy.copy(points)

        return points

    def put(self, name: str, points: PointList):
        """
        Put hit box points into cache with a name
        """
        self._entries[name] = points

    def save(self, path: Union[str, Path]):
        """Save the hit box cache to disk"""
        with open(path, mode="w") as fd:
            fd.write(json.dumps(self._entries, indent=2))
