import {Instrument} from "./Instrument";
import {MidiInstrument} from "./VoiceData/Instructions/ClefInstruction";
import log from "loglevel";

export class SubInstrument {

    constructor(parentInstrument: Instrument) {
        // console.log(parentInstrument, 'parentInstrument')
        this.parentInstrument = parentInstrument;
        this.fixedKey = -1;
        this.name = this.parseMidiInstrument(this.parentInstrument.Name);
        this.midiInstrumentID = SubInstrument.midiInstrument[this.name];
        this.volume = 1.0;
    }

    private static midiInstrument: { [key: string]: MidiInstrument } = {
        "alto_saxophone": MidiInstrument.Alto_Sax, // 中音萨克斯
        "baritone_saxophone": MidiInstrument.Baritone_Sax, // 男中音萨克斯
        "horn_in_f": MidiInstrument.French_Horn, // 圆号
        "english_horn": MidiInstrument.English_Horn, // 英国号
        "euphonium": MidiInstrument.Euphonium, // 上低音号
        "clarinet_in_bb": MidiInstrument.clarinet_in_bb, // 降B调单簧管
        "clarinet_in_eb": MidiInstrument.clarinet_in_eb, // 降E调单簧管
        "clarinet": MidiInstrument.Clarinet,
        "alto_clarinet": MidiInstrument.Alto_Clarinet, // 中音单簧管
        "bass_clarinet": MidiInstrument.Bass_Clarinet, // 低音单簧管
        "bassoon": MidiInstrument.Bassoon, // 巴松管
        "bass_trombone": MidiInstrument.Bass_Trombone, // 低音长号
        "alt": MidiInstrument.Synth_Voice,
        "alto": MidiInstrument.Synth_Voice,
        "banjo": MidiInstrument.Banjo,
        "bariton": MidiInstrument.Synth_Voice,
        "baritone": MidiInstrument.Synth_Voice,
        "bass": MidiInstrument.Synth_Voice,
        "blockflöte": MidiInstrument.Recorder,
        "brass": MidiInstrument.Trombone,
        "bratsche": MidiInstrument.Viola,
        "cello": MidiInstrument.Cello,
        "contrabass": MidiInstrument.Contrabass,
        "drums": MidiInstrument.Percussion,
        "flute": MidiInstrument.Flute,
        "flöte": MidiInstrument.Flute,
        "frenchhorn": MidiInstrument.French_Horn,
        "gitarre": MidiInstrument.Acoustic_Guitar_nylon,
        "guitar": MidiInstrument.Acoustic_Guitar_nylon,
        "harfe": MidiInstrument.Orchestral_Harp,
        "harp": MidiInstrument.Orchestral_Harp,
        "klarinette": MidiInstrument.Clarinet,
        "klavier": MidiInstrument.Acoustic_Grand_Piano,
        "kontrabass": MidiInstrument.Contrabass,
        "oboe": MidiInstrument.Oboe,
        "organ": MidiInstrument.Church_Organ,
        "orgel": MidiInstrument.Church_Organ,
        "orgue": MidiInstrument.Church_Organ,
        "percussion": MidiInstrument.Synth_Drum,
        "小军鼓": MidiInstrument.Synth_Drum,
        "snare_drum": MidiInstrument.Synth_Drum,
        "bass_drum": MidiInstrument.Synth_Drum,
        "side_drum": MidiInstrument.Synth_Drum,
        "piano": MidiInstrument.Acoustic_Grand_Piano,
        "piccolo": MidiInstrument.Piccolo,
        "posaune": MidiInstrument.Trombone,
        "recorder": MidiInstrument.Recorder,
        "sax": MidiInstrument.Tenor_Sax,
        "schlagwerk": MidiInstrument.Percussion,
        "schlagzeug": MidiInstrument.Percussion,
        "sopran": MidiInstrument.Synth_Voice,
        "steeldrum": MidiInstrument.Steel_Drums,
        "streicher": MidiInstrument.String_Ensemble_1,
        "strings": MidiInstrument.String_Ensemble_1,
        "tenor": MidiInstrument.Synth_Voice,
        "tpt": MidiInstrument.Trumpet,
        "trombone": MidiInstrument.Trombone,
        "trompete": MidiInstrument.Trumpet,
        "trumpet": MidiInstrument.Trumpet,
        "tuba": MidiInstrument.Tuba,
        "unnamed": MidiInstrument.Acoustic_Grand_Piano,
        "viola": MidiInstrument.Viola,
        "violin": MidiInstrument.Violin,
        "violon-c": MidiInstrument.Cello,
        "violon.": MidiInstrument.Violin,
        "voice": MidiInstrument.Synth_Voice,
        "woodblock": MidiInstrument.Woodblock,
        "alto_clarinet_in_eb": MidiInstrument.AltoClarinetInEb,
        "trumpet_in_bb": MidiInstrument.TrumpetInBb,
        "tenor_saxophone": MidiInstrument.TenorSaxophone,

    };

    public idString: string;
    public midiInstrumentID: MidiInstrument;
    public volume: number;
    public pan: number;
    public fixedKey: number;
    public name: string;

    private parentInstrument: Instrument;

    public get ParentInstrument(): Instrument {
        return this.parentInstrument;
    }
    public static isPianoInstrument(instrument: MidiInstrument): boolean {
        return (instrument === MidiInstrument.Acoustic_Grand_Piano
          || instrument === MidiInstrument.Bright_Acoustic_Piano
          || instrument === MidiInstrument.Electric_Grand_Piano
          || instrument === MidiInstrument.Electric_Piano_1
          || instrument === MidiInstrument.Electric_Piano_2);
    }
    public setMidiInstrument(instrumentType: string): void {
        this.midiInstrumentID = SubInstrument.midiInstrument[this.parseMidiInstrument(instrumentType)];
    }

    private parseMidiInstrument(instrumentType: string): string {
        // FIXME: test this function
        try {
            // find the best match for the given instrumentType:
            if (instrumentType) {
                let tmpName: string = instrumentType.toLowerCase().trim();
                // Alto Saxophone 次中音萨克斯
                // Horn in F 圆号
                tmpName = tmpName.replace(/\s+/g, "_");
                // console.log(tmpName, "111111111 instrumentType");
                for (const key in SubInstrument.midiInstrument) {
                    if (tmpName.indexOf(key) !== -1) {
                        return key;
                    }
                }
            }
            // if the instrumentType didn't work, use the name:
            if (this.parentInstrument.Name) {
                let tmpName: string = this.parentInstrument.Name.toLowerCase().trim();
                // Alto Saxophone 次中音萨克斯
                // Horn in F 圆号
                tmpName = tmpName.replace(/\s+/g, "_");
                // console.log(tmpName, 'tmpName')
                for (const key in SubInstrument.midiInstrument) {
                    if (tmpName.indexOf(key) !== -1) {
                        return key;
                    }
                }
            }
        } catch (e) {
            log.error("Error parsing MIDI Instrument. Default to Grand Piano.");
        }
        return "unnamed";
    }

}
