let synth = new Tone.Synth().toDestination();
const instruments = {
    "synth": new Tone.Synth().toDestination(),
    "piano": new Tone.Sampler({
	"C3": "https://nbrosowsky.github.io/tonejs-instruments/samples/piano/C3.mp3", 
	"C4": "https://nbrosowsky.github.io/tonejs-instruments/samples/piano/C4.mp3",
	"C5": "https://nbrosowsky.github.io/tonejs-instruments/samples/piano/C5.mp3",
	"C6": "https://nbrosowsky.github.io/tonejs-instruments/samples/piano/C6.mp3",
	"C7": "https://nbrosowsky.github.io/tonejs-instruments/samples/piano/C7.mp3"
    }).toDestination(),
    "violin": new Tone.Sampler({
	"G3": "https://nbrosowsky.github.io/tonejs-instruments/samples/violin/G3.mp3",
	"C4": "https://nbrosowsky.github.io/tonejs-instruments/samples/violin/C4.mp3",
	"C5": "https://nbrosowsky.github.io/tonejs-instruments/samples/violin/C5.mp3",
	"C6": "https://nbrosowsky.github.io/tonejs-instruments/samples/violin/C6.mp3",
	"C7": "https://nbrosowsky.github.io/tonejs-instruments/samples/violin/C7.mp3"
    }).toDestination(),
    "trumpet": new Tone.Sampler({
    	"F3": "https://nbrosowsky.github.io/tonejs-instruments/samples/trumpet/F3.mp3",
    	"C4": "https://nbrosowsky.github.io/tonejs-instruments/samples/trumpet/C4.mp3",
    	"A5": "https://nbrosowsky.github.io/tonejs-instruments/samples/trumpet/A5.mp3",
        "G4": "https://nbrosowsky.github.io/tonejs-instruments/samples/trumpet/G4.mp3",
    	"C6": "https://nbrosowsky.github.io/tonejs-instruments/samples/trumpet/C6.mp3",
    }).toDestination()
};
let recordedNotes = [];
let noteLengths = [];
let pianoRoll = [];
let currentOctave = 4; // 初期オクターブ
     
window.onload = () => {
    drawKeyboard();
};
     
const drawKeyboard = () => {
    const musicalScaleArray = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
    let baseKey;
    for (let i = 0; i < 25; i++) {
        const key = document.createElement("button");
        key.id = `key_${musicalScaleArray[i % musicalScaleArray.length]}${Math.floor(i / 12) + 3}`;
        key.onmousedown = recordNote;
        key.onmouseup = stop;
        key.onmouseleave = stop;
	
        if (musicalScaleArray[i % 12].indexOf("#") > -1) {
            key.classList.add("black");
        } else {
            key.classList.add("white");
            baseKey = document.createElement("div");
        }
        baseKey.appendChild(key);
        document.getElementById("keyboard").appendChild(baseKey);
    }
};

const recordNote = (e) => {
    const scale = e.target.id.split("_")[1];
    const noteLength = document.getElementById("noteLength").value;
    const octaveAdjustedScale = adjustOctave(scale);
    recordedNotes.push(octaveAdjustedScale);
    noteLengths.push(noteLength);
    synth.triggerAttack(octaveAdjustedScale);
    addToPianoRoll(octaveAdjustedScale, noteLength);
    updatePianoRoll();
};

const adjustOctave = (scale) => {
    const note = scale.slice(0, -1);
    const octave = parseInt(scale.slice(-1));
    const newOctave = octave + currentOctave - 4; // 初期オクターブからの差分を計算
    return `${note}${newOctave}`;
};

const addToPianoRoll = (scale, length) => {
    pianoRoll.push({ scale, length });
};

const updatePianoRoll = () => {
    const pianoRollTable = document.getElementById("pianoRoll");
    pianoRollTable.innerHTML = "<tr><th>音高</th><th>長さ</th></tr>";
    pianoRoll.forEach((note, index) => {
        const newRow = document.createElement("tr");
        newRow.innerHTML = `<td>${note.scale}</td><td>${note.length}</td>`;
        pianoRollTable.appendChild(newRow);
    });
};

const play = async () => {
    await Tone.start();
    Tone.Transport.bpm.value = document.getElementById("tempo").value;
    
    let currentTime = Tone.now();
    
    recordedNotes.forEach((scale, index) => {
    	const duration = Tone.Time(noteLengths[index]).toSeconds();
    	const endTime = currentTime + duration;
    	if (scale !== "rest") {
    	    synth.triggerAttackRelease(scale, noteLengths[index], currentTime);
    	}
    	currentTime = endTime;
    });
};

const stop = async () => {
    synth.triggerRelease();
};

const reset = () => {
    recordedNotes = [];
    noteLengths = [];
    pianoRoll = [];
    updatePianoRoll();
};

const toggleKeyboard = () => {
    const keyboard = document.getElementById("keyboard");
    if (keyboard.classList.contains("hidden")) {
        keyboard.classList.remove("hidden");
    } else {
        keyboard.classList.add("hidden");
    }
};

const setInstrument = (instrumentName) => {
    synth = instruments[instrumentName];
};

const increaseOctave = () => {
    if (currentOctave < 7) {
        currentOctave++;
        document.getElementById("currentOctave").textContent = currentOctave;
    }
};

const decreaseOctave = () => {
    if (currentOctave > 1) {
        currentOctave--;
        document.getElementById("currentOctave").textContent = currentOctave;
    }
};
const recordRest = () => {
    const noteLength = document.getElementById("noteLength").value;
    recordedNotes.push("rest");
    noteLengths.push(noteLength);
    addToPianoRoll("休符", noteLength);
    updatePianoRoll();
};
