import re

class XMLTag:
    def __init__(self, name, data):
        self._name = name
        self._children = []
        self.setData(data)
        
    def name(self):
        return self._name

    def setData(self, data):
        self._data = data
        
    def data(self):
        return self._data

    def hasChildren(self):
        return len( self._children ) > 0
        
    def addChildTag(self, tag):
        self._children.append(tag)
        
    def children(self):
        return self._children
    
    def tagWithName(self, name):
        for child in self._children:
            if child.name() == name:
                return child

        return None
        
    def display(self, indent = 0):
        for tag in self._children:
            for i in range(indent):
                print "\t",
            print tag.name()
            if tag.hasChildren():
                tag.display(indent+1)
            else:
                print tag.data()


class SimpleXMLParser:
    def __init__(self):
        self._rootTag = XMLTag('', '')

    def parseNextTag(self, data):

        openTagRE = re.compile(r"<\w*>")
                
        openFind = openTagRE.search(data)
        if openFind:
            openEnd = openFind.end()
    
            tagName = openFind.group()[1:-1]
                
            closeTagRE = re.compile("</"+tagName+">")
            closeFind = closeTagRE.search(data[openEnd:])
            if closeFind:

                endPoint = closeFind.start() + openEnd
                insideTag = data[openEnd:endPoint]    

                return (data[endPoint:], tagName, insideTag)

        return ("", "", "")
         
    def parse(self, data):
        rest = data

        while len(rest) > 0:            
            (rest, tagName, insideTag) = self.parseNextTag(rest)
            
            if len(tagName) > 0:
                tag = XMLTag(tagName, insideTag)
                
                self._rootTag.addChildTag(tag)
                                
                self.parseChild(tag, insideTag)
                
                
    def parseChild(self, parentTag, data):
        rest = data
        while len(rest) > 0:            
            (rest, tagName, insideTag) = self.parseNextTag(rest)
            
            if len(tagName) > 0:
                tag = XMLTag(tagName, insideTag)
                
                parentTag.addChildTag(tag)
                                
                self.parseChild(tag, insideTag)
                    
    def rootTag(self):
        return self._rootTag


class CSDParser:
    def __init__(self):
        pass

    def open(self, name):
        file = open(name)
        fileData = file.read()
        file.close()

        self.xml = SimpleXMLParser()
        self.xml.parse(fileData)
        #xml.rootTag().display()

        synthTag = self.xml.rootTag().tagWithName('CsoundSynthesizer')
        self.orcTag = synthTag.tagWithName('CsInstruments')
        self.scoTag = synthTag.tagWithName('CsScore')

    def orchestra(self):
        return self.orcTag.data()

    def score(self):
        return self.scoTag.data()

    def customConfig(self):
        pass
        
    def setOrchestra(self, orc):        
        self.orcTag.setData(orc)
        
    def setScore(self, sco):            
        self.scoTag.setData(sco)

    def setCustomConfig(self, sco):            
        #self.scoTag.setData(sco)
        pass

    def write(self, name):
        outputStr = self.serialize( self.xml.rootTag() )

        file = open(name, "w")
        file.write(outputStr)
        file.close()
        
    def serialize(self, tag):
        str = ""
        
        for childTag in tag.children():
            str += "<"+childTag.name()+">"
            if childTag.hasChildren():
                str += "\n"            
                str += self.serialize(childTag)
            else:
                str += childTag.data()
            str += "</"+childTag.name()+">\n"
                
        return str
    