package mg.dot.feufaro.midi

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import mg.dot.feufaro.FileRepository

actual class MidiWriterKotlin actual constructor(private val fileRepository: FileRepository) {
    private val sequence = MidiSequence(60)
    private val track    = sequence.createTrack()
    private var tick: Long = 0
    private var nextTick: MutableList<MidiPitch> = mutableListOf()
    private val lastPitch : MutableList<Int> = mutableListOf()
    private val useChord : Boolean = true
    actual fun addNote( voiceNumber: Int, note: Int, velocity: Int, tick: Long) {
        val channel = (voiceNumber -1).coerceIn(0, 3)
        var finalNote = note

        if (voiceNumber == 3 || voiceNumber == 4) {
            finalNote -= 12
        }
        if (lastPitch.size > voiceNumber && lastPitch[voiceNumber] > 0) {
            sequence.addSequence(channel, lastPitch[voiceNumber], tick)
        }
        var finalVelocity = velocity
        var midiNote = finalNote
        if (finalNote <= 0) {
            midiNote = 40
            finalVelocity = 0
        }
        sequence.addSequence(channel, midiNote, tick, 90, finalVelocity)

        while(lastPitch.size <= voiceNumber) {
            lastPitch.add(0)
        }
        lastPitch[voiceNumber] = midiNote
    }
    actual fun save(filePath: String) {
        val parseScope = CoroutineScope(Dispatchers.Default)
        parseScope.launch {
            sequence.write()
            fileRepository.saveFile(filePath, sequence.out.toByteArray())
            //val fout = fileRepository.getOutputStream(filePath)
        }
    }
    actual fun addMetaMessage(type: Int, tick: Int, nbData: Int, metaByteString: String) {
        sequence.addMeta( type, tick, nbData, metaByteString)
    }
    actual fun process(pitches: List<MidiPitch>) {
        val lastTick = 0
        nextTick.clear()
        // addMetaMessage(0x59, 4, 2, 2,0)
        tick = 0
        pitches.forEach {
            if (it.metaType > 0) {
                addMetaMessage(it.metaType, it.tick, it.metaByteSize, it.metaBytes)
            } else if (it.pitch != "") {
                addNote(it.voiceNumber, it.pitch.toInt(), 100, it.tick.toLong())
            }
        }
    }
}