#ifndef __DETECTOR_RETINAFACE_H__
#define __DETECTOR_RETINAFACE_H__

#include <migraphx/program.hpp>
#include <CommonDefinition.h>
#include <SSDDefinition.h>

namespace migraphxSamples
{

class DetectorRetinaFace
{
    public:
    DetectorRetinaFace();

    ~DetectorRetinaFace();

    ErrorCode Initialize(InitializationParameterOfDetector initializationParameterOfDetector);

    ErrorCode Detect(const cv::Mat& srcImage, std::vector<ResultOfDetection>& resultsOfDetection);

    private:
    void GetSSDParameter();
    void GetResult(const std::vector<std::vector<float>>& classification,
                   const std::vector<std::vector<float>>& regression,
                   std::vector<ResultOfDetection>& resultsOfDetection);

    std::vector<float>
    PermuteLayer(const std::vector<float>& data, int width, int height, int channels);
    void PriorBoxLayer(int indexOfLayer, int* priorboxOutputData);
    void SoftmaxLayer(int softMaxWidth[], int* softMaxInputData[], int* softMaxOutputData);
    void DetectionOutputLayer(int* allLocPreds[],
                              int* allPriorBoxes[],
                              int* confScores,
                              int* assistMemPool);

    void ComputeSoftMax(int* src, int size, int* dst);
    void QuickSort(int* src, int low, int high, QuickSortStack* stack, int maxNum);
    void NonMaxSuppression(int* proposals, int anchorsNum, int NMSThresh, int maxRoiNum);
    void Swap(int* src1, int* src2);
    void ComputeOverlap(int xMin1,
                        int yMin1,
                        int xMax1,
                        int yMax1,
                        int xMin2,
                        int yMin2,
                        int xMax2,
                        int yMax2,
                        int* areaSum,
                        int* areaInter);
    void CreateDetectionResults(std::vector<ResultOfDetection>& resultsOfDetection);

    private:
    cv::FileStorage configurationFile;

    migraphx::program net;
    cv::Size inputSize;
    std::string inputName;
    migraphx::shape inputShape;

    float scale;
    cv::Scalar meanValue;
    bool swapRB;
    bool crop;
    bool useInt8;
    bool useFP16;

    SSDParameter ssdParameter;
};

} // namespace migraphxSamples

#endif
