#requires appscript
import aem, mactypes #from appscripts aem module 
from CarbonX import kAE

class FcpAe(aem.Application):
    """Communicates with Apple's Final Cut Pro using Apple Events. 
    Gets and sends XML.
    """

    kFCPEventClass ='KeyG'
    # event commands
    # the Open/Foreground a project file command
    kAEFCPOpenProjectFile ='ofcP'
    #the Close a project file command
    kAEFCPSaveAndCloseProjectFile = 'cfcP'
    #the XML Export command
    kKGAEGetDocumentXML = 'eXML'                
    #the XML Import command
    kAEImportXMLToDocument = 'iXML'
    #Open the item specified in the passed in UUID
    kFCPOpenItemInProject = 'fcOI'
    #Select the item specified in the passed in UUID
    kFCPSelectItemInBrowser = 'fcSI'
    # event parameters
    kXMLDataKey = 'xmlD'
    kXMLDataFileKey = 'xmlF'
    kXMLDataVersion = 'xmlV'
    kFCPProjectFileKey = 'fcpP'
    kFCPItemUUID = 'fcIU'
    kProjectFileCloseFlagsKey= 'fcCF'
    kFCPSaveAndCloseProject = 0
    kFCPDiscardAndCloseProject = 1
    kFindParameters = 'fndP'
    kFindSearchString = 'fndS'
    kFindMatchMode = 'fndM'
    kFindOmitCriteria = 'fndO'
    kFindColumnName = 'fndC'
    kFindLogicMode = 'fndL'
    kFCPFindMatchStartsWith = (1 << 0)
    kFCPFindMatchContains = (1 << 1)
    kFCPFindMatchEquals = (1 << 2)
    kFCPFindMatchEndsWith = (1 << 3)
    kFCPFindMatchLessThan = (1 << 4)
    kFCPFindMatchGreaterThan = (1 << 5)
    kFCPLogicAnd = 0
    kFCPLogicOr = 1

    def __init__(self):
        fcpID = 'com.apple.finalcutpro'
        fcpPath = aem.findapp.byid(fcpID)
        aem.Application.__init__(self,path=fcpPath)
        if not self.isrunning(fcpPath):
            self.launch(fcpPath)

    def commandEvent(self, fcpEvent):
        return ''.join([self.kFCPEventClass, fcpEvent])

    #fcp event commands below
    def openProject(self,unixFileStr):
        proj = mactypes.File(unixFileStr)
        eventkey = self.commandEvent(self.kAEFCPOpenProjectFile)
        res = self.event(eventkey,{self.kFCPProjectFileKey : proj}).send()

    def closeProject(self, unixFileStr, actionOnClose=0): # !!
        proj = mactypes.File(unixFileStr)
        eventkey = self.commandEvent(self.kAEFCPSaveAndCloseProjectFile)
        res = self.event(eventkey,{
                    self.kFCPProjectFileKey : proj,
                    self.kProjectFileCloseFlagsKey : actionOnClose}).send()

    def exportXML(self, projPathStr, fcpVersionXML=1.0):
        """Returns XML form of given FCP project"""

        proj = mactypes.File(projPathStr)
        eventkey = self.commandEvent(self.kKGAEGetDocumentXML)
        event = self.event(eventkey, {
                    self.kFCPProjectFileKey : proj,
                    self.kXMLDataVersion : fcpVersionXML})
        # note that fcp returns the XML test using kXMLDataKey 
        #instead of the usual keyAEResult
        # which is what aem expects
        # hence we use the lower level approach to wrangle the result
        # Thanks HAS!
        eventdesc = event.AEM_event
        replyeventdesc = eventdesc.AESendMessage(kAE.kAEWaitReply, 
                                                kAE.kAEDefaultTimeout)
        paramdict = aem.Codecs().unpack(replyeventdesc)
        return paramdict.get(aem.AEType('xmlD'), '')

    def importXML(self, xmlStr, projPathStr=None):
        """Modifies or creates FCP project based on XML supplied"""

        if projPathStr:
            proj = mactypes.File(projPathStr)
            aedict = {self.kFCPProjectFileKey : proj,
                      self.kXMLDataKey : xmlStr}
        else:
            aedict = {self.kXMLDataKey : xmlStr}
        eventkey = self.commandEvent(self.kAEImportXMLToDocument)
        res = self.event(eventkey, aedict).send()

    def openItem(self, projPathStr, uuid):
        proj = mactypes.File(projPathStr)
        eventkey = self.commandEvent(self.kFCPOpenItemInProject)
        return self.event(eventkey, {
                    self.kFCPProjectFileKey : proj,
                    self.kFCPItemUUID : uuid}).send()

    def selectItem(self, projPathStr, uuid):
        proj = mactypes.File(projPathStr)
        eventkey = self.commandEvent(self.kFCPSelectItemInBrowser)
        return self.event(eventkey, {
                    self.kFCPProjectFileKey : proj,
                    self.kFCPItemUUID : uuid}).send()



# example
testxml = 'Example.xml'
testproj = 'test.fcp'
f = open(testxml,'r')
xmllist = f.readlines()
xml = ''.join(xmllist)
xmlout= ''

fcp = FcpAe()
fcp.openProject(testproj)
print fcp.exportXML(testproj, 3.0)
fcp.importXML(xml)
fcp.closeProject(testproj)