# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 09.08.2005 Andreas Herzog
>>> Zeichenpositionierer

    Das Skript positioniert Dymnamik-Zeichen und -Bezeichnungen überhalb oder unterhalb der Notenzeile.|
    |
    
    |
    Version 1.0 |
    
    |
    

        |

<<<


"""

import xml.dom
import string


from xml.dom.minidom import NodeList

Dynamics = ['f','g','h','i','j','p','q','r','s','z','{','|']
DaCapoDalSegno = ['d','e']
Abkuerzungen = ['cresc.','dim.','decresc.','rit.','rall.','ritard.','accel.','cresc','dim','decresc','rit','rall','ritard','accel','acc','acc.','ad lib','ad lib.','cresc','cresc.','D.C. al Fine','D.S. al  Fine','decresc','decresc.','dim','dim.','dimin','dimin.','ms','pizz','pizz.','rall','rall.','ritard','ritard.','rit','rit.','stacc','stacc.','ten','ten.']
Komplett = ['a deux cordes','a due corde','a tempo','accelerando','acciaccatura','ad libitum','allargando','animato','arco','atacca','balzato','calando','calmato','cedez','Coda','coda','codetta','con calore','con legno battuta','con moto','con sordino','senza sordino','corda','corde','crescendo','Da Capo al Fine','Dal Segno al Fine','deciso','decrescendo','diminuendo','encore','espirando','facile','fine','Fine','flautato','loco','lunga','mano sinistra','marcato','meno','meno mosso','mezza voce','molto marcato','molto','ossia','ostinato','basso ostinato','piacere','a piacere','piu mosso','pizzicato','rallentando', 'ritardando','ritenuto','rubato','saltato','saltato','sempre','senza','senza sordino','simile','sopra','staccato','tacet','tenuto','tre corde','tutte le corde','una corda']
Joker = ['piu','con','col','fine','Fine', 'poco','molto', 'senza','volta','corde', 'corda', 'sempre', 'cordes']


# 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 getDialogValues():
	
    global AlleSysteme, DynamikAn, DaCapoSegnoAn, AbkuerzungenAn, CrescendoAn, ItalicAn, KomplettAn, ZusammenAn, ObenUnten, PosY
    
    radObenUnten = Radio(['unter die Notenzeile', 'über die Notenzeile'], text='Ausrichtung:', padding = 8, value=0) 
    PosYEdit = Edit('4', text = '',min = 0, max = 10, width=4)
    PosYLabel= Label('Abstand von der Notenzeile', width = 10)
    radAlles = Radio(['nur Zeile mit Cursor', 'Zeile mit Cursor in allen Systemen', 'alle Zeilen'], text='Bearbeiten:', padding = 8, value=0) 
  
    DynamicCheck = CheckBox('Dynamikzeichen', value=1)    
    DaCapoCheck = CheckBox('Da Capo / Dal Segno', value=1) 
    AbkuerzungenCheck = CheckBox('Abkürzungen (cresc., etc.)', value=1)
    KomplettCheck = CheckBox('Anweisungen (crescendo, etc.)', value=1)
    CrescendoCheck = CheckBox('Crescendo-/Descrendoklammer', value=1)   
    ItalicAnCheck = CheckBox('Alle kursiven Textfelder', value=0)   
    ZusammenAnCheck = CheckBox('Zusammengesetzte Anweisungen (z.B. piu ...)', value=1) 
      
    
      
    lableer = Label('   ', width = 4)    
    vbox0=VBox([DynamicCheck,DaCapoCheck,KomplettCheck,AbkuerzungenCheck,ZusammenAnCheck,CrescendoCheck,ItalicAnCheck],padding = 8)
    hbox0=HBox([vbox0], text = 'Objekte', padding = 8)
    hbox1= HBox([radObenUnten,radAlles], padding = 4)
    hbox2= HBox([PosYLabel,PosYEdit], padding = 4)
    vbox1= VBox([hbox1,hbox2,hbox0,lableer], padding = 8)
    dlg = Dialog('Bitte wählen: ', vbox1)
	
    if dlg.run():
        ObenUnten = radObenUnten.value()
        PosY = string.atof(PosYEdit.value())
        AlleSysteme = radAlles.value()
        DynamikAn = DynamicCheck.value()
        DaCapoSegnoAn = DaCapoCheck.value()
        AbkuerzungenAn = AbkuerzungenCheck.value()
        CrescendoAn = CrescendoCheck.value()
        KomplettAn = KomplettCheck.value()
        ItalicAn = ItalicAnCheck.value()
        ZusammenAn = ZusammenAnCheck.value()
  
       	return True
    else:
        return False

        
def getContent(text):

	for content in text.getElementsByTagName('content'):
		ObjectContent = content.firstChild.nodeValue
	
	return ObjectContent
												
def isItalic(text):
	TextItalic = 'false'
	
	for font in text.getElementsByTagName('font'):
		if font.hasAttribute('italic'):
			TextItalic = font.getAttribute('italic')
	if TextItalic == 'false':
		return False
	if TextItalic == 'true':
		return True

            
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 getSystemBottom(score, layout):
	for staffLayout in score.getElementsByTagName('staffLayout'):
		if staffLayout.getAttribute('description') == layout:
			for distances in staffLayout.getElementsByTagName('distances'):
				bottom = distances.getAttribute('bottom')
	return float(bottom)

def getSystemTop(score, layout):
	for staffLayout in score.getElementsByTagName('staffLayout'):
		if staffLayout.getAttribute('description') == layout:
			for distances in staffLayout.getElementsByTagName('distances'):
				top = distances.getAttribute('top')
	return float(top)	

def isJoker(text):
	for element in Joker:
		if element == getContent(text)[0:len(element)]:
			return True

def changeVoice(voice):
	Signs = []
	if DynamikAn == 1:
		Signs = Signs + Dynamics
	if DaCapoSegnoAn == 1:
		Signs = Signs + DaCapoDalSegno
	if AbkuerzungenAn == 1:
		Signs = Signs + Abkuerzungen
	if KomplettAn == 1:
		Signs = Signs + Komplett
	if ObenUnten == 0:
		Hoehe = PosY
	if ObenUnten == 1:
		Hoehe = PosY * (-1)
	
	for text in voice.getElementsByTagName('text'):
		content = getContent(text)
		if content in Signs or (isItalic(text) and ItalicAn) or isJoker(text): 
			text.setAttribute('y', (str(Hoehe)))
			
	if CrescendoAn == 1:
		for wedge in voice.getElementsByTagName('wedge'):
				wedge.setAttribute('y1', str(Hoehe-0.5625))			
				wedge.setAttribute('y2', str(Hoehe-0.5625))
			

def changeDoc(score):
	global ErrorMessages
	
	
	sel = getCursor()
	if (sel == None):
		return
	else:
	 system = score.getElementsByTagName('system')[sel[0]]
	 staff = system.getElementsByTagName('staff')[sel[1]]
	 staffSelLayout = staff.getAttribute('layout')
	 voice = staff.getElementsByTagName('voice')[sel[2]]
	 if getDialogValues():

		 ErrorMessages = 0
		 if AlleSysteme == 0:
		 	system = score.getElementsByTagName('system')[sel[0]]
		 	changeVoice(voice)
		 if AlleSysteme == 1:
		 	for staff in score.getElementsByTagName('staff'):
		 		if staff.getAttribute('layout') == staffSelLayout:
		 			if len(staff.getElementsByTagName('voice')) > sel[2]:
		 				voice = staff.getElementsByTagName('voice')[sel[2]]
		 				changeVoice(voice)
		 if AlleSysteme == 2:
		 	for voice in score.getElementsByTagName('voice'):
		 		changeVoice(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("Zeichenpositionierer")
	tempInput = tempfile.mktemp('.capx')
	tempOutput = tempfile.mktemp('.capx')
	activeScore().write(tempInput)
	ScoreChange(tempInput, tempOutput)
	activeScore().read(tempOutput)
	os.remove(tempInput)
	os.remove(tempOutput)
