# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 27.07.2004 Andreas Herzog
>>> Let's Sing

    Mit diesem Skript wird aus einer Stimme immer der oberste Ton ausgelesen. So ist es möglich, aus einem Midi-File z.B. die Singstimme zu extrahieren.|
    |
    Statt der Singstimme (oberste Note eines jeweiligen Akkordes) kann auch eine Bassstimme (unterste Note) extrahiert werden.
    |
    Version 1.0    |
    
    |
    

        |

<<<


"""

import xml.dom
import string
from xml.dom.minidom import NodeList

# doc = [] # parentNode von score



def latin1_e(u):
    return u.encode('Latin-1')
def latin1_d(u):
    return u.decode('Latin-1')
    
# neu eingefügt
def addElementNode(el,tagName):
    # add new Node to el if Node "tagName" does not exist
    # otherwise return the existing Node
    global doc
    childs = el.childNodes
    for n in range(childs.length):
        if childs[n].nodeType ==childs[n].ELEMENT_NODE and childs[n].tagName == tagName:
            return childs[n]
    newChild = doc.createElement(tagName)
    el.appendChild(newChild)
    return newChild
    
# neu eingefügt
def addNewElementNode(el,tagName):
    # add new Node with tagName "tagName" to el 
    global doc
    newChild = doc.createElement(tagName)
    el.appendChild(newChild)
    return newChild

    
def getDialogValues():

    global  Auswahl, SingBass


    rad1 = Radio(['nur Notenzeile mit Cursor', 'Notenzeile mit Cursor in allen Systemen   '], text='Zu bearbeiten:', padding = 0, value=1)
    rad2 = Radio(['die Singstimme', 'die Bassstimme'], text='Reduziere auf:', padding = 0, value=0)
    lab1 = Label(' ', width = 1)


    vbox  = VBox([rad1, rad2], text='', padding=4)
    dlg = Dialog('Bitte auswählen: ', vbox)

    if dlg.run():
        Auswahl = rad1.value()
        SingBass = rad2.value()
        return True
    else:
        return False



def handleNotes(score, voice):
    global ClefChoice
	
    for chord in voice.getElementsByTagName('chord'):
		if SingBass == 1:
				headClone = chord.getElementsByTagName('head')[0].cloneNode(True)
		for head in chord.getElementsByTagName('head'):
			if SingBass == 0:
				headClone = head.cloneNode(True)
			
			overHead = head.parentNode
			overHead.removeChild(head)
		overHead.appendChild(headClone)
    		
    
                    
def getCursor():
    sel = curSelection()
    result = None
    if sel == 0:
        messageBox('Fehler', 'keine aktive Partitur')
        return result
    result = sel[0]
    return result
                        

def changeDoc(score):
    
    if getDialogValues():
	    		if Auswahl == 0:												# Nur die Markierte Zeile 
		        	sel = getCursor()
		    		if sel == None:
		        		return
		    		else:
		        		system = score.getElementsByTagName('system')[sel[0]]
		        		staff = system.getElementsByTagName('staff')[sel[1]]
		        		voice = staff.getElementsByTagName('voice')[sel[2]]
		        		handleNotes(score, voice)
		        					
	    		if Auswahl == 1:												# Nur die Markierte Zeile, allerdings über die gesamte Partitur
		        	sel = getCursor()
		    		if sel == None:
		        		return
		    		else:
		        		system = score.getElementsByTagName('system')[sel[0]]
		        		staff = system.getElementsByTagName('staff')[sel[1]]
		        		actLayout = staff.getAttribute('layout')
		        		for staff in score.getElementsByTagName('staff'):
        					if staff.getAttribute('layout') == actLayout:
		        				for voice in staff.getElementsByTagName('voice'):
		        					handleNotes(score, voice)
		        		


# Hauptprogramm:

from caplib.capDOM import ScoreChange
import tempfile

class ScoreChange(ScoreChange):
	def changeScore(self, score):
	   global doc
	   doc = score.parentNode  
	   changeDoc(score)
		
        

if activeScore():
	
	activeScore().registerUndo("Reduktionsfunktion")
	tempInput = tempfile.mktemp('.capx')
	tempOutput = tempfile.mktemp('.capx')
	activeScore().write(tempInput)
	ScoreChange(tempInput, tempOutput)
	activeScore().read(tempOutput)
	os.remove(tempInput)
	os.remove(tempOutput)
