"""Tools for use in AppleEvent clients and servers.

pack(x) converts a Python object to an AEDesc object
unpack(desc) does the reverse

packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record
unpackevent(event) returns the parameters and attributes from an AEAppleEvent record

Plus...  Lots of classes and routines that help representing AE objects,
ranges, conditionals, logicals, etc., so you can write, e.g.:

    x = Character(1, Document("foobar"))

and pack(x) will create an AE object reference equivalent to AppleScript's

    character 1 of document "foobar"

Some of the stuff that appears to be exported from this module comes from other
files: the pack stuff from aepack, the objects from aetypes.

"""


from types import *
from Carbon import AE
from Carbon import Evt
from Carbon import AppleEvents
import MacOS
import sys
import time

from aetypes import *
from aepack import packkey, pack, unpack, coerce, AEDescType

Error = 'aetools.Error'

# Amount of time to wait for program to be launched
LAUNCH_MAX_WAIT_TIME=10

# Special code to unpack an AppleEvent (which is *not* a disguised record!)
# Note by Jack: No??!? If I read the docs correctly it *is*....

aekeywords = [
    'tran',
    'rtid',
    'evcl',
    'evid',
    'addr',
    'optk',
    'timo',
    'inte', # this attribute is read only - will be set in AESend
    'esrc', # this attribute is read only
    'miss', # this attribute is read only
    'from'  # new in 1.0.1
]

def missed(ae):
    try:
        desc = ae.AEGetAttributeDesc('miss', 'keyw')
    except AE.Error, msg:
        return None
    return desc.data

def unpackevent(ae, formodulename=""):
    parameters = {}
    try:
        dirobj = ae.AEGetParamDesc('----', '****')
    except AE.Error:
        pass
    else:
        parameters['----'] = unpack(dirobj, formodulename)
        del dirobj
    # Workaround for what I feel is a bug in OSX 10.2: 'errn' won't show up in missed...
    try:
        dirobj = ae.AEGetParamDesc('errn', '****')
    except AE.Error:
        pass
    else:
        parameters['errn'] = unpack(dirobj, formodulename)
        del dirobj
    while 1:
        key = missed(ae)
        if not key: break
        parameters[key] = unpack(ae.AEGetParamDesc(key, '****'), formodulename)
    attributes = {}
    for key in aekeywords:
        try:
            desc = ae.AEGetAttributeDesc(key, '****')
        except (AE.Error, MacOS.Error), msg:
            if msg[0] != -1701 and msg[0] != -1704:
                raise
            continue
        attributes[key] = unpack(desc, formodulename)
    return parameters, attributes

def packevent(ae, parameters = {}, attributes = {}):
    for key, value in parameters.items():
        packkey(ae, key, value)
    for key, value in attributes.items():
        ae.AEPutAttributeDesc(key, pack(value))

#
# Support routine for automatically generated Suite interfaces
# These routines are also useable for the reverse function.
#
def keysubst(arguments, keydict):
    """Replace long name keys by their 4-char counterparts, and check"""
    ok = keydict.values()
    for k in arguments.keys():
        if keydict.has_key(k):
            v = arguments[k]
            del arguments[k]
            arguments[keydict[k]] = v
        elif k != '----' and k not in ok:
            raise TypeError, 'Unknown keyword argument: %s'%k

def enumsubst(arguments, key, edict):
    """Substitute a single enum keyword argument, if it occurs"""
    if not arguments.has_key(key) or edict is None:
        return
    v = arguments[key]
    ok = edict.values()
    if edict.has_key(v):
        arguments[key] = Enum(edict[v])
    elif not v in ok:
        raise TypeError, 'Unknown enumerator: %s'%v

def decodeerror(arguments):
    """Create the 'best' argument for a raise MacOS.Error"""
    errn = arguments['errn']
    err_a1 = errn
    if arguments.has_key('errs'):
        err_a2 = arguments['errs']
    else:
        err_a2 = MacOS.GetErrorString(errn)
    if arguments.has_key('erob'):
        err_a3 = arguments['erob']
    else:
        err_a3 = None

    return (err_a1, err_a2, err_a3)

class TalkTo:
    """An AE connection to an application"""
    _signature = None   # Can be overridden by subclasses
    _moduleName = None  # Can be overridden by subclasses
    _elemdict = {}      # Can be overridden by subclasses
    _propdict = {}      # Can be overridden by subclasses

    __eventloop_initialized = 0
    def __ensure_WMAvailable(klass):
        if klass.__eventloop_initialized: return 1
        if not MacOS.WMAvailable(): return 0
        # Workaround for a but in MacOSX 10.2: we must have an event
        # loop before we can call AESend.
        Evt.WaitNextEvent(0,0)
        return 1
    __ensure_WMAvailable = classmethod(__ensure_WMAvailable)

    def __init__(self, signature=None, start=0, timeout=0):
        """Create a communication channel with a particular application.

        Addressing the application is done by specifying either a
        4-byte signature, an AEDesc or an object that will __aepack__
        to an AEDesc.
        """
        self.target_signature = None
        if signature is None:
            signature = self._signature
        if type(signature) == AEDescType:
            self.target = signature
        elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
            self.target = signature.__aepack__()
        elif type(signature) == StringType and len(signature) == 4:
            self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
            self.target_signature = signature
        else:
            raise TypeError, "signature should be 4-char string or AEDesc"
        self.send_flags = AppleEvents.kAEWaitReply
        self.send_priority = AppleEvents.kAENormalPriority
        if timeout:
            self.send_timeout = timeout
        else:
            self.send_timeout = AppleEvents.kAEDefaultTimeout
        if start:
            self._start()

    def _start(self):
        """Start the application, if it is not running yet"""
        try:
            self.send('ascr', 'noop')
        except AE.Error:
            _launch(self.target_signature)
            for i in range(LAUNCH_MAX_WAIT_TIME):
                try:
                    self.send('ascr', 'noop')
                except AE.Error:
                    pass
                else:
                    break
                time.sleep(1)

    def start(self):
        """Deprecated, used _start()"""
        self._start()

    def newevent(self, code, subcode, parameters = {}, attributes = {}):
        """Create a complete structure for an apple event"""

        event = AE.AECreateAppleEvent(code, subcode, self.target,
                  AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
        packevent(event, parameters, attributes)
        return event

    def sendevent(self, event):
        """Send a pre-created appleevent, await the reply and unpack it"""
        if not self.__ensure_WMAvailable():
            raise RuntimeError, "No window manager access, cannot send AppleEvent"
        reply = event.AESend(self.send_flags, self.send_priority,
                                  self.send_timeout)
        parameters, attributes = unpackevent(reply, self._moduleName)
        return reply, parameters, attributes

    def send(self, code, subcode, parameters = {}, attributes = {}):
        """Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
        return self.sendevent(self.newevent(code, subcode, parameters, attributes))

    #
    # The following events are somehow "standard" and don't seem to appear in any
    # suite...
    #
    def activate(self):
        """Send 'activate' command"""
        self.send('misc', 'actv')

    def _get(self, _object, as=None, _attributes={}):
        """_get: get data from an object
        Required argument: the object
        Keyword argument _attributes: AppleEvent attribute dictionary
        Returns: the data
        """
        _code = 'core'
        _subcode = 'getd'

        _arguments = {'----':_object}
        if as:
            _arguments['rtyp'] = mktype(as)

        _reply, _arguments, _attributes = self.send(_code, _subcode,
                _arguments, _attributes)
        if _arguments.has_key('errn'):
            raise Error, decodeerror(_arguments)

        if _arguments.has_key('----'):
            return _arguments['----']
            if as:
                item.__class__ = as
            return item

    get = _get

    _argmap_set = {
        'to' : 'data',
    }

    def _set(self, _object, _attributes={}, **_arguments):
        """set: Set an object's data.
        Required argument: the object for the command
        Keyword argument to: The new value.
        Keyword argument _attributes: AppleEvent attribute dictionary
        """
        _code = 'core'
        _subcode = 'setd'

        keysubst(_arguments, self._argmap_set)
        _arguments['----'] = _object


        _reply, _arguments, _attributes = self.send(_code, _subcode,
                _arguments, _attributes)
        if _arguments.get('errn', 0):
            raise Error, decodeerror(_arguments)
        # XXXX Optionally decode result
        if _arguments.has_key('----'):
            return _arguments['----']

    set = _set

    # Magic glue to allow suite-generated classes to function somewhat
    # like the "application" class in OSA.

    def __getattr__(self, name):
        if self._elemdict.has_key(name):
            cls = self._elemdict[name]
            return DelayedComponentItem(cls, None)
        if self._propdict.has_key(name):
            cls = self._propdict[name]
            return cls()
        raise AttributeError, name

# Tiny Finder class, for local use only

class _miniFinder(TalkTo):
    def open(self, _object, _attributes={}, **_arguments):
        """open: Open the specified object(s)
        Required argument: list of objects to open
        Keyword argument _attributes: AppleEvent attribute dictionary
        """
        _code = 'aevt'
        _subcode = 'odoc'

        if _arguments: raise TypeError, 'No optional args expected'
        _arguments['----'] = _object


        _reply, _arguments, _attributes = self.send(_code, _subcode,
                _arguments, _attributes)
        if _arguments.has_key('errn'):
            raise Error, decodeerror(_arguments)
        # XXXX Optionally decode result
        if _arguments.has_key('----'):
            return _arguments['----']
#pass

_finder = _miniFinder('MACS')

def _launch(appfile):
    """Open a file thru the finder. Specify file by name or fsspec"""
    _finder.open(_application_file(('ID  ', appfile)))


class _application_file(ComponentItem):
    """application file - An application's file on disk"""
    want = 'appf'

_application_file._propdict = {
}
_application_file._elemdict = {
}

# Test program
# XXXX Should test more, really...

def test():
    target = AE.AECreateDesc('sign', 'quil')
    ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
    print unpackevent(ae)
    raw_input(":")
    ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
    obj = Character(2, Word(1, Document(1)))
    print obj
    print repr(obj)
    packevent(ae, {'----': obj})
    params, attrs = unpackevent(ae)
    print params['----']
    raw_input(":")

if __name__ == '__main__':
    test()
    sys.exit(1)
