# -*- coding: ISO-8859-1 -*-
""" capellaScript -- Paul Villiger
>>> Pedalen-Klammern

    Das Skript erzeugt unter den markierten Noten eine Pedalen-Klammer. Die Klammerenden lassen sich auswählen.
    Die Klammern können über die ganze Partitur neu berechnet werden. |
    Spezialbehandlung: Klammerende wird bis zur nächsten Pause oder Note im Takt gezogen oder bis zum Taktstrich. Der gerade Strich wird bis zum Taktstrich nach der Note gezogen.||
    
    Zum Löschen müssen die Klammern mit TAB markiert werden. Die Klammern sind als Polygon (ohne Fläche) realisiert un darum ist eine Markierung mit der Maus nicht möglich.
    

<<<

History: 19.11.04 - Erste Ausgabe
         20.11.04 - Umstellung Tagformat
         12.04.05 - Klammerende bis Taktstrich oder nächste Note
                  - Linie bis Taktstrich
         
"""

scriptTag = '21793-'
# Die nächsten vier Stellen des Tags werden mit Objektinformationen aufgefüllt
# 1000er Form links
# 100er  Form rechts
# 10er, einer: über Anzahl Noten

def getCursor():
    sel = curSelection()
    result = ((0,0,0,0),(0,0,0,0))
    # messageBox('test',str(sel))
    if sel == 0:
        return result
    result = sel
    return result


def createPedalBrackets(typL, typR,d,y):
    pw = 0.5   # peakWidth /2
    if (typL, typR) == (0,0): # links offen, rechts offen  ____
        bracket = {'type': 'polygon',
                      'x': [-1, d+2, -1],
                      'y': [ y, y,   y]}
    elif (typL, typR) == (1,0): #links zu, rechts offen  |____
        bracket = {'type': 'polygon',
                      'x': [-1,  -1, d+2, -1],
                      'y': [ y-1, y, y,    y]}
    elif (typL, typR) == (1,1): #links zu, rechts zu    |____|
        bracket = {'type': 'polygon',
                      'x': [-1,  -1, d+2, d+2, d+2, -1],
                      'y': [ y-1, y, y,   y-1, y,  y]}
    elif (typL, typR) == (0,1): #links offen, rechts zu  ____|
        bracket = {'type': 'polygon',
                      'x': [-1, d+2, d+2, d+2, -1],
                      'y': [ y, y,   y-1, y,    y]}
    elif (typL, typR) == (1,2): #links zu, rechts schräg |___/
        bracket = {'type': 'polygon',
                      'x': [-1,  -1, d+0.5-pw, d+0.5, d+0.5-pw, -1],
                      'y': [ y-1, y, y,        y-1,   y,         y]}
    elif (typL, typR) == (2,2): #links schräg, rechts schräg \___/
        bracket = {'type': 'polygon',
                      'x': [0.5,  0.5+pw, d+0.5-pw, d+0.5, d+0.5-pw, 0.5+pw],
                      'y': [ y-1,  y,  y,     y-1,   y,      y]}
    elif (typL, typR) == (2,0): #links schräg, rechts offen \____
        bracket = {'type': 'polygon',
                      'x': [0.5,  0.5+pw, d+2, 0.5+pw],
                      'y': [y-1,    y,   y,  y]}
    elif (typL, typR) == (0,2): #links offen, rechts schräg  ____/
        bracket = {'type': 'polygon',
                      'x': [-1, d+0.5-pw, d+0.5, d+0.5-pw, -1],
                      'y': [ y, y,        y-1,   y,         y]}
    elif (typL, typR) == (2,1): #links schräg, rechts zu \___|
        bracket = {'type': 'polygon',
                      'x': [0.5,  0.5+pw, d+2, d+2, d+2, 0.5+pw],
                      'y': [ y-1,  y,  y,     y-1,   y,   y]}
        
    return bracket


        
from caplib.capDOM import ScoreChange
import tempfile

if activeScore():
    options = ScriptOptions() 
    opt = options.get()
    formLeft = int(opt.get('pbFormLeft','1'))
    formRight = int(opt.get('pbFormRight','1'))
    vertDist = opt.get('pbVertDist','5')
    lineWidth = opt.get('pbLineWidth','1')

    formLeft  = Radio(['_____','|____','\____'], value= formLeft, text= 'Links')
    formRight = Radio(['_____','____|','____/'], value= formRight, text= 'Rechts')
    vertDist  = Edit(vertDist,  width = 5)
    lineWidth = Edit(lineWidth, width = 5)
    refresh   = CheckBox('Klammern neu berechnen', value = False)
    dlg = Dialog('Pedalen-Klammern',
                 VBox([HBox([formLeft,
                             formRight]),
                       Label(''),
                       HBox([Label('Abstand von der Mittellinie', width = 20, padding = 8),
                             vertDist]),
                       HBox([Label('Linienstärke (1..5)', width = 20, padding = 8),
                             lineWidth]),
                       Label(''),
                       refresh,
                       Label(''),
                       
                     ])
                 )
    
    if dlg.run():
        formLeft = formLeft.value()
        formRight = formRight.value()
        vertDist = float(vertDist.value())
        lineWidth = float(lineWidth.value())
        opt['pbFormLeft'] = str(formLeft)
        opt['pbFormRight'] = str(formRight)
        opt['pbVertDist'] = str(vertDist)
        opt['pbLineWidth'] = str(lineWidth)
        options.set(opt)

        if not refresh.value():
            ((sy1, st1, vo1, ob1),(sy2, st2, vo2, ob2))=getCursor()
            if ob1 > ob2:
                obx = ob1
                ob1 = ob2
                ob2 = obx
            if ob1 <> ob2:
                activeVoice = activeScore().system(sy1).staff(st1).voice(vo1)
                pos1 = activeVoice.noteObj(ob1).posX()
                pos2 = activeVoice.noteObj(ob2-1).posX()
                # Korrekturen / Spezialfälle
                # gerade Linie rechter Rand -> auf Taktstrich aufhören
                object2 = activeVoice.noteObj(ob2-1)
                if formRight in [0,1] and object2.implBarline(): # and ob2 == activeVoice.nNoteObjs():
                    pos2 = object2.implBarline().posX() - 2.2
                # Ende vor Pause -> kurz davor aufhören
                if formRight == 1 and ob2 < activeVoice.nNoteObjs() and not object2.implBarline() and (activeVoice.noteObj(ob2).isRest() or activeVoice.noteObj(ob2).isChord()):
                    pos2 = activeVoice.noteObj(ob2).posX() - 3

                dist = pos2 - pos1
                object1 = activeVoice.noteObj(ob1)
                bracket = createPedalBrackets(formLeft,formRight,dist,vertDist)
                bracket['lineWidth'] = lineWidth / 10.0
                bracket['tag'] = scriptTag + str(1000 * formLeft +100* formRight +ob2 - ob1)
                # messageBox('test',bracket['tag']+' '+str(formLeft)+' '+str(formRight))
                object1.addDrawObj(bracket)
        else:
            for sy1 in range(activeScore().nSystems()):
                system = activeScore().system(sy1)
                for st1 in range(system.nStaves()):
                    staff = system.staff(st1)
                    for vo1 in range(staff.nVoices()):
                        activeVoice = staff.voice(vo1)
                        for ob1 in range(activeVoice.nNoteObjs()):
                            ob = activeVoice.noteObj(ob1)
                            for i in range(ob.nDrawObjs()):
                                actDrawObj = ob.drawObj(i)
                                if 'tag' in actDrawObj and scriptTag in actDrawObj['tag'] and actDrawObj['type'] == 'polygon':
                                    obTag = actDrawObj['tag'][len(scriptTag):]
                                    formLeft = int(obTag) // 1000  # div 1000
                                    formRight = (int(obTag) // 100) % 10  # div 100 mod 10
                                    ob2 = ob1 + int(obTag) % 100
                                    # prüfen ob Balken über Zeilenrand hinausragt
                                    if ob2 > activeVoice.nNoteObjs():
                                        ob2 = activeVoice.nNoteObjs()                                        

                                    pos1 = activeVoice.noteObj(ob1).posX()
                                    pos2 = activeVoice.noteObj(ob2-1).posX()
                                    # Korrekturen / Spezialfälle
                                    # gerade Linie rechter Rand -> auf Taktstrich aufhören
                                    object2 = activeVoice.noteObj(ob2-1)
                                    if formRight in [0,1] and object2.implBarline():  # and ob2 == activeVoice.nNoteObjs():
                                        pos2 = object2.implBarline().posX() - 2.2
                                    # Ende vor Pause -> kurz davor aufhören
                                    if formRight == 1 and ob2 < activeVoice.nNoteObjs() and not object2.implBarline() and (activeVoice.noteObj(ob2).isRest() or activeVoice.noteObj(ob2).isChord()):
                                        pos2 = activeVoice.noteObj(ob2).posX() - 3

                                    dist = pos2 - pos1
                                    
                                    bracket = createPedalBrackets(formLeft,formRight,dist,vertDist)
                                    bracket['lineWidth'] = lineWidth / 10.0
                                    bracket['tag'] = scriptTag + str(1000 * formLeft +100* formRight +ob2 - ob1)
                                    ob.replaceDrawObj(i, bracket)


