# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 17.01.2004 Andreas Herzog
>>> MacMusic - Dudelsacknotation

    Mit diesem Skript können automatisch Noten für Dudelsäcke formatiert werden.|
        |
    Bei der Notation von Dudelsack-Stücken werden die Verzierung (Gracenotes) normalerweise  als 32stel dargestellt. Wer allerdings eine
    Melodie mit 32stel-Noten hat, der kann auch 64stel als Gracenotes darstellen lassen.
    Die Gracenotes werden klein, mit Hals nach oben und ohne Wert formiert. Die anderen Noten
    werden automatisch nach unten ausgerichtet.|
    

        |Vielen Dank für Korrektur und Hilfe an: |Paul Villiger

<<<
History: 20.01.04 - Erste Version

"""

import xml.dom

Stel32 = 0


def getDialogValues():

    global Stel32

    
    rad3 = Radio([' 32stel-Noten ', ' 64stel-Noten'], value=0, padding = 8)
    #lab31 = Label(' ', width = 10)
    hbox3= HBox([rad3], padding = 8, text = 'Gracenotes')

    dlg = Dialog('Notation für Dudelsack einrichten: ', hbox3)

    if dlg.run():
        Stel32 = rad3.value()
        return True
    else:
        return False



def handleGraceNotes(score, voice):
    global stemLimit, minStemLen, Stel32

    previousGraceNote = None
    for chord in voice.getElementsByTagName('chord'):
        duration = chord.getElementsByTagName('duration')[0]
        
        if duration.getAttribute('base') ==  '1/32' and Stel32 == 0 or duration.getAttribute('base') ==  '1/64' and Stel32 == 1:

            previousGraceNote = chord

            # Hals nach oben
            stems = chord.getElementsByTagName('stem')
            if stems.length == 0: # zuerst pruefen ob Element stem vorhanden ist
                # wenn nein muss ein element generiert und an den chord angehaengt werden
                stem = score.parentNode.createElement('stem') # ein neues element wird immer am gesamten Dokument generiert
                chord.appendChild(stem) # das neue Element wird an chord angehaengt
            else:
                stem = stems[0]
            stem.setAttribute('dir', str('up'))

            # Note ohne Wert            
            duration.setAttribute('noDuration','true')

            # Note klein notieren
            displays = chord.getElementsByTagName('display')
            if displays.length == 0:  # hier gilt das gleiche wie bei stem
                display = score.parentNode.createElement('display')
                chord.appendChild(display)
            else:
                display = displays[0]
            display.setAttribute('small','true')

        else:
            # Hals nach unten
            stems = chord.getElementsByTagName('stem')
            if stems.length == 0: 
                stem = score.parentNode.createElement('stem') 
                chord.appendChild(stem) 
            else:
                stem = stems[0]
            stem.setAttribute('dir', 'down')

            # bei vorgaengiger GraceNote Balken unterbrechen            
            if previousGraceNote <> None:
                beams = previousGraceNote.getElementsByTagName('beam')
                if beams.length == 0:
                    beam = score.parentNode.createElement('beam')
                    previousGraceNote.appendChild(beam)
                else:
                    beam = beams[0]
                beam.setAttribute('group', 'split')
                previousGraceNote = None
                

def changeDoc(score):
    
    if getDialogValues():
        for voice in score.getElementsByTagName('voice'):
            handleGraceNotes(score, voice)

# Hauptprogramm:

from caplib.capDOM import ScoreChange
import tempfile

class ScoreChange(ScoreChange):
    def changeScore(self, score):
        changeDoc(score)

if activeScore():
    activeScore().registerUndo("Dudelsacknotation")
    tempInput = tempfile.mktemp('.capx')
    tempOutput = tempfile.mktemp('.capx')
    activeScore().write(tempInput)

    ScoreChange(tempInput, tempOutput)

    activeScore().read(tempOutput)
    os.remove(tempInput)
    os.remove(tempOutput)
