"""
Vectorial image Vimage

Medical Images 2022-2023- MUEI/MNUR ETSEIB

D.Tost
"""
from rectangle import Rectangle
from circle import Circle
from polygon import Polygon
import os, json

class VImage:
    @classmethod
    def from_dict(cls, name, d):
        """
        Creates a vectorial image from a dictionary
        """
        vim = cls(name)
        for sd in d:
            if sd["type"] == "circle":
                elem = Circle.from_dict(sd["value"])
            elif sd["type"] == "rectangle":
                elem = Rectangle.from_dict(sd["value"])
            elif sd["type"] == "polygon":
                elem = Polygon.from_dict(sd["value"])
            else:
                elem = None
            if elem is not None:
                vim.add(elem)
        return vim

    @classmethod
    def from_json(cls, filename):
        """
        Creates a vectorial image from a json file
        """
        name = os.path.splitext(os.path.basename(filename))[0]
        with open(filename, "r") as f:
            return cls.from_dict(name, json.load(f))

    def __init__(self, name):
        """
        Creates a vectorial image with the given name and no figures
        """
        self.name = name
        self.__figures = {}

    def __getitem__(self, id):
        """
        Returns the id-th figure of the VImage
        """
        return self.__figures[id]

    def add(self, figure):
        """
        Adds a figure to the VImage. The index of the added figure in the
        VImage will be it len(self)-1
        """
        id = len(self) + 1
        self.__figures[id] = figure
        return id

    def __contains__(self, figure):
        """
        Indicates if the figure is in the VImage
        """
        return figure in self.__figures

    def remove(self, figure):
        """
        Removes the figure from the VImage
        """
        if figure in self.__figures:
            self.__figures.pop(figure)

    def __len__(self):
        """
        Returns the number of figures of the VImage
        """
        return len(self.__figures)

    def __str__(self):
        """
        Returns a str indicating the name and length of the VImage
        """
        return "Vectorial image {} of {} figures".format(self.name, len(self))

    def __iter__(self):
        """
        Returns an iterator of the figures of the VImage
        """
        return iter(self.__figures.values())

    def __eq__(self, other):
        """
        Returns True if self has the same figures as self and the same name
        """
        return self.__figures == other.__figures and self.name == other.name

    def to_dict(self):
        """
        Returns a dictionary of the figures of the VImage
        """
        d = []
        for elem in self:
            if isinstance(elem, Circle):
                d.append({"type": "circle", "value": elem.to_dict()})
            elif isinstance(elem, Rectangle):
                d.append({"type": "rectangle", "value": elem.to_dict()})
            elif isinstance(elem, Polygon):
                d.append({"type": "polygon", "value": elem.to_dict()})
        return d

    def to_json(self, filename):
        """
        Writes the image in a json file of the given name
        """
        d = self.to_dict()
        with open(filename, 'w') as f:
            json.dump(d, f)

    def bounding_box(self):
        """
        To be implemented. Returns the bounding box of the vimage
        """
        return None
    
