# -*- coding: utf-8 -*-

# Copyright (c) 2003 - 2006 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the handler class for reading an XML project file.
"""

import os
import pickle

from Config import projectFileFormatVersion
from XMLHandlerBase import XMLHandlerBase

class ProjectHandler(XMLHandlerBase):
    """
    Class implementing a sax handler to read an XML project file.
    """
    def __init__(self, project):
        """
        Constructor
        
        @param project Reference to the project object to store the
                information into.
        """
        XMLHandlerBase.__init__(self)
        
        self.startDocumentSpecific = self.startDocumentProject
        
        self.elements.update({
            'Project' : (self.startProject, self.defaultEndElement),
            'ProgLanguage' : (self.startProgLanguage, self.endProgLanguage),
            'UIType' : (self.defaultStartElement, self.endUIType),
            'Description' : (self.defaultStartElement, self.endDescription),
            'Version' : (self.defaultStartElement, self.endVersion),
            'Author' : (self.defaultStartElement, self.endAuthor),
            'Email' : (self.defaultStartElement, self.endEmail),
            'TranslationPrefix' : (self.startTranslationPrefix, self.endTranslationPrefix),
            'VcsType' : (self.defaultStartElement, self.endVcsType),
            'VcsOptions' : (self.defaultStartElement, self.endVcsOptions),
            'VcsOtherData' : (self.defaultStartElement, self.endVcsOtherData),
            'Eric3DocParams' : (self.defaultStartElement, self.endEric3DocParams),
            'Eric3ApiParams' : (self.defaultStartElement, self.endEric3ApiParams),
            'HappyDocParams' : (self.defaultStartElement, self.defaultEndElement),
            'Dir' : (self.defaultStartElement, self.endDir),
            'Name' : (self.defaultStartElement, self.endName),
            'Source' : (self.startSource, self.endSource),
            'Form' : (self.startForm, self.endForm),
            'Translation' : (self.startTranslation, self.endTranslation),
            'Interface' : (self.startInterface, self.endInterface),
            'Other' : (self.startOther, self.endOther),
            'MainScript' : (self.startMainScript, self.endMainScript),
            'FiletypeAssociation' : (self.startFiletypeAssociation, self.defaultEndElement),
            'CxfreezeParams' : (self.defaultStartElement, self.endCxfreezeParams),
            'PyLintParams' : (self.defaultStartElement, self.endPyLintParams),
        })
    
        self.project = project
        
    def startDocumentProject(self):
        """
        Handler called, when the document parsing is started.
        """
        self.pathStack = []
        
    ###################################################
    ## below follow the individual handler functions
    ###################################################
    
    def startProgLanguage(self, attrs):
        """
        Handler method for the "Source" start tag.
        
        @param attrs list of tag attributes
        """
        mixedLanguage = int(attrs.get("mixed", "0"))
        self.project.pdata["MIXEDLANGUAGE"] = [mixedLanguage]
        self.buffer = ""
        
    def endProgLanguage(self):
        """
        Handler method for the "ProgLanguage" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["PROGLANGUAGE"] = [self.buffer]
        
    def endUIType(self):
        """
        Handler method for the "UIType" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["UITYPE"] = [self.buffer]
        
    def endDescription(self):
        """
        Handler method for the "Description" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["DESCRIPTION"] = self.buffer.split(os.linesep)
        
    def endVersion(self):
        """
        Handler method for the "Version" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["VERSION"] = [self.buffer]
        
    def endAuthor(self):
        """
        Handler method for the "Author" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["AUTHOR"] = [self.buffer]
        
    def endEmail(self):
        """
        Handler method for the "Email" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["EMAIL"] = [self.buffer]
        
    def endVcsType(self):
        """
        Handler method for the "VcsType" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.project.pdata["VCS"] = [self.buffer]
        
    def endVcsOptions(self):
        """
        Handler method for the "VcsOptions" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["VCSOPTIONS"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'VcsOptions'):
                    self.project.pdata["VCSOPTIONS"] = []
                else:
                    self.project.pdata["VCSOPTIONS"] = [eval(self.buffer)]
        else:
            self.project.pdata["VCSOPTIONS"] = []
        
    def endVcsOtherData(self):
        """
        Handler method for the "VcsOtherData" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["VCSOTHERDATA"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'VcsOtherData'):
                    self.project.pdata["VCSOTHERDATA"] = []
                else:
                    self.project.pdata["VCSOTHERDATA"] = [eval(self.buffer)]
        else:
            self.project.pdata["VCSOTHERDATA"] = []
        
    def endEric3DocParams(self):
        """
        Handler method for the "Eric3DocParams" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["ERIC3DOCPARMS"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'Eric3DocParams'):
                    self.project.pdata["ERIC3DOCPARMS"] = []
                else:
                    self.project.pdata["ERIC3DOCPARMS"] = [eval(self.buffer)]
        else:
            self.project.pdata["ERIC3DOCPARMS"] = []
        
    def endEric3ApiParams(self):
        """
        Handler method for the "Eric3ApiParams" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["ERIC3APIPARMS"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'Eric3ApiParams'):
                    self.project.pdata["ERIC3APIPARMS"] = []
                else:
                    self.project.pdata["ERIC3APIPARMS"] = [eval(self.buffer)]
        else:
            self.project.pdata["ERIC3APIPARMS"] = []
        
    def endCxfreezeParams(self):
        """
        Handler method for the "CxfreezeParams" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["CXFREEZEPARMS"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'CxfreezeParams'):
                    self.project.pdata["CXFREEZEPARMS"] = []
                else:
                    self.project.pdata["CXFREEZEPARMS"] = [eval(self.buffer)]
        else:
            self.project.pdata["CXFREEZEPARMS"] = []
        
    def endPyLintParams(self):
        """
        Handler method for the "PyLintParams" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        if self.buffer:
            if self.version > '3.8':
                self.project.pdata["PYLINTPARMS"] = [pickle.loads(self.buffer)]
            else:
                if self.project.checkSecurityString(self.buffer, 'PyLintParams'):
                    self.project.pdata["PYLINTPARMS"] = []
                else:
                    self.project.pdata["PYLINTPARMS"] = [eval(self.buffer)]
        else:
            self.project.pdata["PYLINTPARMS"] = []
        
    def endDir(self):
        """
        Handler method for the "Dir" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.pathStack.append(self.buffer)
        
    def endName(self):
        """
        Handler method for the "Name" end tag.
        """
        self.buffer = self.utf8_to_code(self.buffer)
        self.pathStack.append(self.buffer)
        
    def startTranslationPrefix(self, attrs):
        """
        Handler method for the "TranslationPrefix" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endTranslationPrefix(self):
        """
        Handler method for the "TranslationPrefix" end tag.
        """
        path = self.buildPath()
        self.project.pdata["TRANSLATIONPREFIX"].append(path)
        
    def startSource(self, attrs):
        """
        Handler method for the "Source" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endSource(self):
        """
        Handler method for the "Source" end tag.
        """
        path = self.buildPath()
        self.project.pdata["SOURCES"].append(path)
        
    def startForm(self, attrs):
        """
        Handler method for the "Form" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endForm(self):
        """
        Handler method for the "Form" end tag.
        """
        path = self.buildPath()
        self.project.pdata["FORMS"].append(path)
        
    def startTranslation(self, attrs):
        """
        Handler method for the "Translation" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endTranslation(self):
        """
        Handler method for the "Translation" end tag.
        """
        path = self.buildPath()
        self.project.pdata["TRANSLATIONS"].append(path)
        
    def startInterface(self, attrs):
        """
        Handler method for the "Interface" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endInterface(self):
        """
        Handler method for the "Interface" end tag.
        """
        path = self.buildPath()
        self.project.pdata["INTERFACES"].append(path)
        
    def startOther(self, attrs):
        """
        Handler method for the "Other" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endOther(self):
        """
        Handler method for the "Other" end tag.
        """
        path = self.buildPath()
        self.project.pdata["OTHERS"].append(path)
        
    def startMainScript(self, attrs):
        """
        Handler method for the "MainScript" start tag.
        
        @param attrs list of tag attributes
        """
        self.pathStack = []
        
    def endMainScript(self):
        """
        Handler method for the "MainScript" end tag.
        """
        path = self.buildPath()
        self.project.pdata["MAINSCRIPT"] = [path]
        
    def startFiletypeAssociation(self, attrs):
        """
        Handler method for the "FiletypeAssociation" start tag.
        
        @param attrs list of tag attributes
        """
        pattern = attrs.get("pattern", "")
        filetype = attrs.get("type", "OTHERS")
        if pattern:
            self.project.pdata["FILETYPES"][pattern] = filetype
        
    def buildPath(self):
        """
        Private method to assemble a path.
        
        @return The ready assembled path. (string)
        """
        path = ""
        if self.pathStack and not self.pathStack[0]:
            self.pathStack[0] = os.sep
        for p in self.pathStack:
            path = os.path.join(path, p)
        return path
        
    def startProject(self, attrs):
        """
        Handler method for the "Project" start tag.
        
        @param attrs list of tag attributes
        """
        self.version = attrs.get('version', projectFileFormatVersion)
        
    def getVersion(self):
        """
        Public method to retrieve the version of the project.
        
        @return String containing the version number.
        """
        return self.version
