# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 20.01.2005 Andreas Herzog
>>> Textauszug

    Das Skript wandelt Liedtext in Textfelder um.|
    |
    
    |
    Version 1.1b  |
    
    |
    

        |

<<<
# Version 1.0: Originalversion
# Version 1.1b: Fehlerkorrigierte Version: Fehler bei Strophen 7-9 wurden behoben

"""

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')
    
 
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 StrichAutomatik,TextPositionierung, Umbruch, StropheOn1, StropheOn2, StropheOn3, StropheOn4, StropheOn5, StropheOn6, StropheOn7, StropheOn8, StropheOn9
    global Anker, NurLoeschen, StrophenUnterteilung

    radUmbruch = Radio(['kein Textumbruch', 'nach jeder Zeile'], text='Textumbruch', padding = 8, value=0) #,'nach ... Wörter'
    radAnker = Radio(['an der Seite', 'an der ersten Note','an der Note hinter dem Cursor'], text='Verankerung des Textes', padding = 8, value=2) 
    radPositionierung = Radio(['Alle Strophen in einer Textbox','Strophen einzeln horizontal verteilt','Strophen einzeln vertikal verteilt'], text='Strophenverteilung', padding = 8, value = 0)
    StrophenUnterteilungCheck = CheckBox('Strophenunterteilung', value=1) 
    StrichAutomatikCheck = CheckBox('Bindestriche automatisch entfernen', value=1) 
    NurLoeschenCheck = CheckBox('Nur Elemente dieses Skripts löschen!', value=0)
    labNurLoeschen = Label('      (funktioniert nicht bei Verankerung an der Seite)', width = 0)
    
    Strophe1Check = CheckBox('1.Strophe                    ', value=1) 
    Strophe2Check = CheckBox('2.Strophe', value=1) 
    Strophe3Check = CheckBox('3.Strophe', value=1) 
    Strophe4Check = CheckBox('4.Strophe', value=1) 
    Strophe5Check = CheckBox('5.Strophe', value=1) 
    Strophe6Check = CheckBox('6.Strophe', value=1) 
    Strophe7Check = CheckBox('7.Strophe', value=1) 
    Strophe8Check = CheckBox('8.Strophe', value=1) 
    Strophe9Check = CheckBox('9.Strophe', value=1)     
    
    
    
    
    
    vbox2= VBox([Strophe1Check, Strophe2Check, Strophe3Check, Strophe4Check, Strophe5Check, Strophe6Check, Strophe7Check, Strophe8Check, Strophe9Check], padding = 8)
    hbox2= HBox([vbox2],text='Berücksichtigte Strophen', padding = 8)
    hbox3= HBox([radAnker,radUmbruch],padding = 8)
    hbox4= HBox([radPositionierung],padding = 8)
    vbox1= VBox([hbox4,hbox3], padding = 8)
    vbox2= VBox([NurLoeschenCheck, labNurLoeschen], padding = 0)
    vbox3= VBox([vbox1, hbox2, StrichAutomatikCheck, vbox2, StrophenUnterteilungCheck], padding = 8)
    dlg = Dialog('Bitte wählen: ', vbox3)

	
    if dlg.run():
        Umbruch = radUmbruch.value()
        TextPositionierung = radPositionierung.value()
        StrichAutomatik = StrichAutomatikCheck.value()
        StrophenUnterteilung = StrophenUnterteilungCheck.value()
        Anker = radAnker.value()
        NurLoeschen = NurLoeschenCheck.value()
        StropheOn1 = Strophe1Check.value()
        StropheOn2 = Strophe2Check.value()
        StropheOn3 = Strophe3Check.value()
        StropheOn4 = Strophe4Check.value()
        StropheOn5 = Strophe5Check.value()
        StropheOn6 = Strophe6Check.value()
        StropheOn7 = Strophe7Check.value()
        StropheOn8 = Strophe8Check.value()
        StropheOn9 = Strophe9Check.value()       
       	return True
    else:
        return False

def getDialogValues2():
	global StrophenPositionX, StrophenPositionY, StrophenAbstandX, StrophenAbstandY, ZweiterDialogFertig
	
	edit1  = Edit (str(StrophenPositionX), text = 'Horizontale Position der 1.Strophe', width=4)
	edit2  = Edit (str(StrophenPositionY), text = 'Vertikale Position der 1.Strophe', width=4)
	if TextPositionierung == 1:
		StrophenAbstand = StrophenAbstandX
	if TextPositionierung == 2:
		StrophenAbstand = StrophenAbstandY
	edit3  = Edit (str(StrophenAbstand), text = 'Abstand der Strophen', width=4)
    
	lab1 = Label('Horizontale Position der 1.Strophe', width = 4)
	lab2 = Label('Vertikale Position der 1.Strophe', width = 4)
	lab3 = Label('Abstand der Strophen', width = 4) 
       	

	hbox1 = HBox([edit1, lab1], padding = 8)	
	hbox2 = HBox([edit2, lab2], padding = 8)
	hbox3 = HBox([edit3, lab3], padding = 8)
    
	vbox= VBox([hbox1, hbox2,hbox3], padding = 8)
	dlg = Dialog('Bitte wählen: ', vbox)
	
	if dlg.run():
		ZweiterDialogFertig = 2
		StrophenPositionX = string.atof(edit1.value())
		StrophenPositionY = string.atof(edit2.value())
		if TextPositionierung == 1:
			StrophenAbstandX = string.atof(edit3.value())
			StrophenAbstandY = 0
		if TextPositionierung == 2:
			StrophenAbstandX = 0
			StrophenAbstandY = string.atof(edit3.value())	
		return True
	else:
		return False
        
def newText(drawObjects,  width, height, contents):
	global Gruppierung
	
	drawObj = addNewElementNode(drawObjects,'drawObj')
	
	text = addElementNode(drawObj,'text')	
		
	text.setAttribute('x',str(width))
	text.setAttribute('y',str(height))

	content = addNewElementNode(text,'content')
	textNode = doc.createTextNode(latin1_d(contents))
	content.appendChild(textNode)
	text.setAttribute('align','left')
	
	font = addNewElementNode(text,'font')
	font.setAttribute('face','TimesNewRoman')
	font.setAttribute('color','')
	font.setAttribute('height','8')
	font.setAttribute('charSet','1')
	font.setAttribute('pitchAndFamily','2')	 
	
	GraficalTag = '56294-1900'
  	basic = addNewElementNode(drawObj,'basic')							
	basic.setAttribute('tag',GraficalTag) 
	return text

def Test(text):
	messageBox('Test',str(text))

			
def getLyric(chord):
	global LyricContent1, LyricContent2, LyricContent3, LyricContent4, LyricContent5, LyricContent6, LyricContent7, LyricContent8, LyricContent9, VoiceHasText

	
	for lyric in chord.getElementsByTagName('lyric'):
		tag = '0'	
		verseNumber = 0 
		for verse in lyric.getElementsByTagName('verse'):
			verseNumber += 1
			LyricAdd = ''
			if verse.hasChildNodes():
				VoiceHasText = 1			    
				LyricAdd = latin1_e(verse.lastChild.nodeValue)
				if not verse.hasAttribute('hyphen'):
					LyricAdd = LyricAdd + ' '	
				if verse.hasAttribute('hyphen') and StrichAutomatik == 0:
					LyricAdd = LyricAdd + '-'
				if verse.hasAttribute('hyphen') and StrichAutomatik == 1:
					LyricAdd = LyricAdd
				
			if LyricAdd == ' ':
				LyricAdd = ''
																		
			if verseNumber == 1:
				LyricContent1 = LyricContent1 + LyricAdd
			if verseNumber == 2:
				LyricContent2 = LyricContent2 + LyricAdd
			if verseNumber == 3:
				LyricContent3 = LyricContent3 + LyricAdd										
			if verseNumber == 4:
				LyricContent4 = LyricContent4 + LyricAdd
			if verseNumber == 5:
				LyricContent5 = LyricContent5 + LyricAdd
			if verseNumber == 6:
				LyricContent6 = LyricContent6 + LyricAdd															
			if verseNumber == 7:
				LyricContent7 = LyricContent7 + LyricAdd	
			if verseNumber == 8:
				LyricContent8 = LyricContent8 + LyricAdd	
			if verseNumber == 9:
				LyricContent9 = LyricContent9 + LyricAdd													
			

            
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 LyricContent1, LyricContent2, LyricContent3, LyricContent4, LyricContent5, LyricContent6, LyricContent7, LyricContent8, LyricContent9, Umbruch, Anker, StrophenUnterteilung
	global StropheOn1, StropheOn2, StropheOn3, StropheOn4, StropheOn5, StropheOn6, StropheOn7, StropheOn8, StropheOn9
	global TextPositionierung, StrophenPositionX, StrophenPositionY, StrophenAbstandX, StrophenAbstandY, ZweiterDialogFertig
		
	LyricContent1 = ''
	LyricContent2 = ''
	LyricContent3 = ''
	LyricContent4 = ''
	LyricContent5 = ''
	LyricContent6 = ''
	LyricContent7 = ''
	LyricContent8 = ''
	LyricContent9 = ''
		
	sel = getCursor()
	if sel == None:
        #
		return
	else:
	 if not testVoice(score,sel):
	 	messageBox('Fehler','Stimme mit Cursor hat keinen Liedtext!')
	 if testVoice(score,sel):
	   if getDialogValues1():
	    if TextPositionierung == 1 or TextPositionierung == 2:
	   	 	getDialogValues2()	     
	    if TextPositionierung == 0 or ZweiterDialogFertig == 2:
	   	
			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') == '56294-1900':
							
								drawObjects.removeChild(drawObj)
								
								
			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-19':
								drawObjects.removeChild(drawObj)   							
			
			if NurLoeschen == 0: 
				systemCountAll = 0
				for system in score.getElementsByTagName('system'):
					systemCountAll += 1
				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]:
						return
					for obj in objList:
						if obj.tagName == 'chord':
							getLyric(obj)
							
					if Umbruch == 1 and systemCount <> (systemCountAll-1):
						if LyricContent1 <> '': 
							LyricContent1 = LyricContent1 + '\n'
						if LyricContent2 <> '': 
							LyricContent2 = LyricContent2 + '\n'
						if LyricContent3 <> '': 
							LyricContent3 = LyricContent3 + '\n'
						if LyricContent4 <> '': 
							LyricContent4 = LyricContent4 + '\n'
						if LyricContent5 <> '': 															
							LyricContent5 = LyricContent5 + '\n'
						if LyricContent6 <> '': 
							LyricContent6 = LyricContent6 + '\n'
						if LyricContent7 <> '': 
							LyricContent7 = LyricContent7 + '\n'
						if LyricContent8 <> '': 															
							LyricContent8 = LyricContent8 + '\n'
						if LyricContent9 <> '': 
							LyricContent9 = LyricContent9 + '\n'
					systemCount += 1
	
				if score.getElementsByTagName('pageObjects').length == 0:
					pageObjects = doc.createElement('pageObjects')
					for layout in score.getElementsByTagName('layout'):
						next = layout.nextSibling
						score.insertBefore(pageObjects,next)
	        	
				for pageObjects in score.getElementsByTagName('pageObjects'):
					pageObjects = score.getElementsByTagName('pageObjects')[0]	
	
				system = score.getElementsByTagName('system')[sel[0]]
				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]:
					return
	
	        
				obj = objList[sel[3]]
				

				if Anker == 0:
					AnkerObjekt = pageObjects
				if Anker == 1:
					found = 0
					for drawObjects in score.getElementsByTagName('chord')[0].getElementsByTagName('drawObjects'):
						found = 1 
						AnkerObjekt = score.getElementsByTagName('chord')[0].getElementsByTagName('drawObjects')[0]
					if found == 0:
						AnkerObjekt = addNewElementNode(score.getElementsByTagName('chord')[0],'drawObjects')
				if Anker == 2:
					found = 0
					for drawObjects in obj.getElementsByTagName('drawObjects'):
						found = 1 
						AnkerObjekt = obj.getElementsByTagName('drawObjects')[0]
					if found == 0:
						AnkerObjekt = addNewElementNode(obj,'drawObjects')			
	
				
				LyricContent = ''
				StrophenInsert = ''


	
				if LyricContent1 <> '' and StropheOn1 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe1:' + '\n'	
					LyricContent =  StrophenInsert + LyricContent1
				if LyricContent2 <> '' and StropheOn2 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 2:' + '\n'
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent2
				if LyricContent3 <> '' and StropheOn3 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 3:' + '\n'				
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent3
				if LyricContent4 <> '' and StropheOn4 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 4:' + '\n'						
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent4			
				if LyricContent5 <> '' and StropheOn5 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 5:' + '\n'						
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent5
				if LyricContent6 <> '' and StropheOn6 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 6:' + '\n'						
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent6								
				if LyricContent7 <> '' and StropheOn7 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 7:' + '\n'						
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent7
				if LyricContent8 <> '' and StropheOn8 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 8:' + '\n'						
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent8
				if LyricContent9 <> '' and StropheOn9 == 1:
					if StrophenUnterteilung == 1:
						StrophenInsert = 'Strophe 9:' + '\n'				
					LyricContent = LyricContent + '\n\n' + StrophenInsert + LyricContent9											
				
				
	
				
				if TextPositionierung == 0 and VoiceHasText == 1:
					textAll = newText(AnkerObjekt, 0,40, LyricContent)
				if (TextPositionierung == 1 or TextPositionierung == 2) and VoiceHasText == 1:
					ErledigteStrophen = 0
					if LyricContent1 <> '':
						textStrophe1 = newText(AnkerObjekt, (StrophenPositionX),(StrophenPositionY), LyricContent1)
						ErledigteStrophen += 1
					if LyricContent2 <> '':
						textStrophe2 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent2)
						ErledigteStrophen += 1
					if LyricContent3 <> '':
						textStrophe3 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent3)
						ErledigteStrophen += 1        		
					if LyricContent4 <> '':
						textStrophe4 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent4)
						ErledigteStrophen += 1  
					if LyricContent5 <> '':
						textStrophe5 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent5)
						ErledigteStrophen += 1  
					if LyricContent6 <> '':
						textStrophe6 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent6)
						ErledigteStrophen += 1  
						
					if LyricContent7 <> '':
						textStrophe7 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent7)
						ErledigteStrophen += 1  
						
					if LyricContent8 <> '':
						textStrophe8 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent8)
						ErledigteStrophen += 1  
						
					if LyricContent9 <> '':
						textStrophe9 = newText(AnkerObjekt, (StrophenPositionX + (StrophenAbstandX *ErledigteStrophen)),(StrophenPositionY + (StrophenAbstandY *ErledigteStrophen)), LyricContent9)
						ErledigteStrophen += 1  	        			        		
	        		
	        		
# Hauptprogramm:

from caplib.capDOM import ScoreChange
import tempfile

class ScoreChange(ScoreChange):
	
	def changeScore(self, score):
		global StrophenPositionX, StrophenPositionY, StrophenAbstandX, StrophenAbstandY, ZweiterDialogFertig, VoiceHasText
		
		VoiceHasText = 0
		ZweiterDialogFertig = 0
		StrophenPositionX = 00
		StrophenPositionY = 50 
		StrophenAbstandX = 10
		StrophenAbstandY = 10
		global doc
		doc = score.parentNode  
		changeDoc(score)
		
        

if activeScore():
	
	activeScore().registerUndo("Textauszug")
	tempInput = tempfile.mktemp('.capx')
	tempOutput = tempfile.mktemp('.capx')
	activeScore().write(tempInput)
	ScoreChange(tempInput, tempOutput)
	activeScore().read(tempOutput)
	os.remove(tempInput)
	os.remove(tempOutput)

