# -*- coding: ISO-8859-1 -*-
""" capellaScript -- 14.11.2004 Andreas Herzog
>>> SpaceMaker

    Das Skript setzt Zeilenabstände.|
    |
    
    |
    Version 1.0    |
    
    |
    

        |

<<<


"""

import xml.dom
import new, string
from xml.dom.minidom import NodeList, Node, Element

# 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 Test(text):
	messageBox('Test',str(text))
    
def getDialogValues():

	global AbstandOben, AbstandUnten,AbstandSystemOben,AbstandSystemUnten,AbstandSystemGruppe, AbstandErsteZeile, AbstandSysteme, Auswahl

	ZwischenRaeumeLabel = Label(' Zwischenräume', width = 13)
	radAuswahl = Radio(['nur Notenzeile mit Cursor', 'Notenzeile mit Cursor in allen Systemen','gesamte Partitur / Mustersystem nur für Zeile mit Cursor','gesamte Partitur / Mustersystem für alle Zeile'], text='Zu bearbeiten:', padding = 0, value=1)
	
	AbstandObenEdit = Edit(str(AbstandOben), min= 0, max = 199,width = 6)
	AbstandObenLabel = Label('Abstand nach oben:', width = 13)
	
 	AbstandUntenEdit = Edit(str(AbstandUnten),min= 0, max = 199, width = 6)
	AbstandUntenLabel = Label('Abstand nach unten:', width = 13)   

	AbstandObenSysEdit = Edit(str(AbstandSystemOben), min= 0, max = 199,width = 6)
	AbstandObenSysLabel = Label('Abstand nach oben:', width = 13)
	
 	AbstandUntenSysEdit = Edit(str(AbstandSystemUnten),min= 0, max = 199, width = 6)
	AbstandUntenSysLabel = Label('Abstand nach unten:', width = 13)  
	
	AbstandGruppeSysEdit = Edit(str(AbstandSystemGruppe),min= 0, max = 199, width = 6)
	AbstandGruppeSysLabel = Label('Gruppenabstand:', width = 13)  

 	AbstandErsteZeileEdit = Edit(str(AbstandErsteZeile),min= 0, max = 199, width = 6)
	AbstandErsteZeileLabel = Label('über erstem System:', width = 13)  
	
	AbstandSystemeEdit = Edit(str(AbstandSysteme),min= 0, max = 199, width = 6)
	AbstandSystemeLabel = Label('zwischen Systemen:', width = 13) 

	lab1 = Label(' ', width = 1)
	lab2 = Label('Zeile(n):', width = 1)
	lab3 = Label('Systemabstände:', width = 1)

	hbox1 = HBox([AbstandObenLabel,AbstandObenEdit,ZwischenRaeumeLabel], padding = 4)
	hbox2 = HBox([AbstandUntenLabel,AbstandUntenEdit,ZwischenRaeumeLabel], padding = 4)
	hbox3 = HBox([AbstandObenSysLabel,AbstandObenSysEdit,ZwischenRaeumeLabel], padding = 4)
	hbox4 = HBox([AbstandUntenSysLabel,AbstandUntenSysEdit,ZwischenRaeumeLabel], padding = 4)
	hbox5 = HBox([AbstandGruppeSysLabel,AbstandGruppeSysEdit,ZwischenRaeumeLabel], padding = 4)
	hbox6 = HBox([AbstandErsteZeileLabel,AbstandErsteZeileEdit,ZwischenRaeumeLabel], padding = 4)
	hbox7 = HBox([AbstandSystemeLabel,AbstandSystemeEdit,ZwischenRaeumeLabel], padding = 4)
	
	vbox10 = VBox([hbox1,hbox2], padding = 4)
	vbox20 = VBox([lab2,hbox3,hbox4, hbox5, lab3, hbox6, hbox7], padding = 4)
	
	hbox10 = HBox([vbox10], text='Abstände Zeile(n):',padding = 4)
	hbox20 = HBox([vbox20], text='Abstände im Mustersystem:',padding = 4)
	vbox  = VBox([hbox10, hbox20,radAuswahl], text='', padding=4)
	dlg = Dialog('Zeilenabstand formatieren', vbox)

	if dlg.run():
		Auswahl = radAuswahl.value()
		AbstandOben = AbstandObenEdit.value()
		AbstandUnten= AbstandUntenEdit.value()
		AbstandSystemOben = AbstandObenSysEdit.value()
		AbstandSystemUnten= AbstandUntenSysEdit.value()
		AbstandSystemGruppe=AbstandGruppeSysEdit.value()
		AbstandSysteme = AbstandSystemeEdit.value()
		AbstandErsteZeile = AbstandErsteZeileEdit.value()
		return True
	else:
		return False

def gotoChild(self, name, new=False, first=False):
    newEl = None
    if new:
        pass
    else:
        for child in self.childNodes:
            if child.nodeType == child.ELEMENT_NODE and child.tagName == name:
                newEl = child
                break
    if newEl == None:
        newEl = doc.createElement(name)
        if first and self.firstChild:
            self.insertBefore(newEl, self.firstChild )            
        else:
            self.appendChild(newEl)
    return newEl
Node.gotoChild = new.instancemethod(gotoChild,None,Node)


def handleStaff(staff):
	

	extraDistance = staff.gotoChild('extraDistance', first=True)
	extraDistance.setAttribute('top',str(AbstandOben))
	extraDistance.setAttribute('bottom',str(AbstandUnten))


def handleStaffLayout(score, staffLayout):
	
	distances = staffLayout.gotoChild('distances', first=True)
	distances.setAttribute('top',str(AbstandSystemOben))
	distances.setAttribute('bottom',str(AbstandSystemUnten))

def getCursor():
    sel = curSelection()
    result = None
    if sel == 0:
        messageBox('Fehler', 'keine aktive Partitur')
        return result
    result = sel[0]
    return result
                        

def changeDoc(score):
	global AbstandOben, AbstandUnten,AbstandSystemOben,AbstandSystemUnten,AbstandSystemGruppe, AbstandErsteZeile, AbstandSysteme
	
	AbstandOben = 0
	AbstandUnten = 0
	AbstandSystemOben = 0
	AbstandSystemUnten = 0
	AbstandSystemGruppe = 0
	AbstandErsteZeile = 0
	AbstandSysteme = 0 
	
	sel = getCursor()
	if sel == None:
		return
	else:
		system = score.getElementsByTagName('system')[sel[0]]
		staff = system.getElementsByTagName('staff')[sel[1]]
		actLayout = staff.getAttribute('layout')
		for extraDistance in staff.getElementsByTagName('extraDistance'):
			AbstandOben= str(extraDistance.getAttribute('top'))
			AbstandUnten=str(extraDistance.getAttribute('bottom'))
			if AbstandOben == '':
				AbstandOben = 0
			if AbstandUnten == '':
				AbstandUnten = 0
			
		for staffLayout in score.getElementsByTagName('staffLayout'):
			if staffLayout.getAttribute('description') == actLayout:
				
				staffLayoutSel = staffLayout
				for distances in staffLayoutSel.getElementsByTagName('distances'):
					
					AbstandSystemOben = distances.getAttribute('top')
					AbstandSystemUnten = distances.getAttribute('bottom')
					if distances.hasAttribute('group'):
						AbstandSystemGruppe = distances.getAttribute('group')
		for layout in score.getElementsByTagName('layout'):
			for systems in layout.getElementsByTagName('systems'):
				AbstandErsteZeile = systems.getAttribute('top')
				AbstandSysteme = systems.getAttribute('between')
				
					
	if getDialogValues():
		for layout in score.getElementsByTagName('layout'):
			for systems in layout.getElementsByTagName('systems'):
				systems.setAttribute('top',AbstandErsteZeile)
				systems.setAttribute('between',AbstandSysteme)
		
		if Auswahl == 0:												# Nur die Markierte Zeile 
			handleStaff(staff)
			handleStaffLayout(score, staffLayoutSel)
		if Auswahl >= 1:
			
			
			for staff in score.getElementsByTagName('staff'):		# Nur die Markierte Zeile, allerdings über die gesamte Partitur
				if (staff.getAttribute('layout') == actLayout) or (Auswahl > 1):
					handleStaff(staff)

				if (staff.getAttribute('layout') == actLayout):	
					handleStaffLayout(score, staffLayoutSel)
				if Auswahl == 3:
					for staffLayout in score.getElementsByTagName('staffLayout'):
						distances = staffLayout.gotoChild('distances', first=True)
						distances.setAttribute('top',str(AbstandSystemOben))
						distances.setAttribute('bottom',str(AbstandSystemUnten))


# 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("Zeilenabstand formatieren")
	tempInput = tempfile.mktemp('.capx')
	tempOutput = tempfile.mktemp('.capx')
	activeScore().write(tempInput)
	ScoreChange(tempInput, tempOutput)
	activeScore().read(tempOutput)
	os.remove(tempInput)
	os.remove(tempOutput)
