# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 28.05.2007 Hans H. Lampe
>>> Notennamen anzeigen
    (Version 2.2 - 24.09.2010)|||

    Mit diesem Skript werden die Notennamen und wahlweise|deren Oktavkennzeichnungen
    der ausgewählten Notenzeile angezeigt.||

    Bitte den Cursor für die automatische Zeilenwahl in die entsprechende Notenzeile setzen,
    oder die gewünschte Notenzeile im nachfolgenden Dialog wählen.||

    Es werden nur einstimmige Notenzeilen unterstützt.|
    Bei mehrstimmigen Notenzeilen werden die Notennamen der obersten Stimme angezeigt.||

    Bei Akkorden wird der Name der untersten Note angezeigt.|||

    Rückmeldungen bitte an Hans H. Lampe:|HansHermann.Lampe@t-online.de        
<<<

NEU in Version 2.0: Oktav-Kennzeichnungen sind implementiert
                    Einzelne Notenzeilen einer Partitur können selektiert werden
NEU in Version 2.1: Oktavkennzeichnungen wahlweise
                    Hinweis im Dialog auf negative Werte für Positionierung unterhalb der Notenzeile
                    "Zifferngröße" durch "Zeichengröße" ersetzt

                                  
"""
noteNames = {
            0:('ceses','ces','c','cis','cisis'),
            1:('deses','des','d','dis','disis'),
            2:('eses', 'es', 'e','eis','eisis'),
            3:('feses','fes','f','fis','fisis'),
            4:('geses','ges','g','gis','gisis'),
            5:('asas', 'as', 'a','ais','aisis'),
            6:('heses','b',  'h','his','hisis'),
            
            7:('Ceses','Ces','C','Cis','Cisis'),
            8:('Deses','Des','D','Dis','Disis'),
            9:('Eses', 'Es', 'E','Eis','Eisis'),
           10:('Feses','Fes','F','Fis','Fisis'),
           11:('Geses','Ges','G','Gis','Gisis'),
           12:('Asas', 'As', 'A','Ais','Aisis'),
           13:('Heses','B',  'H','His','Hisis'),
            }




# -------- Cursorzeile ermitteln --------- #

staffList = activeScore().voiceList()
staffIndex = 0
sel = curSelection()


if sel <> 0:
    (sy,st,vo,no) = sel[0]
    system = activeScore().system(sy)
    staff = system.staff(st)
      
               
    # ------ Aktuellen Eintrag im Mustersystem bestimmen ------- #

    i = 0
    for descr in staffList:
        if staff.index() == system.staffIndexFromDescr(descr):
            staffIndex = i
        i += 1

# ------------- Dialog ------------- #        

labStaff1 = Label('Notenzeile des Instruments wählen  (durch Cursorpositionierung automatisch vorgewählt)')
selStaff = ComboBox(staffList, value = staffIndex, width=23)
labStaff2 = Label('  "Beschreibung" der Notenzeile im Mustersystem', width=38)
numberSize = Edit(' 8', width=2)
labSize = Label(' Zeichengröße      ')
vertDist = Edit(' 6', width=2)
labDist = Label(' vertikaler Abstand von der Notenzeile nach oben ("negative Werte" nach unten)')
displOct = CheckBox('Sollen Oktavkennzeichnungen angezeigt werden?', value=1)
remark = Label('HINWEIS: Bitte den Text auf dem ersten Bild nach Aufruf des Skripts beachten !')

dlg = Dialog('   Notennamen anzeigen  (Version 2.2)',

             VBox([
                   HBox([labStaff1]),
                   (''),
                   HBox([selStaff, labStaff2]),
                   (''),
                   HBox([numberSize, labSize, vertDist, labDist]),
                   (''),
                   HBox([displOct]),
                   (''),
                   HBox([remark]),
                   ('')
                   ]
                 )
             )

# ---------------------------------- #


from caplib.capDOM import ScoreChange
import tempfile, codecs

def displayNoteNames(score):
    
    parameter = {'x':0,'y':'','font':{'height':''},'type':'text','content':''} 
    font = parameter['font']
    font['weight'] = 0 # nicht fett
    font['height'] = int(numberSize.value())
    parameter['y'] = -int(vertDist.value())
    displOctaves = displOct.value()
   
    for system in activeScore().systems():
        for staff in system.staves():
         
            if staff.index() != selStaff.value(): # suche die gewählte Notenzeile
                continue
            
            voice = staff.voice(0) # nur einstimmige Notenzeilen
                                  
            for noteObj in voice.noteObjs():
                            
                subType = noteObj.subType()
               
                if subType != 1: # 1 = Chord
                   continue
                    
                else: # Chord
                    
                    head = noteObj.head(0)
                    diatonic = head.diatonicPitch()
                    pitch = diatonic[0] # Name des Stammtones
                    
                    if   pitch > 62: pitch = pitch - 63; octave = '5'
                    elif pitch > 55: pitch = pitch - 56; octave = '4'
                    elif pitch > 48: pitch = pitch - 49; octave = "'''"
                    elif pitch > 41: pitch = pitch - 42; octave = '"'
                    elif pitch > 34: pitch = pitch - 35; octave = "'"
                    elif pitch > 27: pitch = pitch - 28; octave = ""
                    elif pitch > 20: pitch = pitch - 14; octave = ""  
                    elif pitch > 13: pitch = pitch -  7; octave = "1"
                    elif pitch >  6: pitch = pitch -  0; octave = "2"
                    
                    noteName = noteNames[pitch] # Table-LookUp
                    alter = diatonic[1] # Alteration
                    
                    if displOctaves:
                        parameter['content'] = noteName[2+alter] + octave # Notenname plus Oktav-Kennzeichnung
                    else:
                        parameter['content'] = noteName[2+alter]

                    noteObj.addDrawObj(parameter)

                    


 
class displNoteNames(ScoreChange):
        def changeScore(self, score):
            global scriptAction, doc
            doc = score.parentNode
            displayNoteNames(score)


# ------ Hauptprogramm ------ #

activeScore().registerUndo("Notennamen anzeigen")

if dlg.run():

    if activeScore():  
        activeScore().registerUndo("Notennamen anzeigen")
        tempInput = tempfile.mktemp('.capx') # für aktuelle aktive Partitur #
        tempOutput = tempfile.mktemp('.capx')
        activeScore().write(tempInput)
       
        displNoteNames(tempInput, tempOutput) # Notennamen anzeigen

        
        os.remove(tempInput)
        os.remove(tempOutput)

