""" An offer to create adapters from one protocol to another. """


from traits.api import Any, HasTraits, Property

from apptools.adaptation.adaptation_manager import AdaptationManager
from apptools.naming.initial_context import _import_symbol


class AdaptationOffer(HasTraits):
    """ An offer to create adapters from one protocol to another.

    An adaptation offer consists of a factory for an adapter, and the
    definition of the protocols from and to which an object can be adapted.

    """

    #### 'AdaptationOffer' protocol ###########################################

    #: A factory for adapters.
    #:
    #: The factory takes one argument, the object to be adapted, and returns
    #: an adapter from `from_protocol` to `to_protocol`.
    #:
    #: The factory can be specified as a callable object, or a string in the
    #: form 'foo.bar.baz' which is turned into an import statement
    #: 'from foo.bar import baz' and imported when this trait is first
    #: requested.
    factory = Property(Any)

    #: Shadow attribute storing the value for the corresponding property.
    _factory = Any

    def _get_factory(self):
        if isinstance(self._factory, basestring):
            self._factory = _import_symbol(self._factory)

        return self._factory

    def _set_factory(self, value):
        self._factory = value

        return

    #: Adapters created by the factory adapt from this protocol.
    #: It can be a string in the form 'foo.bar.baz' which is turned
    #: into an import statement 'from foo.bar import baz' and imported when
    #: this trait is first requested.
    from_protocol = Property(Any)

    #: Shadow attribute storing the value for the corresponding property.
    _from_protocol = Any

    def _get_from_protocol(self):
        if isinstance(self._from_protocol, basestring):
            self._from_protocol = _import_symbol(self._from_protocol)

        return self._from_protocol

    def _set_from_protocol(self, value):
        self._from_protocol = value

        return

    #: Adapters created by the factory adapt to this protocol.
    #: It can be a string in the form 'foo.bar.baz' which is turned
    #: into an import statement 'from foo.bar import baz' and imported when
    #: this trait is first requested.
    to_protocol = Property(Any)

    #: Shadow attribute storing the value for the corresponding property.
    _to_protocol = Any

    def _get_to_protocol(self):
        if isinstance(self._to_protocol, basestring):
            self._to_protocol = _import_symbol(self._to_protocol)

        return self._to_protocol

    def _set_to_protocol(self, value):
        self._to_protocol = value

        return

    def adapt(self, obj, to_protocol):

        if not AdaptationManager.provides_protocol(type(obj), self.from_protocol):
            return None

        if to_protocol is not self.to_protocol:
            return None

        return self.factory(adaptee=obj)

    #### 'object' protocol ####################################################

    def __repr__(self):
        template = "AdapterFactoryOffer: '{from_}' -> '{to}'"
        repr = template.format(
            from_ = self.from_protocol.__name__,
            to    = self.to_protocol.__name__
        )
        return repr

#### EOF ######################################################################

@@ -3118,24 +3118,25 @@
 '%7Bto%7D'%22%0A
+%0A
         
 repr = t
@@ -3131,30 +3131,27 @@
     
-repr = template.format
+from_name = getattr
 (%0A  
@@ -3163,16 +3163,8 @@
     
- from_ =
  sel
@@ -3170,33 +3170,34 @@
 lf.from_protocol
-.
+, 
 __name__,%0A      
@@ -3189,24 +3189,48 @@
 _name__,
+ str(self.from_protocol)
 %0A       
      to 
@@ -3225,20 +3225,49 @@
     
+ )%0A
      
-to    =
+   to_name = getattr(%0A           
  sel
@@ -3283,17 +3283,18 @@
 ocol
-.
+, 
 __name__
 %0A   
@@ -3289,26 +3289,111 @@
 __name__
-%0A        )
+, str(self.to_protocol)%0A        )%0A%0A        repr = template.format(from_=from_name, to=to_name)%0A
 %0A       

Fix __repr__ for lazy adapters.