using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using HARKlib;

namespace HARKlibSample
{
    class Extracting : NetworkDef
    {
        public override void build(Network network, DataSourceMap input, DataSinkMap output)
        {
            var node_multi_fft = network.create<MultiFFT>("MultiFFT");
            var node_feature_remover = network.create<FeatureRemover>("FeatureRemover");
            var node_delta = network.create<Delta>("Delta");
            var node_mel_filter_bank = network.create<MelFilterBank>("MelFilterBank");
            var node_msls_extraction = network.create< MSLSExtraction>("MSLSExtraction");
            var node_pre_emphasis = network.create<PreEmphasis>("PreEmphasis");

            node_multi_fft
                .add_input("INPUT", input["CHANNEL_WAV"]);

            node_feature_remover
                .add_input("INPUT", node_delta["OUTPUT"])
                .add_input("SELECTOR", "40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81");

            node_mel_filter_bank
                .add_input("INPUT", node_pre_emphasis["OUTPUT"])
                .add_input("FBANK_COUNT", 40);

            node_msls_extraction
                .add_input("FBANK", node_mel_filter_bank["OUTPUT"])
                .add_input("SPECTRUM", node_pre_emphasis["OUTPUT"])
                .add_input("FBANK_COUNT", 40)
                .add_input("NORMALIZATION_MODE", "SPECTRAL")
                .add_input("USE_POWER", true);

            node_pre_emphasis
                .add_input("INPUT", node_multi_fft["OUTPUT"])
                .add_input("INPUT_TYPE", "SPECTRUM");

            node_delta
                .add_input("INPUT", node_msls_extraction["OUTPUT"]);

            output
                .add_input("OUTPUT", node_feature_remover["OUTPUT"]);
        }
    }

    class Recording : NetworkDef
    {
        public override void build(Network network, DataSourceMap input, DataSinkMap output)
        {
            var node_extracting = network.create<Extracting>("Extracting");
            var node_speech_recognition_client = network.create<SpeechRecognitionClient>("SpeechRecognitionClient");
            var node_spectral_mean_normalization_incremental = network.create<SpectralMeanNormalizationIncremental>("SpectralMeanNormalizationIncremental");
            var node_vad_zc = network.create<VADZC>("VAD_ZC");
            var node_save_features = network.create<SaveFeatures>("SaveFeatures");
            var node_save_wave_pcm2 = network.create<SaveWavePCM2>("SaveWavePCM2");
            var node_audio_stream_from_memory = network.create<AudioStreamFromMemory, TriggeredMultiShotDispatcher>("AudioStreamFromMemory");
            var node_publisher = network.create<PublishData, RepeatDispatcher>("Publisher");
            var node_subscriber = network.create<SubscribeData>("Subscriber");
            var node_source_subscriber = network.create<SubscribeData>("Subscriber_Source");

            node_audio_stream_from_memory
                .add_input("INPUT", node_publisher["OUTPUT"]);

            node_vad_zc
                .add_input("INPUT", node_audio_stream_from_memory["AUDIO"])
                .add_input("CHANNEL_COUNT", 1)
                .add_input("LEVEL_THRESHOLD", 60.0)
                .add_input("ZEROCROSS_THRESHOLD", 80)
                .add_input("HEAD_MARGIN", 400.0)
                .add_input("TAIL_MARGIN", 600.0);

            node_source_subscriber
                .add_input("INPUT", node_vad_zc["SOURCES"]);

            node_extracting
                .add_input("CHANNEL_WAV", node_vad_zc["OUTPUT"]);

            node_spectral_mean_normalization_incremental
            .add_input("INPUT",  node_extracting["OUTPUT"])
            .add_input("NOT_EOF", true) // ToDo
            .add_input("SM_HISTORY", false) // ToDo
            .add_input("PERIOD", 1)
            .add_input("BASENAME", "")
            .add_input("OUTPUT_FNAME", "");

            node_speech_recognition_client
            .add_input("FEATURES", node_spectral_mean_normalization_incremental["OUTPUT"])
            .add_input("MASKS", node_spectral_mean_normalization_incremental["OUTPUT"])
            .add_input("SOURCES", node_vad_zc["SOURCES"])
            .add_input("MFM_ENABLED", false);

            node_save_features
            .add_input("FEATURES", node_spectral_mean_normalization_incremental["OUTPUT"])
            .add_input("SOURCES", node_vad_zc["SOURCES"])
            .add_input("BASENAME", "feature_");

            node_save_wave_pcm2
            .add_input("ENABLE", false)
            .add_input("INPUT", node_vad_zc["OUTPUT"])
            .add_input("BASENAME", "pcm_{srcid}_");

            node_subscriber
                .add_input("INPUT", node_spectral_mean_normalization_incremental["OUTPUT"]);
        }
    }

    class Main : NetworkDef
    {
        public override void build(Network network, DataSourceMap input, DataSinkMap output)
        {
            var loop = network.create<Recording>("Recording");
   
        }

    }
}
