from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

import abc
from compas.geometry import Primitive


class Shape(Primitive):
    """Base class for geometric shapes."""

    @abc.abstractmethod
    def to_vertices_and_faces(self):
        pass

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

import abc
from ..geometry import Geometry


class Shape(Geometry):
    """Base class for geometric shapes."""

    @abc.abstractmethod
    def to_vertices_and_faces(self):
        pass

    def __add__(self, other):
        """Compute the boolean union using the "+" operator of this shape and another.

        Parameters
        ----------
        other : :class:`Solid`
            The solid to add.

        Returns
        -------
        :class:`Solid`
            The resulting solid.

        Examples
        --------
        >>> from compas.geometry import Box, Sphere
        >>> A = Box.from_width_height_depth(2, 2, 2)
        >>> B = Sphere([1, 1, 1], 1.0)
        >>> C = A + B
        """
        from compas.geometry import boolean_union_mesh_mesh
        from compas.geometry import Polyhedron
        A = self.to_vertices_and_faces(triangulated=True)
        B = other.to_vertices_and_faces(triangulated=True)
        V, F = boolean_union_mesh_mesh(A, B)
        return Polyhedron(V, F)

    def __sub__(self, other):
        """Compute the boolean difference using the "-" operator of this shape and another.

        Parameters
        ----------
        other : :class:`Solid`
            The solid to subtract.

        Returns
        -------
        :class:`Solid`
            The resulting solid.

        Examples
        --------
        >>> from compas.geometry import Box, Sphere
        >>> A = Box.from_width_height_depth(2, 2, 2)
        >>> B = Sphere([1, 1, 1], 1.0)
        >>> C = A - B
        """
        from compas.geometry import boolean_difference_mesh_mesh
        from compas.geometry import Polyhedron
        A = self.to_vertices_and_faces(triangulated=True)
        B = other.to_vertices_and_faces(triangulated=True)
        V, F = boolean_difference_mesh_mesh(A, B)
        return Polyhedron(V, F)

    def __and__(self, other):
        from compas.geometry import boolean_intersection_mesh_mesh
        from compas.geometry import Polyhedron
        A = self.to_vertices_and_faces(triangulated=True)
        B = other.to_vertices_and_faces(triangulated=True)
        V, F = boolean_intersection_mesh_mesh(A, B)
        return Polyhedron(V, F)

    def __or__(self, other):
        return self.__add__(other)

rebase shape and add boolean operators