let synth1 = new Tone.Synth().toDestination();
let synth2 = new Tone.Synth().toDestination();
let instrument1 = synth1;
let instrument2 = synth2;
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 recordedNotes1 = [];
let recordedNotes2 = [];
let noteLengths1 = [];
let noteLengths2 = [];
let pianoRoll1 = [];
let pianoRoll2 = [];

let selectedRow = null;

let currentOctave = 4; // 初期オクターブ

window.onload = () => {
    drawKeyboard();
    
};

const selectRow = (index) => {
    selectedRow = index;
    // 選択された行の内容をテキストボックスに反映する
    const selectedNote = pianoRoll1[index];
    const pianoRollTextBox = document.getElementById("pianoRoll");
    pianoRollTextBox.value = `${selectedNote.scale} (${selectedNote.length})`;
};

const updatePianoRollTextBox = () => {
    const track = document.getElementById("trackSelect").value;
    let pianoRoll;

    if (track === "track1") {
        pianoRoll = pianoRoll1;
    } else if (track === "track2") {
        pianoRoll = pianoRoll2;
    } else {
        return;
    }

    const pianoRollTextBox = document.getElementById("pianoRoll");
    pianoRollTextBox.value = ""; // Clear the text box

    pianoRoll.forEach((note, index) => {
        pianoRollTextBox.value += `${note.scale} (${note.length})\n`;
    });
};


const editNote = () => {
    const editedText = document.getElementById("pianoRoll").value.trim();
    if (editedText === "") {
        return;
    }

    const parts = editedText.split(" ");
    if (parts.length === 2) {
        const newScale = parts[0];
        const newLength = parts[1];

        const track = document.getElementById("trackSelect").value;
        let pianoRoll;

        if (track === "track1") {
            pianoRoll = pianoRoll1;
        } else if (track === "track2") {
            pianoRoll = pianoRoll2;
        } else {
            return;
        }

        // 選択された行の内容を更新する
        pianoRoll[selectedRowIndex].scale = newScale;
        pianoRoll[selectedRowIndex].length = newLength;

        // ピアノロールとテキストボックスを更新する
        updatePianoRoll();
        updatePianoRollTextBox();
    }
};

const editSelected = () => {
    if (selectedRow !== null) {
        // 選択された行の内容をテキストボックスから取得する
        const editedText = document.getElementById("pianoRoll").value;
        // 音階と長さを更新する
        const parts = editedText.split(" ");
        if (parts.length === 2) {
            pianoRoll1[selectedRow].scale = parts[0];
            pianoRoll1[selectedRow].length = parts[1];
        }
        // ピアノロールを更新する
        updatePianoRoll();
        // 選択解除する
        selectedRow = null;
    }
};

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);
    const track = document.getElementById("trackSelect").value;

    if (track === "track1") {
	recordedNotes1.push(octaveAdjustedScale);
	noteLengths1.push(noteLength);
	pianoRoll1.push({ scale: octaveAdjustedScale, length: noteLength });
	instrument1.triggerAttack(octaveAdjustedScale);
    } else if (track === "track2") {
	recordedNotes2.push(octaveAdjustedScale);
	noteLengths2.push(noteLength);
	pianoRoll2.push({ scale: octaveAdjustedScale, length: noteLength });
	instrument2.triggerAttack(octaveAdjustedScale);
    } else {
	return;
    }
    updatePianoRoll();
};

const recordRest = () => {
    const noteLength = document.getElementById("noteLength").value;
    const track = document.getElementById("trackSelect").value;
    if (track === "track1") {
	recordedNotes1.push("rest");
	noteLengths1.push(noteLength);
	addToPianoRoll("休符", noteLength);
    }
    else if (track === "track2") {
	recordedNotes2.push("rest");
	noteLengths2.push(noteLength);
	addToPianoRoll("休符", noteLength);
    }
    else {
	return;
    }
    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) => {
    const track = document.getElementById("trackSelect").value;
    if (track === "track1") {
        pianoRoll1.push({ scale, length });
    } else if (track === "track2") {
        pianoRoll2.push({ scale, length });
    } else {
	return;
    }
};

const updatePianoRoll = () => {
    const track = document.getElementById("trackSelect").value;
    let pianoRoll;

    if (track === "track1") {
        pianoRoll = pianoRoll1;
    } else if (track === "track2") {
        pianoRoll = pianoRoll2;
    } else {
        return;
    }

    const pianoRollTable = document.getElementById("pianoRoll");
    const pianoRollTextBox = document.getElementById("pianoRoll");
    
    pianoRollTable.innerHTML = "<tr><th>音高</th><th>長さ</th></tr>";
    pianoRollTextBox.value = ""; // Clear the text box

    pianoRoll.forEach((note, index) => {
        const newRow = document.createElement("tr");
        newRow.innerHTML = `<td>${note.scale}</td><td>${note.length}</td>`;
        pianoRollTable.appendChild(newRow);
        pianoRollTextBox.value += `${note.scale} (${note.length})\n`; // Add to the text box
    });
};


const play1 = async () => {
    await Tone.start();
    Tone.Transport.bpm.value = document.getElementById("tempo").value;
    
    let currentTime1 = Tone.now();
    
    recordedNotes1.forEach((scale, index) => {
    	const duration1 = Tone.Time(noteLengths1[index]).toSeconds();
    	const endTime1 = currentTime1 + duration1;
    	if (scale !== "rest") {
    	    instrument1.triggerAttackRelease(scale, noteLengths1[index], currentTime1);
    	}
    	currentTime1 = endTime1;
    });
};

const play2 = async () => {
    await Tone.start();
    Tone.Transport.bpm.value = document.getElementById("tempo").value;
    
    let currentTime2 = Tone.now();
    
    recordedNotes2.forEach((scale, index) => {
    	const duration2 = Tone.Time(noteLengths2[index]).toSeconds();
    	const endTime2 = currentTime2 + duration2;
    	if (scale !== "rest") {
    	    instrument2.triggerAttackRelease(scale, noteLengths2[index], currentTime2);
    	}
    	currentTime2 = endTime2;
    });
};

const play = async () => {
    await Tone.start();
    Tone.Transport.bpm.value = document.getElementById("tempo").value;

    let currentTime1 = Tone.now();
    let currentTime2 = Tone.now();

    recordedNotes1.forEach((scale, index) => {
    	const duration1 = Tone.Time(noteLengths1[index]).toSeconds();
    	const endTime1 = currentTime1 + duration1;
    	if (scale !== "rest") {
    	    instrument1.triggerAttackRelease(scale, noteLengths1[index], currentTime1);
    	}
	currentTime1 = endTime1;
    });
    recordedNotes2.forEach((scale, index) => {
    	const duration2 = Tone.Time(noteLengths2[index]).toSeconds();
    	const endTime2 = currentTime2 + duration2;
        if (scale !== "rest") {
    	    instrument2.triggerAttackRelease(scale, noteLengths2[index], currentTime2);
        }
    	currentTime2 = endTime2;
    });
};

const stop = async () => {
    const track = document.getElementById("trackSelect").value;
    if (track === "track1") {
        instrument1.triggerRelease();
    } else if (track === "track2") {
        instrument2.triggerRelease();
    } else {
	return;
    }
};

const reset = () => {
    recordedNotes1 = [];
    recordedNotes2 = [];
    noteLengths1 = [];
    noteLengths2 = [];
    pianoRoll1 = [];
    pianoRoll2 = [];
    updatePianoRoll();
};

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

const setInstrument1 = (instrumentName) => {
	instrument1 = instruments[instrumentName];
};

const setInstrument2 = (instrumentName) => {
	instrument2 = instruments[instrumentName];
};

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

const decreaseOctave = () => {
    if (currentOctave > 1) {
        currentOctave--;
        document.getElementById("currentOctave").textContent = currentOctave;
    }
};
