//
//  Network.h
//  HARKlib
//
//  Created by Tomoyoshi Kinoshita on 2021/04/01.
//

#ifndef Network_h
#define Network_h

#import <Foundation/Foundation.h>

@class BaseDispatcher;
@class NetworkDef;

#define BEGIN_DECLARE_NODEDEF(type) \
    @interface type: NodeDef \
    - (void)build: (nonnull Network *)network \
            input: (nonnull DataSourceMap *)input \
            output: (nonnull DataSinkMap *)output; \

#define DECLARE_NODEDEF(type) \
    BEGIN_DECLARE_NODEDEF(type) \
    @end \


@interface Source: NSObject
@property(nonatomic, readonly, nonnull, getter=get_position) NSArray *position;
@property(nonatomic) float x;
@property(nonatomic) float y;
@property(nonatomic) float z;
@property(nonatomic) float power;
@property(nonatomic) int id;
@property(nonatomic) int sub_id;
@property(nonatomic) int mic_id;

- (nonnull id)init;
- (nonnull id)initWithId: (int)id x:(float)x y:(float)y z:(float)z subId: (int)subId micId: (int)micId power: (float)power;
- (nonnull NSArray *)get_position;
- (nonnull NSString *)description;
@end

@interface DataSource: NSObject
@end

@interface DataSink: NSObject
@end

@interface DataSourceMap: NSObject

- (nonnull DataSource *)get: (nonnull NSString *)name;

@end

@interface DataSinkMap: NSObject
- (nonnull DataSinkMap *)add_input: (nonnull NSString *)name
                 source: (nonnull DataSource *)source;
@end

@interface BaseNode: NSObject

- (nonnull BaseNode *)add_input: (nonnull NSString *)name
                 source: (nonnull DataSource *)source;
- (nonnull BaseNode *)add_input: (nonnull NSString *)name
                 string: (nonnull NSString *)string;
- (nonnull BaseNode *)add_input: (nonnull NSString *)name
                 number: (nonnull NSNumber *)number;
- (nonnull BaseNode *)add_input: (nonnull NSString *)name
                 boolean: (bool)value;

- (nonnull BaseNode *)loop_condition: (nonnull DataSource *)source;

- (nonnull DataSource *)get: (nonnull NSString *)name;

@end

@interface NodeDef: NSObject

@end

@interface Network: NSObject

- (void)dealloc;

- (nonnull BaseNode *)createNode: (nonnull NodeDef *)def
                            name: (nonnull NSString *)name
                      dispatcher: (nonnull BaseDispatcher *)dispatcher;

- (nonnull BaseNode *)createNode: (nonnull NodeDef *)def
                            name: (nonnull NSString *)name;

- (nonnull BaseNode *)createNode: (nonnull NodeDef *)def
                      dispatcher: (nonnull BaseDispatcher *)dispatcher;

- (nonnull BaseNode *)createNode: (nonnull NodeDef *)def;

- (nonnull Network *)createNetwork: (nonnull NetworkDef *)def
                            name: (nonnull NSString *)name
                      dispatcher: (nonnull BaseDispatcher *)dispatcher;

- (nonnull Network *)createNetwork: (nonnull NetworkDef *)def
                            name: (nonnull NSString *)name;

- (nonnull Network *)createNetwork: (nonnull NetworkDef *)def
                      dispatcher: (nonnull BaseDispatcher *)dispatcher;

- (nonnull Network *)createNetwork: (nonnull NetworkDef *)def;

+ (nonnull Network *)createNetwork: (nonnull NetworkDef *)def
                              name: (nonnull NSString *)name;

- (nonnull Network *)add_input: (nonnull NSString *)name
                 source: (nonnull DataSource *)source;
- (nonnull Network *)add_input: (nonnull NSString *)name
                 string: (nonnull NSString *)string;
- (nonnull Network *)add_input: (nonnull NSString *)name
                 number: (nonnull NSNumber *)number;
- (nonnull Network *)add_input: (nonnull NSString *)name
                 boolean: (bool)value;

- (nonnull Network *)loop_condition: (nonnull DataSource *)source;

- (nonnull DataSource *)get: (nonnull NSString *)name;

- (nullable NodeDef *)query_nodedef: (nonnull NSString *)name;

- (void)execute;

- (void)stop;

@end

@interface NetworkDef: NSObject

- (void)build: (nonnull Network *)network
        input: (nonnull DataSourceMap *)input
        output: (nonnull DataSinkMap *)output;

@end

@interface BaseDispatcher: NSObject
@end

@interface OneShotDispatcher: BaseDispatcher
@end

@interface RepeatDispatcher: BaseDispatcher
@end

@interface TriggeredOneShotDispatcher: BaseDispatcher
@end

@interface TriggeredMultiShotDispatcher: BaseDispatcher
@end

@interface TriggeredRepeatDispatcher: BaseDispatcher
@end

//DECLARE_NODEDEF(AND)
DECLARE_NODEDEF(Constant)
//DECLARE_NODEDEF(Delay)
//DECLARE_NODEDEF(Equal)
//DECLARE_NODEDEF(Grater)
//DECLARE_NODEDEF(IF)
DECLARE_NODEDEF(InputStream)
//DECLARE_NODEDEF(IterCount)
//DECLARE_NODEDEF(Iterate)
//DECLARE_NODEDEF(NOP)
//DECLARE_NODEDEF(NOT)
//DECLARE_NODEDEF(OR)
//DECLARE_NODEDEF(Sleep)
//DECLARE_NODEDEF(Smaller)

DECLARE_NODEDEF(AudioStreamFromMemory)
DECLARE_NODEDEF(AudioStreamFromWave)
//DECLARE_NODEDEF(BF)
//DECLARE_NODEDEF(BGNEstimator)
//DECLARE_NODEDEF(CMChannelSelector)
//DECLARE_NODEDEF(CMConjEachElement)
//DECLARE_NODEDEF(CMDivideEachElement)
//DECLARE_NODEDEF(CMIdentityMatrix)
//DECLARE_NODEDEF(CMInverseMatrix)
//DECLARE_NODEDEF(CMLoad)
//DECLARE_NODEDEF(CMMakerFromFFT)
//DECLARE_NODEDEF(CMMakerFromFFTwithFlag)
//DECLARE_NODEDEF(CMMultiplyEachElement)
//DECLARE_NODEDEF(CMMultiplyMatrix)
//DECLARE_NODEDEF(CMSave)
//DECLARE_NODEDEF(CSP)
//DECLARE_NODEDEF(CalcSpecAddPower)
//DECLARE_NODEDEF(CalcSpecSubGain)
//DECLARE_NODEDEF(ChannelSelector)
//DECLARE_NODEDEF(CombineMap)
//DECLARE_NODEDEF(CombineSource)
//DECLARE_NODEDEF(ConstantLocalization)
//DECLARE_NODEDEF(DataLogger)
DECLARE_NODEDEF(Delta)
//DECLARE_NODEDEF(DeltaMask)
//DECLARE_NODEDEF(DeltaPowerMask)
//DECLARE_NODEDEF(DisplayLocalization)
//DECLARE_NODEDEF(EstimateLeak)
//DECLARE_NODEDEF(EstimateTF)
DECLARE_NODEDEF(FeatureRemover)
//DECLARE_NODEDEF(GHDSS)
//DECLARE_NODEDEF(HRLE)
//DECLARE_NODEDEF(HarkDataStreamSender)
//DECLARE_NODEDEF(HarkParamDynReconf)
//DECLARE_NODEDEF(LoadMapFrames)
//DECLARE_NODEDEF(LoadSourceFrames)
//DECLARE_NODEDEF(LoadVectorFrames)
//DECLARE_NODEDEF(LocalizeBFDS)
//DECLARE_NODEDEF(LocalizeMUSIC)
//DECLARE_NODEDEF(MFCCExtraction)
//DECLARE_NODEDEF(MFMGeneration)
//DECLARE_NODEDEF(ML)
DECLARE_NODEDEF(MSLSExtraction)
//DECLARE_NODEDEF(MSNR)
//DECLARE_NODEDEF(MVDR)
//DECLARE_NODEDEF(MapIDOffset)
//DECLARE_NODEDEF(MapMatrixValueOverwrite)
//DECLARE_NODEDEF(MapOperator)
//DECLARE_NODEDEF(MapSelectorBySource)
//DECLARE_NODEDEF(MapToMap)
//DECLARE_NODEDEF(MapToMatrix)
//DECLARE_NODEDEF(MapToVector)
//DECLARE_NODEDEF(MapVectorValueOverwrite)
//DECLARE_NODEDEF(MatrixToMap)
//DECLARE_NODEDEF(MatrixToMatrix)
//DECLARE_NODEDEF(MatrixToVector)
//DECLARE_NODEDEF(MatrixValueOverwrite)
DECLARE_NODEDEF(MelFilterBank)
//DECLARE_NODEDEF(MultiDownSampler)
DECLARE_NODEDEF(MultiFFT)
//DECLARE_NODEDEF(MultiGain)
//DECLARE_NODEDEF(MultiLocalizationIntegrator)
//DECLARE_NODEDEF(NormalizeMUSIC)
//DECLARE_NODEDEF(PlayAudio)
//DECLARE_NODEDEF(PostFilter)
//DECLARE_NODEDEF(PowerCalcForMap)
//DECLARE_NODEDEF(PowerCalcForMatirx)
DECLARE_NODEDEF(PreEmphasis)
//DECLARE_NODEDEF(ResizeMapMatrixValue)
//DECLARE_NODEDEF(ResizeMapVectorValue)
DECLARE_NODEDEF(SaveFeatures)
//DECLARE_NODEDEF(SaveHTKFeatures)
//DECLARE_NODEDEF(SaveMapFrames)
//DECLARE_NODEDEF(SaveMatrixFrames)
//DECLARE_NODEDEF(SaveRawPCM)
//DECLARE_NODEDEF(SaveSourceLocation)
//DECLARE_NODEDEF(SaveVectorFrames)
DECLARE_NODEDEF(SaveWavePCM)
//DECLARE_NODEDEF(SegmentAudioStreamByID)
DECLARE_NODEDEF(SemiBlindICA)
//DECLARE_NODEDEF(SourceIntervalExtender)
//DECLARE_NODEDEF(SourceSelectorByDirection)
//DECLARE_NODEDEF(SourceSelectorByID)
//DECLARE_NODEDEF(SourceSelectorBySourceInfo)
//DECLARE_NODEDEF(SourceTracker)
//DECLARE_NODEDEF(SourceTrackerPF)
//DECLARE_NODEDEF(SourceTransformer)
//DECLARE_NODEDEF(SpectralGainFilter)
//DECLARE_NODEDEF(SpectralMeanNormalization)
DECLARE_NODEDEF(SpectralMeanNormalizationIncremental)
DECLARE_NODEDEF(SpeechRecognitionClient)
//DECLARE_NODEDEF(SpeechRecognitionSMNClient)
//DECLARE_NODEDEF(SubscribeFLAC)
DECLARE_NODEDEF(Synthesize)
//DECLARE_NODEDEF(TextConcatenate)
//DECLARE_NODEDEF(TextConverter)
DECLARE_NODEDEF(VADZC)
DECLARE_NODEDEF(VectorToMap)
DECLARE_NODEDEF(VectorToMatrix)
DECLARE_NODEDEF(VectorToVector)
DECLARE_NODEDEF(VectorValueOverwrite)
DECLARE_NODEDEF(WhiteNoiseAdder)

DECLARE_NODEDEF(VADPyAnnote)
DECLARE_NODEDEF(Print)

BEGIN_DECLARE_NODEDEF(PublishData)

- (void)push: (nonnull NSObject *)value;

- (void)pushInt16Vector: (nonnull const SInt16 *)value
                    count: (size_t)count;

@end

@protocol SubscribeDataDelegate

- (void)receive: (nonnull NSObject *)value;

@end

BEGIN_DECLARE_NODEDEF(SubscribeData)
@property(weak, nonatomic, nullable, setter=set_delegate:) id <SubscribeDataDelegate> delegate;
- (nonnull id)init: (nonnull id<SubscribeDataDelegate>)delegate;
- (void)set_delegate: (nonnull id<SubscribeDataDelegate>)delegate;
@end

#endif /* Network_h */
