#ifndef PROCESSOR_H
#define PROCESSOR_H

#include <iostream>
#include <string>
/*Data Storage Class DataSet*/
class VideoMemoryRaw {
  public:
    uint8_t* data;
    int width;
    int height;
    int channels;
    int frameCount;
    double fps;

    VideoMemoryRaw();
};
/*Transformer Class */

class Processor {
  private:
    int idx(int y, int x, int width); 

    float* allocateFloatBuffer(int size);

    uint8_t* allocateU8Buffer(int size); 

    void extractChannel(uint8_t* bgr,int width,int height,int channel,float* out);

    void interleaveChannels(uint8_t* B,uint8_t* G,uint8_t* R,int width,int height,uint8_t* outBGR);
    
    void normalizeFloatToU8(float* input,uint8_t* output,int size);


public:


    void processVideo(const std::string& inputPath,const std::string& outputPath); 
   
    VideoMemoryRaw* loadVideoToMemoryRowMajor(const std::string& inputPath);
    
    void freeVideoMemory(VideoMemoryRaw* vm); 

    uint8_t* getFramePointer(VideoMemoryRaw* vm, int frameIndex); 

    void processAllVideoFramesFromMemoryInPlace(VideoMemoryRaw* vm); 

    void  processVideoFromMemoryIndex(VideoMemoryRaw* vm, int frameIndex);

    void processVideoFromMemoryIndexChannel(VideoMemoryRaw* vm,int frameIndex,int channelIndex);

    void saveVideoFromMemory(VideoMemoryRaw* vm, const std::string& outputPath);

    void  saveVideoFromMemoryRange(VideoMemoryRaw* vm,int startFrame,int endFrame,const std::string& outputPath);

    void saveVideoFromMemory(VideoMemoryRaw* vm,const std::string& outputPath,int selectedChannel);
   
    void saveThreeChannelVideosFromMemory(VideoMemoryRaw* vm,const std::string& blueOutputPath,const std::string& greenOutputPath,const std::string& redOutputPath);
};

#endif
