# -*- coding: ISO-8859-1 -*-
""" capellaScript   (c) Paul Villiger
>>> Doppelpunkt entfernen

    Diese Skript entfernt bei mehrstimmigen Notenzeilen in der unteren Stimme die Punktierung,
    sofern beide Noten gleich sind.
    
<<<

History:  24.04.04 - Erste Ausgabe
          15.03.2008 Berücksichtigung von 3-fach Punktierung
          12.04.2008 dur2getAttribute korrigiert

"""


from xml.dom.minidom import NodeList

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 getNoteObjects(voice):  # returns a List
    noteObject = voice.getElementsByTagName('noteObjects')[0]
    objList = noteObject.childNodes
    newList = NodeList()
    for n in range(objList.length):
        if objList[n].nodeType == objList[n].ELEMENT_NODE:
            newList.append(objList[n])
    return newList

def checkDots(vo1,vo2):
    nos1 = getNoteObjects(vo1)
    nos2 = getNoteObjects(vo2)
    time1 = time2 = Rational(0)
    pt2 = 0
    for no1 in nos1:
        if no1.tagName in ['chord','rest']:
            dur1 = no1.getElementsByTagName('duration')[0]
            rat1 = Rational(str(dur1.getAttribute('base')))
            hasDots = False
            if dur1.hasAttribute('dots'):
                hasDots = True
                d = dur1.getAttribute('dots')
                if d == '1':
                    rat1 = rat1 * 1.5
                elif d == '2':
                    rat1 = rat1 * 1.75
                elif d == '3':
                    rat1 = rat1 * 1.875
            time1 = time1 + rat1

            while time1 > time2 and pt2 < nos2.length:
                no2 = nos2[pt2]
                if no2.tagName in ['chord','rest']:
                    dur2 = no2.getElementsByTagName('duration')[0]
                    rat2 = Rational(str(dur2.getAttribute('base')))
                    if dur2.hasAttribute('dots'):
                        d = dur2.getAttribute('dots')
                        if d == '1':
                            rat2= rat2 * 1.5
                        elif d == '2':
                            rat2= rat2 * 1.75
                        elif d == '3':
                            rat2= rat2 * 1.875
                    time2 = time2 + rat2
                pt2 +=1

            if hasDots and time1 == time2 and rat1 == rat2 and no1.tagName == 'chord' and no2.tagName == 'chord':
                if no1.getElementsByTagName('head')[0].getAttribute('pitch') == no2.getElementsByTagName('head')[0].getAttribute('pitch'):
                    display = addElementNode(no2,'display')
                    display.setAttribute('dotsInvisible','true')
                    
def changeDoc(score):
    for staff in score.getElementsByTagName('staff'):
        for voice1 in staff.getElementsByTagName('voice'):
            if voice1.hasAttribute('stemDir') and voice1.getAttribute('stemDir') == 'up':
                for voice2 in staff.getElementsByTagName('voice'):
                    if voice2.hasAttribute('stemDir') and voice2.getAttribute('stemDir') == 'down':
                        checkDots(voice1,voice2)


# 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("Pausen immer in der Mitte")
    tempInput = tempfile.mktemp('.capx')
    tempOutput = tempfile.mktemp('.capx')
    activeScore().write(tempInput)
    
    ScoreChange(tempInput, tempOutput)

    activeScore().read(tempOutput)
    os.remove(tempInput)
    os.remove(tempOutput)                

