# -*- coding: ISO-8859-1 -*-
""" capellaScript
>>> erstellt Kopfzeile, Fußzeile und bis zu zwei Titelzeilen
Im Dialogfenster können für jede dieser Zeilen ein linksbündiger, zentrierter und rechtsbündiger Text mit variabler Textgröße eingegeben werden.
Im Text können Platzhalter für Seitennummern und Instrumentenbezeichnung eingegeben werden.  
<<<
History:
17.11.2004  Erstversion
"""


from caplib.capDOM import ScoreChange
import tempfile

def getFirstElement(parent, *children):
    """ liefert von den genannten Elementen das erste, das vorkommt """
    for n in parent.childNodes:
        for c in children:
            if n.nodeType == parent.ELEMENT_NODE and n.tagName == c:
                return n
    return parent

def getElement(parent, *children):
     """ liefert Kind/Enkel/Urenkel..., z.B. grandchild = getElement(parent,'childname','grandchildname') """
     p = parent
     for c in children:
         found = 0
         for n in p.childNodes:
             if n.nodeType == parent.ELEMENT_NODE and n.tagName == c:
                 p = n
                 found = 1
                 break
         if not found: return 0
     return p

def delTagObjects(objects, tag):
        for basic in objects.getElementsByTagName('basic'):
            if basic.hasAttribute('tag'):
              oldtag=basic.getAttribute('tag')
#              messageBox('tag = '+tag, 'oldtag = '+oldtag)
              if tag in oldtag:
                basic.parentNode.parentNode.removeChild(basic.parentNode)


class ScoreChange(ScoreChange):
    def addTextObj(self,objects,x,y,halign,valign,pages,fontface,fontsize,text,makeframe,tag):
        # pages: Bitkombination aus
        #        1 erste Seite
        #        2 ungerade Seiten ab 3
        #        4 gerade Seiten
        # x,y: in mm
        # halign: -1=left, 0=center, 1=right
        # valign: 0=baseline, 1=top
     global partname, unit

     if tag!='': delTagObjects(objects,tag)    

     ybase=y
     fontheight=fontsize*25.4/72
     if valign==1:  # y gibt oberen Textrand an
           ybase+=fontheight
     else: y-=fontheight
     
     text=text.decode('Latin-1')
     text=text.replace('%',partname)
     if makeframe:
         width=len(text)*fontheight*0.55 # die Breite des Textobjekts kann leider nur geschätzt werden
         height=fontheight
         gap=fontheight/2
         if halign==1:
           x2=x
           x1=x2-width-4*gap
           x-=2*gap
         elif halign==0:
           x1=x-width/2-2*gap
           x2=x+width/2+2*gap
         else:
           x1=x
           x2=x+width+4*gap
           x+=2*gap
         y1=y
         y2=y1+height+2*gap
         ybase+=gap*0.8

     newobj = self.doc.createElement('drawObj')
     objects.appendChild(newobj) 
     txt = self.doc.createElement('text')
     newobj.appendChild(txt)
     txt.setAttribute('x',str(x/unit))
     txt.setAttribute('y',str(ybase/unit))
     if   halign==1: s='right'
     elif halign==0: s='center'
     else:          s='left'
     txt.setAttribute('align',s)
     cnt = self.doc.createElement('content')
     txt.appendChild(cnt)
     cnt.appendChild(self.doc.createTextNode(text))
     font = self.doc.createElement('font')
     txt.appendChild(font)
     font.setAttribute('face',fontface)
     font.setAttribute('height',str(fontsize))
     font.setAttribute('weight','0')
     font.setAttribute('pitchAndFamily','0')
     basic = self.doc.createElement('basic')
     newobj.appendChild(basic)
     if tag!='':
       basic.setAttribute('tag',tag) # das Tag-Attribut ist leider beim nächsten Skriptaufruf verschwunden (?!)
     if (pages&1)==0:
       basic.setAttribute('firstPage','false')
     if (pages&2)==0: 
       basic.setAttribute('oddPagesExceptFirst','false')
     if (pages&4)==0:
       basic.setAttribute('evenPages','false')

     if makeframe:
         newobj = self.doc.createElement('drawObj')
         objects.appendChild(newobj) 
         re = self.doc.createElement('rectangle')
         newobj.appendChild(re)
         re.setAttribute('x1',str(x1/unit))
         re.setAttribute('y1',str(y1/unit))
         re.setAttribute('x2',str(x2/unit))
         re.setAttribute('y2',str(y2/unit))
         basic = self.doc.createElement('basic')
         newobj.appendChild(basic)
         if tag!='':
           basic.setAttribute('tag',tag)
         if (pages&1)==0:
           basic.setAttribute('firstPage','false')
         if (pages&2)==0: 
           basic.setAttribute('oddPagesExceptFirst','false')
         if (pages&4)==0:
           basic.setAttribute('evenPages','false')

    def changeScore(self, score):
     global fontface, deleteold, not1stpage
     global h1text,h2text,h3text,h1size,h2size,h3size,h1pos,h2pos,h3pos,hmargin
     global s1text,s2text,s3text,s1size,s2size,s3size,s1pos,s2pos,s3pos
     global t1text,t2text,t3text,t1size,t2size,t3size,t1pos,t2pos,t3pos
     global f1text,f2text,f3text,f1size,f2size,f3size,f1pos,f2pos,f3pos,fmargin
     global partname, unit
     # Textpositionen berechnen   
     sl=getElement(score,'layout','distances','staffLines')
     unit=float(sl.getAttribute('pageObj'))
     page=getElement(score,'layout','pages')
     firstpagenumber = 1
     fst = page.getAttribute('first')
     if fst!='':
         firstpagenumber=int(fst)
     marginleft =float(page.getAttribute('left') )
     margintop  =float(page.getAttribute('top')  )
     marginright=float(page.getAttribute('right'))
     marginbottom=float(page.getAttribute('bottom'))
     pagewidth=210
     pageheight=297
     if page.getAttribute('landscape')=='true':
         pagewidth=297
         pageheight=210
     xleft=0 
     xright=pagewidth-marginleft-marginright  # bedruckbare Breite in mm
     xcenter=xright/2
     yheader=-1
     yfooter=pageheight-margintop
     xhleft=xleft
     xhright=xright
     if hmargin!='':
         xhleft+=int(hmargin)-marginleft
         xhright-=int(hmargin)-marginright
     xfleft=xleft
     xfright=xright
     if fmargin!='':
         xfleft+=int(fmargin)-marginleft
         xfright-=int(fmargin)-marginright

     

     # Name der ersten verwendeten Stimme ermitteln
     partname=''
     sys0=getElement(score,'systems','system')
     if sys0:         
      staff0 = getElement(sys0,'staves','staff')
      if staff0:
       layoutname = staff0.getAttribute('layout')
       layoutstaves=getElement(score,'layout','staves')
       for staffLayout in layoutstaves.getElementsByTagName('staffLayout'):
         descr=staffLayout.getAttribute('description')
         if layoutname == descr:
           for instr in staffLayout.getElementsByTagName('instrument'):
             partname = instr.getAttribute('name')
           break

     # pageObjects suchen/erstellen   
     pageobj=getElement(score,'pageObjects')    
     if pageobj:
         if deleteold:
             for o in pageobj.childNodes:
               if o.nodeType == o.ELEMENT_NODE:
                 if len(o.getElementsByTagName('text')) or len(o.getElementsByTagName('rectangle')):
                     pageobj.removeChild(o)
     else:
         pageobj=self.doc.createElement('pageObjects')
         # pageobj an der richtigen Stelle einsortieren
         refchild=getFirstElement(score,'barCount','systems')
         score.insertBefore(pageobj,refchild)

     # Textobjekte erstellen     
     on1stpage = 1
     if not1stpage: on1stpage=0
     if len(h1text):
       if ('#' in h1text) and (len(h3text)) and ('#' in h3text):
         leftpages=4
         rightpages=2|on1stpage
         if not (firstpagenumber & 1):
             leftpages=2|on1stpage
             rightpages=4
         self.addTextObj(pageobj,xhleft ,h1pos-margintop,-1,1, leftpages ,fontface,h1size,h1text,0,'4343-01')
         self.addTextObj(pageobj,xhright,h3pos-margintop, 1,1, rightpages,fontface,h3size,h3text,0,'4343-03')
         h3text=''       
       else:
         self.addTextObj(pageobj,xhleft  ,h1pos-margintop,-1,1, 6|on1stpage,fontface,h1size,h1text,0,'4343-01')
     if len(h2text):
         self.addTextObj(pageobj,xcenter,h2pos-margintop, 0,1, 6|on1stpage,fontface,h2size,h2text,0,'4343-02')
     if len(h3text):
         self.addTextObj(pageobj,xhright ,h3pos-margintop, 1,1, 6|on1stpage,fontface,h3size,h3text,0,'4343-03')
     if len(s1text):
         self.addTextObj(pageobj,xleft  ,s1pos-margintop,-1,1, 1,fontface,s1size,s1text,framepartname and ('%' in s1text),'4343-11')
     if len(s2text):
         self.addTextObj(pageobj,xcenter,s2pos-margintop, 0,1, 1,fontface,s2size,s2text,framepartname and ('%' in s2text),'4343-12')
     if len(s3text):
         self.addTextObj(pageobj,xright ,s3pos-margintop, 1,1, 1,fontface,s3size,s3text,framepartname and ('%' in s3text),'4343-13')
     if len(t1text):
         self.addTextObj(pageobj,xleft  ,t1pos-margintop,-1,1, 1,fontface,t1size,t1text,framepartname and ('%' in t1text),'4343-21')
     if len(t2text):
         self.addTextObj(pageobj,xcenter,t2pos-margintop, 0,1, 1,fontface,t2size,t2text,framepartname and ('%' in t2text),'4343-22')
     if len(t3text):
         self.addTextObj(pageobj,xright ,t3pos-margintop, 1,1, 1,fontface,t3size,t3text,framepartname and ('%' in t3text),'4343-23')
     if len(f1text):
       if ('#' in f1text) and (len(f3text)) and ('#' in f3text):
         leftpages=4
         rightpages=3
         if not (firstpagenumber & 1):
             leftpages=3
             rightpages=4
         self.addTextObj(pageobj,xfleft ,yfooter-f1pos,-1,0, leftpages ,fontface,f1size,f1text,0,'4343-31')
         self.addTextObj(pageobj,xfright,yfooter-f3pos, 1,0, rightpages,fontface,f3size,f3text,0,'4343-33')
         f3text=''       
       else:
         self.addTextObj(pageobj,xfleft ,yfooter-f1pos,-1,0, 7,fontface,f1size,f1text,0,'4343-31')
     if len(f2text):
         self.addTextObj(pageobj,xcenter,yfooter-f2pos, 0,0, 7,fontface,f2size,f2text,0,'4343-32')
     if len(f3text):
         self.addTextObj(pageobj,xfright,yfooter-f3pos, 1,0, 7,fontface,f3size,f3text,0,'4343-33')
     
def scriptDialog():
    global fontface, deleteold, not1stpage, framepartname
    global h1text,h2text,h3text,h1size,h2size,h3size,h1pos,h2pos,h3pos,hmargin
    global s1text,s2text,s3text,s1size,s2size,s3size,s1pos,s2pos,s3pos
    global t1text,t2text,t3text,t1size,t2size,t3size,t1pos,t2pos,t3pos                 
    global f1text,f2text,f3text,f1size,f2size,f3size,f1pos,f2pos,f3pos,fmargin
   
    options = ScriptOptions() 
    opt = options.get()  

    stcfontface = Label('Schriftart')
    edtfontface = Edit(opt.get('fontface','Times New Roman'),width=20)
    stcfontsize = Label('    Schriftgröße: wird bei jedem Textfeld definiert')
    boxfontface = HBox([stcfontface,edtfontface,stcfontsize],padding=8)
    chxdeleteold = CheckBox('alle alten Seitentexte löschen', value=int(opt.get('deleteold','1')))
    boxchx = HBox([chxdeleteold],padding=8)

    chxnot1stpage = CheckBox('1. Seite nicht', value=int(opt.get('not1stpage','1')))

    edth1text = Edit (opt.get('h1text','#'),width=20)
    stch1size = Label('Größe:')
    edth1size = Edit (str(opt.get('h1size',12)),min=0,max=99,width=3)
    stch1pos  = Label('  Position:')
    edth1pos  = Edit (str(opt.get('h1pos',10)),min=0,max=999,width=3)
    hboxh1    = HBox([stch1size,edth1size,stch1pos,edth1pos],padding=4)
    boxh1     = VBox([edth1text,hboxh1],padding=0)   
    edth2text = Edit (opt.get('h2text',''),width=20)
    stch2size = Label('Größe:')
    edth2size = Edit (str(opt.get('h2size',12)),min=0,max=99,width=3)
    stch2pos  = Label('  Position:')
    edth2pos  = Edit (str(opt.get('h2pos',10)),min=0,max=999,width=3)
    hboxh2    = HBox([stch2size,edth2size,stch2pos,edth2pos],padding=4)
    boxh2     = VBox([edth2text,hboxh2],padding=0)   
    edth3text = Edit (opt.get('h3text','#'),width=20)
    stch3size = Label('Größe:')
    edth3size = Edit (str(opt.get('h3size',12)),min=0,max=99,width=3)
    stch3pos  = Label('  Position:')
    edth3pos  = Edit (str(opt.get('h3pos',10)),min=0,max=999,width=3)
    hboxh3    = HBox([stch3size,edth3size,stch3pos,edth3pos],padding=4)
    boxh3     = VBox([edth3text,hboxh3],padding=0)
    stchmargin = Label('Seitlicher Randabstand: ')
    edthmargin = Edit(opt.get('hmargin',''),min=0, max=99, width=3)
    stchmargin2= Label('mm   (leeres Feld = normaler Randabstand)')
    boxhmargin = HBox([stchmargin,edthmargin,stchmargin2],padding=2)
    boxheader = VBox([chxnot1stpage,HBox([boxh1,boxh2,boxh3],padding=8),boxhmargin],padding=8, text='Kopfzeile')

    edts1text = Edit (opt.get('s1text',''),width=20)
    stcs1size = Label('Größe:')
    edts1size = Edit (str(opt.get('s1size',12)),min=0,max=99,width=3)
    stcs1pos  = Label('  Position:')
    edts1pos  = Edit (str(opt.get('s1pos',20)),min=0,max=999,width=3)
    hboxs1    = HBox([stcs1size,edts1size,stcs1pos,edts1pos],padding=4)
    boxs1     = VBox([edts1text,hboxs1],padding=0)
    edtt1text = Edit (opt.get('t1text',''),width=20)
    stct1size = Label('Größe:')
    edtt1size = Edit (str(opt.get('t1size',12)),min=0,max=99,width=3)
    stct1pos  = Label('  Position:')
    edtt1pos  = Edit (str(opt.get('t1pos',30)),min=0,max=999,width=3)
    hboxt1    = HBox([stct1size,edtt1size,stct1pos,edtt1pos],padding=4)
    boxt1     = VBox([edtt1text,hboxt1],padding=0)   
    edts2text = Edit (opt.get('s2text',''),width=20)
    stcs2size = Label('Größe:')
    edts2size = Edit (str(opt.get('s2size',12)),min=0,max=99,width=3)
    stcs2pos  = Label('  Position:')
    edts2pos  = Edit (str(opt.get('s2pos',20)),min=0,max=999,width=3)
    hboxs2    = HBox([stcs2size,edts2size,stcs2pos,edts2pos],padding=4)
    boxs2     = VBox([edts2text,hboxs2],padding=0)
    edtt2text = Edit (opt.get('t2text',''),width=20)
    stct2size = Label('Größe:')
    edtt2size = Edit (str(opt.get('t2size',12)),min=0,max=99,width=3)
    stct2pos  = Label('  Position:')
    edtt2pos  = Edit (str(opt.get('t2pos',30)),min=0,max=999,width=3)
    hboxt2    = HBox([stct2size,edtt2size,stct2pos,edtt2pos],padding=4)
    boxt2     = VBox([edtt2text,hboxt2],padding=0)
    edts3text = Edit (opt.get('s3text',''),width=20)
    stcs3size = Label('Größe:')
    edts3size = Edit (str(opt.get('s3size',12)),min=0,max=99,width=3)
    stcs3pos  = Label('  Position:')
    edts3pos  = Edit (str(opt.get('s3pos',20)),min=0,max=999,width=3)
    hboxs3    = HBox([stcs3size,edts3size,stcs3pos,edts3pos],padding=4)
    boxs3     = VBox([edts3text,hboxs3],padding=0)
    edtt3text = Edit (opt.get('t3text',''),width=20)
    stct3size = Label('Größe:')
    edtt3size = Edit (str(opt.get('t3size',12)),min=0,max=99,width=3)
    stct3pos  = Label('  Position:')
    edtt3pos  = Edit (str(opt.get('t3pos',30)),min=0,max=999,width=3)
    hboxt3    = HBox([stct3size,edtt3size,stct3pos,edtt3pos],padding=4)
    boxt3     = VBox([edtt3text,hboxt3],padding=0)
    chxframe  = CheckBox('Instrumentenbezeichnung umrahmen', value=int(opt.get('framepartname','1')))

    boxtitle = VBox([chxframe,HBox([boxs1,boxs2,boxs3],padding=8), HBox([boxt1,boxt2,boxt3],padding=8)],padding=8,text='Titel (nur erste Seite)')

    edtf1text = Edit (opt.get('f1text',''),width=20)
    stcf1size = Label('Größe:')
    edtf1size = Edit (str(opt.get('f1size',12)),min=0,max=99,width=3)
    stcf1pos  = Label('  Position:')
    edtf1pos  = Edit (str(opt.get('f1pos',30)),min=0,max=999,width=3)
    hboxf1    = HBox([stcf1size,edtf1size,stcf1pos,edtf1pos],padding=4)
    boxf1     = VBox([edtf1text,hboxf1],padding=0)   
    edtf2text = Edit (opt.get('f2text',''),width=20)
    stcf2size = Label('Größe:')
    edtf2size = Edit (str(opt.get('f2size',12)),min=0,max=99,width=3)
    stcf2pos  = Label('  Position:')
    edtf2pos  = Edit (str(opt.get('f2pos',30)),min=0,max=999,width=3)
    hboxf2    = HBox([stcf2size,edtf2size,stcf2pos,edtf2pos],padding=4)
    boxf2     = VBox([edtf2text,hboxf2],padding=0)   
    edtf3text = Edit (opt.get('f3text',''),width=20)
    stcf3size = Label('Größe:')
    edtf3size = Edit (str(opt.get('f3size',12)),min=0,max=99,width=3)
    stcf3pos  = Label('  Position:')
    edtf3pos  = Edit (str(opt.get('f3pos',30)),min=0,max=999,width=3)
    hboxf3    = HBox([stcf3size,edtf3size,stcf3pos,edtf3pos],padding=4)
    boxf3     = VBox([edtf3text,hboxf3],padding=0)   
    stcfmargin = Label('Seitlicher Randabstand: ')
    edtfmargin = Edit(opt.get('fmargin',''),min=0, max=99, width=3)
    stcfmargin2= Label('mm   (leeres Feld = normaler Randabstand)')
    boxfmargin = HBox([stcfmargin,edtfmargin,stcfmargin2],padding=2)
    boxfooter = VBox([HBox([boxf1,boxf2,boxf3],padding=8),boxfmargin],padding=8, text='Fußzeile')

    remark = Label('Position = Abstand vom oberen Blattrand in mm (bei der Fußzeile vom unteren)\n"%"=Bezeichnung des ersten Instruments, das im ersten System verwendet wird.\n"#"=Seitenzahl. Wenn links und rechts angegeben, werden gerade Zahlen links, ungerade rechts dargestellt.\t\t')

    box = VBox([boxfontface,boxchx,remark,boxheader,boxtitle,boxfooter],padding=4)
    dlg = Dialog('Seitenzahlen und Titel', box)

    if dlg.run():
        fontface=edtfontface.value()
        deleteold=chxdeleteold.value()
        not1stpage=chxnot1stpage.value()
        h1text=edth1text.value()
        h1size=int(edth1size.value())
        h1pos =int(edth1pos.value())
        s1text=edts1text.value()
        s1size=int(edts1size.value())
        s1pos =int(edts1pos.value())
        t1text=edtt1text.value()
        t1size=int(edtt1size.value())
        t1pos =int(edtt1pos.value())
        f1text=edtf1text.value()
        f1size=int(edtf1size.value())
        f1pos =int(edtf1pos.value())
        
        h2text=edth2text.value()
        h2size=int(edth2size.value())
        h2pos =int(edth2pos.value())
        s2text=edts2text.value()
        s2size=int(edts2size.value())
        s2pos =int(edts2pos.value())
        t2text=edtt2text.value()
        t2size=int(edtt2size.value())
        t2pos =int(edtt2pos.value())
        f2text=edtf2text.value()
        f2size=int(edtf2size.value())
        f2pos =int(edtf2pos.value())
        
        h3text=edth3text.value()
        h3size=int(edth3size.value())
        h3pos =int(edth3pos.value())
        s3text=edts3text.value()
        s3size=int(edts3size.value())
        s3pos =int(edts3pos.value())
        t3text=edtt3text.value()
        t3size=int(edtt3size.value())
        t3pos =int(edtt3pos.value())
        f3text=edtf3text.value()
        f3size=int(edtf3size.value())
        f3pos =int(edtf3pos.value())
        fmargin=edtfmargin.value();
        hmargin=edthmargin.value();
        framepartname=int(chxframe.value())
        opt.update(dict(fontface=fontface, deleteold=deleteold, not1stpage=not1stpage,
            h1text=h1text,h2text=h2text,h3text=h3text,h1size=h1size,h2size=h2size,h3size=h3size,
            h1pos=h1pos,h2pos=h2pos,h3pos=h3pos,
            s1text=s1text,s2text=s2text,s3text=s3text,s1size=s1size,s2size=s2size,s3size=s3size,
            s1pos=s1pos,s2pos=s2pos,s3pos=s3pos,
            t1text=t1text,t2text=t2text,t3text=t3text,t1size=t1size,t2size=t2size,t3size=t3size,
            t1pos=t1pos,t2pos=t2pos,t3pos=t3pos,
            f1text=f1text,f2text=f2text,f3text=f3text,f1size=f1size,f2size=f2size,f3size=f3size,
            f1pos=f1pos,f2pos=f2pos,f3pos=f3pos,
            framepartname=framepartname, fmargin=fmargin, hmargin=hmargin))
        options.set(opt)
        return True
    else:
        return False


if activeScore():
    if scriptDialog():    
        activeScore().registerUndo("Seitenzahlen setzen")
        tempInput = tempfile.mktemp('.capx')
        tempOutput = tempfile.mktemp('.capx')
        activeScore().write(tempInput)

        ScoreChange(tempInput, tempOutput)
#        messageBox(tempInput, tempOutput)

        activeScore().read(tempOutput)
        os.remove(tempInput)
        os.remove(tempOutput)

