# -*- coding: ISO-8859-1 -*-
""" capellaScript -- Paul Villiger
>>> Capella Font Selector

    Mit diesem Skript kann in den Einfachtexten der Capellafont gewechselt und
    der Style fest mit der Partitur verknüpft werden. Die Änderung erfolgt in der ganzen Partitur.|
    Auswahl Style: Der Style wird fest mit der Partitur verknüpft.
    Der Font wechselt auf den im Style definierten Zeichensatz.|
    Auswahl Font: Der Capellafont wird in der ganzen Partitur gewechselt.|
    |
    Anmerkung: Nach dem Ändern des Styles muss die Partitur neu geladen werden.
    Die Styledefinitionen werden aus capella.dat gelesen. capella.dat muss korrekt sein.
    

<<<
History:  15.12.2003 - Erstausgabe
          22.12.2003 - Undo aktualisiert
          17.03.2005 - Die Styles werden aus capella.dat gelesen
          19.03.2005 - Style wird auch in info eingetragen, wenn noch keine Info vorhanden ist
                     - Auswahl zwischen Style und Font
          20.03.2005 - Skriptfehler
          08.01.2012 - Anpassung an geänderten Ort von capella.dat seit capella 2008 für Vista/W7 (B. Jungmann) 
"""

from xml.dom.minidom import NodeList, Node, Element
from caplib.capDOM import ScoreChange
import tempfile, os, string, new

def gotoChild(self, name, new=False, first=False):
    newEl = None
    if new:
        pass
    else:
        for child in self.childNodes:
            if child.nodeType == child.ELEMENT_NODE and child.tagName == name:
                newEl = child
                break
    if newEl == None:
        newEl = doc.createElement(name)
        if first and self.firstChild:
            self.insertBefore(newEl, self.firstChild )            
        else:
            self.appendChild(newEl)
    return newEl
Node.gotoChild = new.instancemethod(gotoChild,None,Node)


capellaDat = {}
datFileName = os.path.join(getPersonalDataDir(), 'config\\data', 'capella.dat')
datFile = file(datFileName,'r')
datFileList = datFile.readlines()


schluessel = None
for n in range(len(datFileList)):
    s = datFileList[n]
    s = string.strip(string.split(s,'/n')[0]) # Zeilenumbruch abschneiden
    s = string.strip(string.split(s,';')[0]) # Kommentar abschneiden
    if '[' in s and ']' in s:
        schluessel = string.strip(string.split(datFileList[n],'[')[1])
        schluessel = string.strip(string.split(schluessel,']')[0])
        capellaDat[schluessel] = {}
    elif schluessel:
        if '=' in s:
            s = string.split(s,'=')
            capellaDat[schluessel][string.strip(s[0])] = string.strip(s[1])

styles = capellaDat.get('Styles',{'N':'0'})
capellaStyles = {}
for n in range(eval(styles.get('N','0')) + 1):
    s = styles.get(str(n),'')
    if s <> '':
        capellaStyles[s] = ''


capellaFontNames = {}
for s in capellaStyles:
    styleDef = capellaDat.get(s,None)
    if styleDef:
        fontName = styleDef.get('FontName','capella3')
        capellaFontNames[fontName] = '' 

        
def latin1_e(u):
    return u.encode('Latin-1')
def latin1_d(u):
    return u.decode('Latin-1')


class ScoreChange(ScoreChange):

    def changeScore(self, score):
        global doc, newFont
        doc = score.parentNode
        styleDict = capellaDat.get(newStyle, {})
        if styleSelect:
            newFont = styleDict.get('FontName', 'capella3')

            info = score.gotoChild('info', first=True)
            comment = info.gotoChild('comment')
            data = ''
            for child in comment.childNodes:
                if child.nodeType == child.TEXT_NODE:
                    data = latin1_e(child.data)
                    comment.removeChild(child)
            style = '<style>'+latin1_d(newStyle) + '</style>'
            if '<style>' in data and '</style>' in data:
                s1 = string.split(data, '<style>')[0]
                s2 = string.split(data, '</style>')[1]
                style = s1 + style + s2
            textNode = score.parentNode.createTextNode(style)
            comment.appendChild(textNode)

        fonts = score.getElementsByTagName('font')
        for font in fonts:
            if latin1_e(font.getAttribute('face')) in capellaFontNames:
                font.setAttribute('face',latin1_d(newFont))
            
def scriptDialog():
    global newStyle, newFont, styleSelect
    styleList = ComboBox( capellaStyles.keys(), padding = 8, value = 0, width=32 )
    fontList = ComboBox( capellaFontNames.keys(), padding = 8, value = 0, width=32 )

    select = Radio(['Style wechseln in Partitur und Einfachtext','Font wechseln in Einfachtext '], value = 0, width = 50)    
    
    dlg = Dialog('  -- Capella Style Selector --  ',
                  VBox([select,
                        HBox([Label('Style:', width = 10 ),styleList]),
                        HBox([Label('Font:', width = 10 ),fontList]),
                        Label(' '),
                        Label('Nach Stylewechsel muss die Partitur neu geladen werden'),
                        Label(' ')
                        ], padding = 10)
                    )

    if dlg.run():
        newStyle = capellaStyles.keys()[styleList.value()]
        newFont = capellaFontNames.keys()[fontList.value()]
        styleSelect = select.value() == 0
        
        return True
    else:
        return False
        
        
# Hauptprogramm:

if activeScore():

    if scriptDialog():
    
        activeScore().registerUndo("Capella Font Selector")
        tempInput = tempfile.mktemp('.capx')
        tempOutput = tempfile.mktemp('.capx')
        activeScore().write(tempInput)
    
        ScoreChange(tempInput, tempOutput)
    
        activeScore().read(tempOutput)
        os.remove(tempInput)
        os.remove(tempOutput)

