# -*- coding: ISO-8859-1 -*-
""" capellaScript -- von Hartmut Lemmel
>>> Font Replace

    Bestimmte Schriftarten und -größen von Einfachtexten können global ersetzt werden.
<<<
History:
29.12.2003  Erstversion
17.11.2004  Kein Fehler mehr wenn ein Textobjekt eine kommabehaftete Fontgröße hat
17.11.2004  Umwandlung von Texten in Kleinbuchstaben möglich
"""

from caplib.capDOM import ScoreChange
import tempfile

# string in int umwandeln bzw. 0 zurückliefern, wenn string leer oder nicht numerisch ist
def atoi(str):
    if len(str)>0 and str[0] in '0123456789':
      return int(str)
    else:
      return 0

# boolean in int umwandeln
def btoi(str):
    if len(str)>0 and str=='true':
      return 1
    else:
      return 0

def changefonts(items):
    counter=0
    for item in items:
#        messageBox('hallo','item, counter='+str(counter))
        fonts = item.getElementsByTagName('font')
        for font in fonts:
            size=int(float(font.getAttribute('height')))
            face=font.getAttribute('face')
            if 'capella' not in face:
             if findsize1==0 or findsize1==size or (findsize1<=size and size<=findsize2):
              if len(findfont)==0 or findfont[0]=='<' or findfont==face:
               if findital==2 or findital==btoi(font.getAttribute('italic')):
                if findbold==2 or findbold==(atoi(font.getAttribute('weight'))>=700):
                    if len(replfont)>0 and replfont[0]!='<':
                        font.setAttribute('face',replfont)
                    if replsize!=0:
                        font.setAttribute('height',str(replsize))
                    if replital==0:
                        font.setAttribute('italic','false')
                    elif replital==1:
                        font.setAttribute('italic','true')
                    if replbold==0:
                        font.setAttribute('weight','400')
                    elif replbold==1:
                        font.setAttribute('weight','700')
                    counter=counter+1
#    messageBox('fertig','counter='+str(counter))
    return counter

class ScoreChange(ScoreChange):
    def changeScore(self, score):
        global rangeInstr,rangeBarct,rangeGalry,rangePgobj,rangeText,rangeLyric,Sys1,Sys2,repllower
        counter = 0
        if rangeInstr: counter+=changefonts(score.getElementsByTagName('layout'))
        if rangeBarct: counter+=changefonts(score.getElementsByTagName('barCount'))
        if rangeGalry: counter+=changefonts(score.getElementsByTagName('gallery'))
        if rangePgobj: counter+=changefonts(score.getElementsByTagName('pageObjects'))
        if rangeText or rangeLyric:
            systems=score.getElementsByTagName('system')
            max=len(systems)
            if Sys1>0: Sys1-=1
            if Sys2==0 or Sys2>max: Sys2=max
#            messageBox('Schriftart global ersetzen:', 'sys = '+str(Sys1)+' bis '+str(Sys2)+', max='+str(max))
            for sys in systems[Sys1:Sys2]:
              voices=sys.getElementsByTagName('voice')
              for voice in voices:
                if rangeText:
#                    counter+=changefonts(texts)
                    for text in voice.getElementsByTagName('text'):
                        if changefonts([text]):
                            counter+=1
                            if repllower:
                                cnt=text.getElementsByTagName('content')[0]
                                cnt.firstChild.nodeValue=cnt.firstChild.nodeValue.lower()
                if rangeLyric: counter+=changefonts(voice.getElementsByTagName('lyricsSettings'))

        if counter==0: text='Es wurde kein passendes Textobjekt gefunden.'
        elif counter==1: text='Es wurde ein Textobjekt verändert.'
        else: text='Es wurden '+str(counter)+' Textobjekte verändert.'
        messageBox('Schriftart global ersetzen:', text)
           
def scriptDialog():
    global findfont,findsize1,findsize2,findital,findbold
    global replfont,replsize,replital,replbold,repllower
    global rangeInstr,rangeBarct,rangeGalry,rangePgobj,rangeText,rangeLyric,Sys1,Sys2
    options = ScriptOptions() 
    opt = options.get()  
    
    lablfindfont = Label('Schriftart',width=6)
    editfindfont = Edit (opt.get('findfont','<egal>'),width=20)
    linefindfont = HBox([lablfindfont,editfindfont],padding=8)
    lablfindsize1= Label('Größe',width=6)
    editfindsize1= Edit (opt.get('findsize1','<egal>'),width=6)
    lablfindsize2= Label('bis',width=1)
    editfindsize2= Edit (opt.get('findsize2',''),min=0,max=999,width=6)
    linefindsize = HBox([lablfindsize1,editfindsize1,lablfindsize2,editfindsize2],padding=8)
    radfindital = Radio(['nein','ja','egal'],text='kursiv',value=int(opt.get('findital','2')))
    radfindbold = Radio(['nein','ja','egal'],text='fett',value=int(opt.get('findbold','2')))
    linefindoptions = HBox([radfindital,radfindbold],padding=8)
    boxfind = VBox([linefindfont,linefindsize,linefindoptions],text='Suchen:',padding=1)

    lablreplfont = Label('Schriftart',width=6)
    editreplfont = Edit (opt.get('replfont','<unverändert>'),width=20)
    linereplfont = HBox([lablreplfont,editreplfont],padding=8)
    lablreplsize = Label('Größe',width=6)
    editreplsize = Edit (opt.get('replsize','<unverändert>'),width=10)
    linereplsize = HBox([lablreplsize,editreplsize],padding=8)
    radreplital = Radio(['nein','ja','unverändert'],text='kursiv',value=int(opt.get('replital','2')))
    radreplbold = Radio(['nein','ja','unverändert'],text='fett',value=int(opt.get('replbold','2')))
    linereploptions = HBox([radreplital,radreplbold],padding=8)
    chxrepllower = CheckBox('in Kleinbuchstaben umwandeln (nur Einfachtexte)', value=int(opt.get('repllower','0')))
    boxrepl = VBox([linereplfont,linereplsize,linereploptions,chxrepllower],text='Ersetzen:',padding=1)

    chxInstr = CheckBox('Instrumentenbezeichnungen', value=int(opt.get('rangeInstr','0')))
    chxBarct = CheckBox('Taktnummern',               value=int(opt.get('rangeBarct','0')))
    chxGalry = CheckBox('Einfachtexte in der Gallerie',     value=int(opt.get('rangeGalry','0')))
    chxPgobj = CheckBox('an Seiten verankerte Einfachtexte ', value=int(opt.get('rangePgobj','0')))
    boxrange1 = VBox([chxInstr,chxBarct,chxGalry,chxPgobj],padding=0)
    
    lablsys1 = Label('Systeme',width=3)
    editsys1 = Edit(opt.get('rangeSys1','1'),width=6)
    lablsys2 = Label('bis',width=1)
    editsys2 = Edit(opt.get('rangeSys2','<Ende>'),width=6)
    linesys  = HBox([lablsys1,editsys1,lablsys2,editsys2],padding=8)
    labltext = Label('',width=2)
    chxText  = CheckBox('Einfachtexte',              value=int(opt.get('rangeText','1')))
    linetext = HBox([labltext,chxText])
    labllyric= Label('',width=2)
    chxLyric = CheckBox('Liedtexte',                 value=int(opt.get('rangeLyric','0')))
    linelyric= HBox([labllyric,chxLyric])
    boxrange2= VBox([linesys,linetext,linelyric])

    boxrange = HBox([boxrange1,boxrange2],text='Suchbereiche:',padding=0)

    box1 = HBox([boxfind,boxrepl],padding=4)
    box = VBox([boxrange,box1],padding=4)
    dlg = Dialog('Schriftart global ersetzen:', box)

    if dlg.run():
        findfont = editfindfont.value()
        findsize1= atoi(editfindsize1.value())
        findsize2= atoi(editfindsize2.value())
        findital = radfindital.value()
        findbold = radfindbold.value()
        replfont = editreplfont.value()
        replsize = atoi(editreplsize.value())
        replital = radreplital.value()
        replbold = radreplbold.value()
        repllower= chxrepllower.value();
        rangeInstr=chxInstr.value();
        rangeBarct=chxBarct.value();
        rangeGalry=chxGalry.value();
        rangePgobj=chxPgobj.value();
        rangeText =chxText.value();
        rangeLyric=chxLyric.value();
        Sys1 =atoi(editsys1.value());
        Sys2 =atoi(editsys2.value());

        if findsize1==0: findsize1str='<egal>'
        else: findsize1str= str(findsize1)
        if findsize2==0: findsize2str=''
        else: findsize2str=str(findsize2)
        if replsize==0: replsizestr='<unverändert>'
        else: replsizestr=str(replsize)
        if Sys1==0: rangeSys1str='1'
        else: rangeSys1str=str(Sys1)
        if Sys2==0: rangeSys2str='<Ende>'
        else: rangeSys2str=str(Sys2)
        
        opt.update(dict(findfont=findfont,findsize1=findsize1str,findsize2=findsize2str,
                        findital=str(findital),findbold=str(findbold),replfont=replfont,
                        replsize=replsizestr,replital=str(replital),replbold=str(replbold),
                        repllower=str(repllower),
                        rangeInstr=str(rangeInstr),rangeBarct=str(rangeBarct),
                        rangeGalry=str(rangeGalry),rangePgobj=str(rangePgobj),
                        rangeText =str(rangeText ),rangeLyric=str(rangeLyric),                        
                        rangeSys1=rangeSys1str,rangeSys2=rangeSys2str))
        options.set(opt)
        return True
    else:
        return False
        
        
# Hauptprogramm:

if activeScore():

    if scriptDialog():
    
        activeScore().registerUndo("Font Replace")
        tempInput = tempfile.mktemp('.capx')
        tempOutput = tempfile.mktemp('.capx')
        activeScore().write(tempInput)
    
        ScoreChange(tempInput, tempOutput)
    
        activeScore().read(tempOutput)
        os.remove(tempInput)
        os.remove(tempOutput)

