package mg.dot.feufaro.musicXML

import mg.dot.feufaro.solfa.Transpose

data class SolfaXMLTuo (
    var timeLapse: Int = 0,
    var duration: Int = 0,
    var markers: MutableList<MutableList<String>> = mutableListOf(),
    var oneNote: MutableList<String> = mutableListOf(),
    val lyrics: MutableList<String> = mutableListOf()
) {
    fun resetMarkers() {
        markers = mutableListOf()
    }
    fun addMarker(voiceNumber: Int, marker: String) {
        while (markers.size <= voiceNumber) {
            markers.add(mutableListOf())
        }
        markers[voiceNumber].add(marker)
    }
    fun setTime(newTimeLapse: Int?, newDuration: Int?): SolfaXMLTuo {
        if (newTimeLapse != null) timeLapse = newTimeLapse
        if (newDuration != null) duration = newDuration
        return this
    }
    fun setNote(voiceNumber: Int, note: String)  {
        while (oneNote.size <= voiceNumber) {
            if (oneNote.isEmpty()) {
                oneNote.add("")
            } else {
                oneNote.add(note)
            }
        }
        oneNote[voiceNumber] = note
    }
    fun clone(
        timeLapse: Int = this.timeLapse,
        duration: Int = this.duration,
        markers: MutableList<MutableList<String>> = this.markers.toMutableList(),
        oneNote: MutableList<String> = this.oneNote.toMutableList(),
        newNote: String? = null
    ): SolfaXMLTuo {
        val cloned = SolfaXMLTuo(timeLapse, duration, markers, oneNote)
        if (newNote != null) {
            cloned.oneNote.forEachIndexed { itVoice, itNote ->
                cloned.setNote(itVoice, newNote)
            }
        }
        return cloned
    }
    fun addLyrics(mxLyrics: MXLyric) {
        val number = mxLyrics.number ?: -1
        var text = mxLyrics.text ?: ""
        while(lyrics.size <= number) {
            lyrics.add(lyrics.size, "")
        }
        if (mxLyrics.syllabic in listOf("begin", "middle")) {
            text += "-"
        }
        lyrics[number] = text
    }
    fun toUString(): String {
        return markers.joinToString(separator = "") {
            it.joinToString(separator = "") { it ->
                when (it) {
                    "(", ")" -> ""
                    else -> it
                }
            }
        }
    }
    fun getN(voiceOrder: VoiceOrder): VoiceOrder {
        val newVoiceOrder: VoiceOrder = voiceOrder
        val newVoiceFirst = newVoiceOrder.voiceFirst
        val index0 = voiceOrder.voiceMin + voiceOrder.voiceFirst
        val index1 = voiceOrder.voiceMin + 1 - voiceOrder.voiceFirst
        val note0 = oneNote.getOrElse(index0) { "" }
        val note1 = oneNote.getOrElse(index1) { "" }
        val marker0 = markers.getOrNull(index0)
        val marker1 = markers.getOrNull(index1)
        val markerOne = when {
            marker0 == null -> ""
            marker0.contains("(") -> "("
            marker0.contains(")") -> ")"
            else -> ""
        }
        val markerTwo = when {
            marker1 == null -> ""
            marker1.contains("(") -> "("
            marker1.contains(")") -> ")"
            else -> ""
        }
        if (note0 != note1 && note0 !in listOf("-", "z") && note1 !in listOf("-", "z")) {
            if (Transpose.compareNotes(note0, note1) < 0) {
                return VoiceOrder(voiceOrder.voiceMin, 1 - newVoiceFirst, note1, note0, markerOne, markerTwo )
            }
        }
        return VoiceOrder(voiceOrder.voiceMin, newVoiceFirst, note0, note1, markerOne, markerTwo)
    }
}