# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 29.05.2005 Andreas Herzog
>>> Take Your Breath

    Das Skript kann Atemzeichen formatieren, die in Capella mit der Shift + '1' eingefügt wurden. ||Achtung:|
    Das Skript selber fügt keine Atemzeichen ein!|
    ||
    Mit der Funktion vertikale Korrektur kann man die Unterschiede zwischen " ' " und "," aus- gleichen.
    |
    |
    Version 1.0c  |
    
    |
    

        |

<<<

# Version 1.0b: Ursprungsversion
# Version 1.0c: Fehlerkorrektur bei der Formatierung der Schriftart der Atemzeichen
"""

import xml.dom
import string


from xml.dom.minidom import NodeList

MoeglicheZeichen = ['\'',',']

# doc = [] # parentNode von score

def latin1_e(u):
    return u.encode('Latin-1')
def latin1_d(u):
    return u.decode('Latin-1')
    
 
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
    

def addNewElementNode(el,tagName):
    # add new Node with tagName "tagName" to el 
    global doc
    newChild = doc.createElement(tagName)
    el.appendChild(newChild)
    return newChild



    
def getDialogValues1():
	

    
    global AlleZeichen, Schriftart, NurLoeschen, Schriftgrad, Schriftzeichen, Schrifthoehe, Schriftweite, AllePositionen, VertikaleKorrektur

    NurLoeschenCheck = CheckBox('Nur Elemente dieses Skripts löschen!', value=0)
   
    AlleZeichenCheck = CheckBox('Alle Zeichen gleich formatieren', value=0) 
    
    AllePositionenCheck = CheckBox('Die Position aller Zeichen verändern', value=0) 
    
    labLeer = Label(' ', width = 5)
    labelHinweis1 = Label('Bitte beachten:', width = 6)
    labelHinweis2 = Label('--------------', width = 6)
    labelHinweis3= Label('Das Skript setzt KEINE Atemzeichen, sondern formatiert diese nur.', width = 6)
    labelHinweis4= Label('Die Atemzeichen können in capella mit Shift + 1 gesetzt werden.', width = 6)
    
    editSchriftart = Edit(str(Schriftart), width = 20)
    labelSchriftart = Label('Schriftart:   ', width = 4)
  
    editSchriftgrad = Edit(str(Schriftgrad), width = 20)
    labelSchriftgrad = Label('Schriftgrad:', width = 4)

    editVertikaleKorrektur = Edit(str(VertikaleKorrektur), width = 5, min = -2.0, max=2.0)
    labelVertikaleKorrektur = Label('Vertikale Korrektur:', width = 4)

    labelSchriftzeichen = Label('Schriftzeichen:', width = 4)
        
    comboZeichen= ComboBox(MoeglicheZeichen, value = Schriftzeichen)

    editSchriftweite = Edit(str(Schriftweite), width = 5)
    labelSchriftweite = Label('Horizontale Position:', width = 4)
        
    editSchrifthoehe = Edit(str(Schrifthoehe), width = 5)
    labelSchrifthoehe = Label('Vertikale Position:    ', width = 4)
    
    
    vbox8= VBox([NurLoeschenCheck], padding = 8)
    hbox1= HBox([labelSchriftart,editSchriftart],padding = 8)
    hbox2= HBox([labelSchriftgrad,editSchriftgrad],padding = 8)
    hbox3= HBox([labelSchriftzeichen,comboZeichen],padding = 8)
    hbox4= HBox([labelSchriftweite,editSchriftweite],padding = 8)
    hbox5= HBox([labelSchrifthoehe,editSchrifthoehe],padding = 8)
    hbox6= HBox([labelVertikaleKorrektur,editVertikaleKorrektur],padding = 8)
    vbox1= VBox([hbox1, hbox2, hbox3, AlleZeichenCheck], padding = 8)
    vbox2= VBox([hbox4, hbox5, AllePositionenCheck], padding = 8)
    vbox9= VBox([hbox6], padding = 8)
    
    vbox10= VBox([labLeer, labelHinweis1, labelHinweis2,labelHinweis3, labelHinweis4, labLeer], padding = 2)
    
    
    hbox8= HBox([vbox1],text='Schrift', padding = 8)
    hbox9= HBox([vbox2],text='Position', padding = 8)
    
    hbox10= HBox([vbox9],text='Vertikale Korrektur', padding = 8)
    
    vbox3= VBox([hbox8,hbox9, hbox10, vbox8,vbox10 ], padding = 4)
    dlg = Dialog('Bitte wählen: ', vbox3)

	
    if dlg.run():

        NurLoeschen = NurLoeschenCheck.value()
        AlleZeichen = AlleZeichenCheck.value()
        AllePositionen = AllePositionenCheck.value()
        Schriftart = str(editSchriftart.value())
        Schriftgrad = str(editSchriftgrad.value())
        Schriftweite = str(editSchriftweite.value())
        Schrifthoehe = str(editSchrifthoehe.value())
        VertikaleKorrektur = str(editVertikaleKorrektur.value())
        Schriftzeichen = comboZeichen.value()
        
   	
       	return True
    else:
        return False


        
def setText(drawObject, Durchlauf):
	global Schriftart, Schriftgrad, Schriftzeichen, Schrifthoehe, Schriftweite, AllePositionen, VertikaleKorrektur
	
	GraficalTag = '56294-2000'

  	basic = addNewElementNode(drawObject,'basic')							
	basic.setAttribute('tag',GraficalTag) 
	for text in drawObject.getElementsByTagName('text'):
		

		if AllePositionen == 1 or Durchlauf == 0:
			text.setAttribute('x',Schriftweite)
			text.setAttribute('y',Schrifthoehe)
		if AlleZeichen == 1 or Durchlauf == 0:
			for font in text.getElementsByTagName('font'):
				font.setAttribute('face',Schriftart)
				font.setAttribute('height',Schriftgrad)
				font.setAttribute('weight', Weight)
				font.setAttribute('pitchAndFamily',PitchAndFamily)
				
			for content in text.getElementsByTagName('content'):
				 killContent = content.lastChild
				 content.removeChild(killContent)
				 textNode = doc.createTextNode(MoeglicheZeichen[Schriftzeichen])
				 content.appendChild(textNode)

def setHeightCorrected(drawObject):
	for text in drawObject.getElementsByTagName('text'):
		Schrifthoehe = text.getAttribute('y')
		Schrifthoehe = str(string.atof(VertikaleKorrektur) + string.atof(Schrifthoehe))
		text.setAttribute('y',Schrifthoehe)
			 

			
def getText(drawObject):

	TextContent = ''
	for text in drawObject.getElementsByTagName('text'):
				
		for content in drawObject.getElementsByTagName('content'):
			if content.hasChildNodes():
				TextContent = latin1_e(content.lastChild.nodeValue)			
				
	return TextContent

def getFont(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		for font in drawObject.getElementsByTagName('font'):
			Font = font.getAttribute('face')
				
	return Font

def getHeight(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		for font in drawObject.getElementsByTagName('font'):
			Height = font.getAttribute('height')
	return Height	

def getWeight(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		for font in drawObject.getElementsByTagName('font'):
			Weight = font.getAttribute('weight')
	return Weight

def getPitchAndFamily(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		for font in drawObject.getElementsByTagName('font'):
			PitchAndFamily = font.getAttribute('pitchAndFamily')
	return PitchAndFamily

def getPosY(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		PosY = text.getAttribute('y')
	return PosY

def getPosX(drawObject):

	for text in drawObject.getElementsByTagName('text'):
		PosX = text.getAttribute('x')
	return PosX
			    
def getCursor():
    sel = curSelection()
    result = None
    if sel == 0:
        messageBox('Fehler', 'keine aktive Partitur')
        return result
    #if sel[0] != sel[1]:
    #    messageBox('Fehler', 'Markierung ist nicht leer')
    #    return result
    result = sel[0]
    return result

def getElementObjects(objList):  # returns a List
    newList = NodeList()
    for n in range(objList.length):
        if objList[n].nodeType == objList[n].ELEMENT_NODE:
            newList.append(objList[n])
    return newList

def testVoice(score,sel):
	hasLyric = False
	for system in score.getElementsByTagName('system'):
		staff = system.getElementsByTagName('staff')[sel[1]]
		voice = staff.getElementsByTagName('voice')[sel[2]]
		noteObjects = voice.getElementsByTagName('noteObjects')[0]
		for lyric in noteObjects.getElementsByTagName('lyric'):		
			for verse in lyric.getElementsByTagName('verse'):
				if verse.hasChildNodes():
					hasLyric = True
	return hasLyric
				    
def changeDoc(score):
	global Schriftart, Schriftgrad, Schriftzeichen, Schrifthoehe, Schriftweite, PitchAndFamily, Weight
		
	PitchAndFamily=''
	Weight = ''
	
	sel = getCursor()
	if sel == None:
        #
		return
	else:
	   
	   for system in score.getElementsByTagName('system'):
			
			staff = system.getElementsByTagName('staff')[sel[1]]
			voice = staff.getElementsByTagName('voice')[sel[2]]
			noteObject = voice.getElementsByTagName('noteObjects')[0]
			objList = getElementObjects(noteObject.childNodes)
			if objList.length > sel[3]:

				obj = objList[sel[3]]
				
				if obj.tagName == 'chord' or 'rest':
						for drawObject in obj.getElementsByTagName('drawObj'):
							
							TextContent = getText(drawObject)
							
							if TextContent in MoeglicheZeichen:
		
								Schriftart = getFont(drawObject)
								Schriftgrad = getHeight(drawObject)
								Schriftzeichen = MoeglicheZeichen.index(TextContent)
								Schrifthoehe = getPosY(drawObject)
								Schriftweite = getPosX(drawObject)
								PitchAndFamily = getPitchAndFamily(drawObject)
								Weight = getWeight(drawObject)
							

	   if getDialogValues1():
					
			if NurLoeschen == 1: 
				for drawObjects in score.getElementsByTagName('drawObjects'):	# Alle drawObj mit tag == GraficalTag löschen
					for drawObj in drawObjects.childNodes:
						if drawObj.nodeType == drawObj.ELEMENT_NODE and drawObj.tagName == 'drawObj':
							for basic in drawObj.getElementsByTagName('basic'):
								if basic.hasAttribute('tag') and basic.getAttribute('tag')[0:8] == '56294-20':
									drawObjects.removeChild(drawObj)   							
			
			if NurLoeschen == 0: 
				systemCount = 0
				for system in score.getElementsByTagName('system'):
					
					staff = system.getElementsByTagName('staff')[sel[1]]
					voice = staff.getElementsByTagName('voice')[sel[2]]
					noteObject = voice.getElementsByTagName('noteObjects')[0]
					objList = getElementObjects(noteObject.childNodes)
					if objList.length > sel[3]:

						obj = objList[sel[3]]
						
						if obj.tagName == 'chord' or 'rest':
								for drawObject in obj.getElementsByTagName('drawObj'):
									TextContent = ''
									TextContent = getText(drawObject)
									
									if (TextContent == ',') or (TextContent == '\''):
										setText(drawObject,0)
										#messageBox('Gefunden','OK')
							

				if AlleZeichen == 0: 
					setHeightCorrected(drawObject)
				if AlleZeichen == 1 or AllePositionen == 1: 
					for drawObject in score.getElementsByTagName('drawObj'):
								
						TextContent = ''
						TextContent = getText(drawObject)
						

						if (TextContent == ',') or (TextContent == '\''):
							setText(drawObject,1)
							#messageBox('Gefunden','OK')					
       				      		
	        		for drawObject in score.getElementsByTagName('drawObj'):
	        			setHeightCorrected(drawObject)
	        		
# Hauptprogramm:

from caplib.capDOM import ScoreChange
import tempfile

class ScoreChange(ScoreChange):
	
	def changeScore(self, score):
		
	
		global doc, Schriftart, Schriftgrad, Schriftzeichen, Schrifthoehe, Schriftweite, VertikaleKorrektur
		
		Schriftgrad = '12'
		Schriftart = 'Arial'
		Schriftzeichen = 1
		Schrifthoehe = '-2.5'
		Schriftweite = '2.0'
		VertikaleKorrektur = '0.0'
		doc = score.parentNode  
		changeDoc(score)
		
        

if activeScore():
	
	activeScore().registerUndo("Atemzeichen formatieren")
	tempInput = tempfile.mktemp('.capx')
	tempOutput = tempfile.mktemp('.capx')
	activeScore().write(tempInput)
	ScoreChange(tempInput, tempOutput)
	activeScore().read(tempOutput)
	os.remove(tempInput)
	os.remove(tempOutput)

