# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

import string
import traceback
import sys
from coral import log
from qt import *
import re
import time
import types
import iconcache

logger=log.getLogger("coral.model.CoralAction")

class ActionRegistry:
    def __init__(self):
        self.actions={}
        self.groups={}
        self.currentWindow=None
        self.handler={}
        
    def __getitem__(self, key): return self.actions[key]
    def __setitem__(self, key, item):   self.actions[key] = item

    def __getattr__(self,key):
        return self.actions[key]
        
    def __exists__(self,e):
        return self.actions.has_key(e)

    def __reset__(self):
        self.actions={}

    def __iter__( self ):
        return self.actions.__iter__()
    
    def __declareAction__(self,a):
        if type(a) in [types.FunctionType,types.MethodType]:
            a=self.createActionFromFunction(a)
        if not self.actions.has_key(a.name):
            self.actions[a.name]=a
        return a

    def setCurrentHandler(self,name,h):
        self.handler[name]=h

    def getCurrentHandler(self,name):

        return self.handler[name]

    def createActionFromFunction(self,f):
        group=""
        name=""
        iconSet=QIconSet(iconcache.getIcon("noicon"))
        accelerator=0
        description=""
        menuLabel=""
        script=""
        
        for __l in string.split(f.__doc__,"\n"):
            __m = re.search("CoralAction:\s+(.*)", __l)
            if __m:
                name = __m.group(1)

            __m = re.search("Group:\s+(.*)", __l)
            if __m:
                group = __m.group(1)

            __m = re.search("Label:\s+(.*)", __l)
            if __m:
                menuLabel = __m.group(1)

            __m = re.search("Icon:\s+(.*)", __l)
            
            if __m:
                 iconSet=QIconSet(iconcache.getIcon( __m.group(1)))

            __m = re.search("Accelerator:\s+(.*)", __l)            
            if __m:
                 accelerator=QKeySequence( __m.group(1))

            __m = re.search("Script:\s+(.*)", __l)            
            if __m:
                 script=__m.group(1)
                 

        if script:
            handler=script
        elif group:
            handler=group+"."+f.__name__
        else:
            handler=f

        return CoralAction(None,name,handler,menuLabel,iconSet,accelerator,description)
            
        
                
class CoralAction(QAction):
    def __init__(self,parent,name,handler,menuLabel,iconSet,accelerator,description=""):
        QAction.__init__(self,parent,name)
        self.name=name
        self.parent=parent
        self.setMenuText(menuLabel)
        self.iconLabel=string.replace(menuLabel,'&','')
        self.iconLabel=string.replace(self.iconLabel,'&','')
        self.label=menuLabel
        self.setIconSet(iconSet)
        self.iconset=iconSet
        self.accelerator=accelerator
        self.handler=handler
        self.description=description
        self.connect(self,SIGNAL("activated()"),self.activated)

        self.setEnabled(0)
      
            
    def __call__(self,*args,**kargs):
        return self.dispatch(*args, **kargs)

    def getDocumentation(self):
        t="Action "+self.name+"\n"
        t=t+" Handler "+str(self.handler)+"\n"
        t=t+self.description
        return t

    def activated(self):
        return self.dispatchProtected()
    
    def dispatchProtected(self,*args,**kargs):
                            
        try:           
            st = time.time()            
            result=self.dispatch(*args, **kargs)

            QApplication.restoreOverrideCursor()
            et = time.time()
            logger.debug("Action " + self.name + " executed in " + str(et - st) + " seconds.")
            return result
        
        except Exception,e:
            QApplication.restoreOverrideCursor()
            log.getLogger().exception(e)
            txt="Exception while executing action "+self.name+"\n"
            txt=txt+str(e)+"\n\n"
            for l in traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback):
                txt+=l
            reportException(txt,self.name)
        return None
        
    def dispatch(self,*args,**kargs):
        toCall=None

        #from coral.modeler.window import getQtApp

        if type(self.handler)==type(""):	
            l=string.split(self.handler,".")
            handler=action.getCurrentHandler(l[0])
            toCall=eval(self.handler,{l[0]:handler})
        else:
            toCall=self.handler

        if toCall:
            logger.debug("Executing action %s" % self.name)
            result=toCall(*args, **kargs)
            return result
        else:
            logger.debug("Cannot execute action %s window handler %s " % (self.name,self.handler))
        return None
    
    #def setEnabled(self,status):
    #    pass

    #def addToMenu(self,menu):
    #    menu.insertItem(self.iconSet,self.label,self.dispatchProtected,self.accelerator)

    #def addToToolBar(self,toolBar):
    #    toolBar
    
def reportException(txt,name=""):
    import qt
    try:
        import qt
        qt.QMessageBox.critical(None,"Error in Action "+name,txt)
    except:
        logger.debug("It is not possible to show QMessageBox.critical")


                
#action=ActionRegistry()

from coral.modeler import extension

action=ActionRegistry()
