r"""
A minimal example of a field that behaves badly with the coercion system (but should not).

EXAMPLES::

    sage: F = MyField()
    sage: a = F(2)
    sage: a._complex_mpfr_field_(CC)
    2.00000000000000
    sage: CC(a)
    Traceback (most recent call last):
    ...
    RuntimeError: maximum recursion depth exceeded

The reason is that the coercion system finds better to go through the complex
lazy field::

    sage: CC.convert_map_from(F)
    Composite map:
      From: Is it really a field?
      To:   Complex Field with 53 bits of precision
      Defn:   Generic morphism:
              From: Is it really a field?
              To:   Complex Lazy Field
            then
              Conversion map:
              From: Complex Lazy Field
              To:   Complex Field with 53 bits of precision

The situation with real fields is very different::

    sage: RR(a)
    2.00000000000000
    sage: RR.convert_map_from(F)
    Conversion via _mpfr_ method map:
      From: Is it really a field?
      To:   Real Field with 53 bits of precision

    sage: RIF(a)
    2
    sage: RIF.convert_map_from(F)
    Call morphism:
      From: Is it really a field?
      To:   Real Interval Field with 53 bits of precision

And it works for complex interval fields::

    sage: CIF.convert_map_from(F)
    Call morphism:
      From: Is it really a field?
      To:   Complex Interval Field with 53 bits of precision
"""

from sage.structure.unique_representation import UniqueRepresentation
from sage.structure.element import FieldElement
from sage.structure.parent import Parent

from sage.categories.fields import Fields

class MyFieldElement(FieldElement):
    r"""
    Wrap all operations and provide two methods ``_mpfr_`` and
    ``_complex_mpfr_field_`` that are used to convert elements to the real and
    complex fields.
    """
    def __init__(self, parent, value):
        FieldElement.__init__(self, parent)
        self._value = value

    def _repr_(self):
        return "Element {} of my field".format(self._value)

    def _mpfr_(self, R):
        return self._value

    def _complex_mpfr_field_(self, R):
        return R(self._value)

    def _add_(self, other):
        P = self.parent()
        return P.element_class(P, self._value + other._value)
    
    def _mul_(self, other):
        P = self.parent()
        return P.element_class(P, self._value * other._value)

    def _div_(self, other):
        P = self.parent()
        return P.element_class(P, self._value / other._value)

    def __neg__(self):
        P = self.parent()
        return P.element_class(P, - self._value)

    def __invert__(self):
        P = self.parent()
        return P.element_class(P, ~self._value)

class MyField(UniqueRepresentation, Parent):
    Element = MyFieldElement

    def __init__(self):
        Parent.__init__(self, categories=Fields())

    def _repr_(self):
        return "Is it really a field?"

    def _element_constructor_(self, value):
        return self.element_class(self, value)

    def an_element(self):
        return self(2)
