import os

PLUGIN_VERSION = "20140226"

# subfolder for gimmicks
GIMMICK_SUBDIR = "gimmicks"

# gimmick file extension
GIMMICK_EXT = ".gimmick"

MENU_NAME = "Gimmick"

SERVICE_GIMMICKS = "KellerGimmicksPlugin.gimmicks"

#_MENU_TOKEN_SEPARATOR_ = "|"
#_MENU_KNOB_NAME_ = "_kMenu"
GIMMICK_BASEDIR = os.path.join(WORKGROUP_BASEDIR, GIMMICK_SUBDIR)
GIMMICK_TEMPLATE_SUBDIR = "Templates"
GIMMICK_GROUP_SUBDIR = "Gimmicks"

class KellerGimmicksPlugin(KellerNukePlugin):

    def configurePlugin(self):
         # register menu entry
        self.menu = nuke.menu("Nuke")
        #m = menu.addMenu("&Edit")
        m = self.menu.addMenu(MENU_NAME)
        m.addCommand("Save from Node...", "kellerGimmicks.saveGimmick()")
        m.addCommand("Update Nodes", "kellerGimmicks.updateGimmicks()")
        
        #nuke.debug("basedir ist %s " % self.getBaseDir())
        KellerPluginManager.setServiceData(SERVICE_GIMMICKS, dict())
        
        registerGimmicks(GIMMICK_BASEDIR)
        
    def unconfigurePlugin(self):
        
        self.menu.removeItem(MENU_NAME)
        
        # remove gimmicks
        removeGimmicks(GIMMICK_BASEDIR)
        
        KellerPluginManager.removeServiceData(SERVICE_GIMMICKS)
        
        
        
        
       
    
    
    
class KellerGimmick():
    pass
    def __init__(self, file=None):
        
        self._initFile(file)
        self._gimmickData = dict()
        
    def _initFile(self, file):

        import re
        print ("created gimmick %s" % file)
        self.menuLocation = list()
        
        
        self.file = None
        
        if file is not None:
            
            # init menu location from filename
            if GIMMICK_BASEDIR is not None:
                # check if valid directory
                if not os.path.isdir(GIMMICK_BASEDIR):
                    # TODO, raise specific exception
                    raise Exception
                
                gimmickPath = os.path.dirname(file)
                #if gimmickPath == GIMMICK_BASEDIR:
                #    relPath = ""
                #else:
                relPath = os.path.relpath(gimmickPath, GIMMICK_BASEDIR)
                
                
                
                #nuke.debug("RELPATH: %s" %relPath)
                relPath = relPath.replace("\\","/")
                
                menuEntries = relPath.split("/")
                # remove . element
                if "." in menuEntries:
                    menuEntries.remove(".")
                self.setMenuLocation(menuEntries)
                self.file = os.path.normpath(file).replace("\\","/")
            
                # get name from file
                m = re.match("(.*)\..*", os.path.basename(file))
                if m is not None:
                    self.name = m.group(1)
                else:
                    self.name=os.path.basename(file)
        else: # filename is none
            self.file = None
            self.name = "unknown"    
        
    def getFile(self):
        return self.file
       
    def load(self, file):
        pass
    
    def setMenuLocation(self, menuLocation):
        
        self.menuLocation = menuLocation
    
    def addData(self,name, value):
        self._gimmickData[name] = value
        
            
    def _createDefaultGimmickData(self):
        
        import time
        self.addData("Creation Time", time.ctime())
        
        
    def _saveAs(self, file):
        
        try:
            nuke.nodeCopy(file)
        except:
            nuke.message("Error saving node to %s" % file)
        self._initFile(file)
        
        # append gimmick data
        self._createDefaultGimmickData()
        self._saveGimmickData()
        
    def setName(self, name):
        self.name = name
    
    def getName(self):
        return self.name
    
    def addMenuLocation(self, menuString):
        print ("added %s" % menuString)
        self.menuLocation.append(menuString)
    
    def removeFromMenu(self):
        
        print (self.menuEntry)
        
        
        if self.menuEntry is not None:
            print ("remove from menu, entry=%s" % str(self.menuEntry))
            
            (parent, commandName) = self.menuEntry
            
            parent.removeItem(commandName)
    
    def _registerMenu(self):
        #nuke.debug("register menulocation %s" % str(self.menuLocation))
        self._registerMenuInternal(self.menuLocation, -1, len(self.menuLocation))
          
          
    def _registerMenuInternal(self, entries, level, numLevels, parent=None):
        
        if level > numLevels:
            return
        
        if (level == -1):
            #
            # Root Menu
            #
            #nuke.debug( "creating root menu NODES ")
            parent = nuke.menu("Nodes")
            #print ("Menu %s" % entries[level])
        
        elif (level >= 0 ) and (level < numLevels):
            #
            # Sub menues
            #
            
            #nuke.debug( "submenu %s" % entries[level] )
            parent = parent.addMenu(entries[level],icon="gimmicks.png")
        
        elif (level == numLevels):
            #
            # register command
            #
            #nuke.debug(  "register command ")
            parent.addCommand(self.name,"kellerGimmicks.createGimmick(\"%s\")" % self.file,icon="gimmicks.png")
            
            self.menuEntry = (parent, self.name)
            
        #else:
            # done
        #    return
            
        # continue
        self._registerMenuInternal(entries, level+1, numLevels, parent)    
           
    
    def getMenuLocation(self, menuString):
        self.menuLocation
    
    
    def pasteGimmick(self):
        pass
    
    def _saveGimmickData(self):
        
        #return
        with open(self.file, 'a+') as f:
            content = f.read()
            f.seek(0,0)
            
            print (self._gimmickData)
            for key in self._gimmickData.keys():
                f.write("# %s=%s\n" % (key, self._gimmickData[key]))
            
        f.close()
           
    
    @staticmethod
    def loadFromFile(file):

        file = os.path.normpath(file)
        gimmick = KellerGimmick(file)

        #f = open(file,'r')
        #script = f.read()
        #f.close()
        #import re   
        
        #for line in script.split("\n"):
        #    tokens = line.strip().split()
            
            #if ( (len(tokens)>0) and (tokens[0].startswith(_MENU_KNOB_NAME_)) ):
            #    gimmick.addMenuLocation(tokens[1])
                
            #if ( (len(tokens)>0) and (tokens[0].startswith("name")) ):
            #    gimmick.setName(tokens[1])
            
        #gimmick.registerMenus()
        #match = re.findall("_kMenu\d*\s*(?P<menu>[a-zA-Z0-9_|]*)\s*", script)
                 
        
        
        return gimmick


#def createGimmick(file):
#    nuke.nodePaste(file)
    
def updateGimmicks():
    removeGimmicks(GIMMICK_BASEDIR)
    registerGimmicks(GIMMICK_BASEDIR)
      
def saveGimmick():
    
    selection = nuke.selectedNodes();
    
    if len(selection) == 0:
        nuke.message("No node selected")
        return
    
    
    defaultName =  "customTemplate" + GIMMICK_EXT
    
    folderProposal = GIMMICK_BASEDIR
    if len(selection) == 1:
        
        n = selection[0]
        if isinstance(n, nuke.Group):
            # use name of group by default
            defaultName =  n.name() + GIMMICK_EXT
            #nuke.message("Node must be a group type")
            folderProposal = os.path.join(GIMMICK_BASEDIR, GIMMICK_GROUP_SUBDIR)
    else:
        folderProposal = os.path.join(GIMMICK_BASEDIR, GIMMICK_TEMPLATE_SUBDIR)
        
        
        
    saveFile = nuke.getFilename("Save...", pattern="*.gimmick", default=os.path.join(folderProposal, defaultName), type="save")
    
    if saveFile is None:
        return
    
    if not saveFile.endswith(".gimmick"):
        saveFile = saveFile + ".gimmick"
    
    if os.path.isdir(saveFile):
        # is already a dir, append the filename
        saveFile = os.path.join(saveFile, defaultName)
    else:
        saveFile = saveFile
    
    
    gimmick = KellerGimmick()
    
    creatorName = nuke.getInput("Enter your name:","")
    if creatorName:
        gimmick.addData("Creator", creatorName)
  
        
    
    if os.path.exists(saveFile):
        if not nuke.ask("File exists, overwrite?"):
            return
        backupFile(saveFile)    
        
    gimmick._saveAs(saveFile)
    gimmick._registerMenu()
    
    
        
    # register new gimmick
    # TODO

def backupFile(file):
    import shutil
    try:
        shutil.copy(file, file+".bak")
    except:
        nuke.debug("Cannot create backup of gimmick %s" % file)
   
def removeGimmicks(folder):
    # TODO: retrieve list of gimmicks and remove from menu
    gimmicks = KellerPluginManager.getServiceData(SERVICE_GIMMICKS)
    
    for gimmick in gimmicks.values():
        print ("removing %s" % gimmick)
        gimmick.removeFromMenu()
    
    KellerPluginManager.setServiceData(SERVICE_GIMMICKS, dict())
    
def createGimmick(file):
    nuke.nodePaste(file)
        
    
def registerGimmicks(folder, menu=None):
   
    
    if (menu is None):
        menu = list()
        #menu = nuke.menu("Nodes")
    
    files = os.listdir(folder)
    
    for file in files:
        absfile = os.path.join(folder, file)
        
        if file.endswith(GIMMICK_EXT):
            # register command
            gimmick = KellerGimmick.loadFromFile(absfile)
            gimmick._registerMenu()
            
            
            gimmicks = KellerPluginManager.getServiceData(SERVICE_GIMMICKS)
            gimmicks[gimmick.getName()] = gimmick
            #menu.addCommand(gimmick.getName(),"kellerGimmicks.createGimmick(\"%s\")" % gimmick.getFile())
            # create gimmick
            #kGimmick = KellerGimmick.parseFromFile(os.path.join(folder,file))
            
        if os.path.isdir(absfile):
            # create menu
            #menu = menu.addMenu(file)
            menu.append(file)
            
            # recurse
            registerGimmicks(absfile,  menu=menu,)
            
        
            
if __name__ == "__main__":
    #print ("start")
    registerGimmicks("p:/env/nuke/_workgroup/_Projects/temp_schnelli/gimmicks")