#ifndef _P1_IMAGESDK_STITCHING_HPP_
#define _P1_IMAGESDK_STITCHING_HPP_


#include <memory>

#include "P1ImageRawImage.hpp"

namespace P1
{ 
    namespace ImageSdk
    {
        class CStitching;
        enum StitcherResult;

        class EXPORT_API Stitching
        {
        public:
            Stitching();

            ~Stitching();

            /** @brief A class to stitch L and R images from a PAS280 camera. The left image is regarded as the master image. The stitcher will seamlessly merge togther the two images into one large image.
            * @param leftImage is a reference to the left image (containing metadata etc.) 
            * @param leftBitmap is a reference to a bitmap of the left image
            * @param rightImage is a reference to the right image (containing metadata etc.)
            * @param rightBitmap is a reference to a bitmap of the right image            
            * @param alloc is an allocator that is used to allocate memory for the output bitmap. Its an optional parameter and should not be used unless its important for the host program.
            * @throw throws an SdkException on errors
            * @return A bitmap containing the stitched image. The memory for the bitmap is allocated by the allocator and must be freed by the host software when not needed.
            */
            P1::ImageSdk::BitmapImage DoStitching(P1::ImageSdk::RawImage& leftImage, P1::ImageSdk::BitmapImage& leftBitmap, P1::ImageSdk::RawImage& rightImage, P1::ImageSdk::BitmapImage& rightBitmap, std::allocator<uint8_t> alloc = std::allocator<uint8_t>());


            /** @brief A class to stitch L and R images from a PAS280 camera. The left image is regarded as the master image. The stitcher will seamlessly merge togther the two images into one large image.
            * @param leftImage is a reference to the left image (containing metadata etc.)
            * @param leftBitmap is a reference to a bitmap of the left image
            * @param leftCalibration is a reference to geometric calibration for left image
            * @param rightImage is a reference to the right image (containing metadata etc.)
            * @param rightBitmap is a reference to a bitmap of the right image
            * @param rightCalibration is a reference to geometric calibration for right image
            * @param alloc is an allocator that is used to allocate memory for the output bitmap. Its an optional parameter and should not be used unless its important for the host program.
            * @throw throws an SdkException on errors
            * @return A bitmap containing the stitched image. The memory for the bitmap is allocated by the allocator and must be freed by the host software when not needed.
            */
            P1::ImageSdk::BitmapImage DoStitching(P1::ImageSdk::RawImage& leftImage, P1::ImageSdk::BitmapImage& leftBitmap, P1::ImageSdk::GeometricCorrection& leftCalibration, P1::ImageSdk::RawImage& rightImage, P1::ImageSdk::BitmapImage& rightBitmap, P1::ImageSdk::GeometricCorrection& rightCalibration, double nominalFocalLength, std::allocator<uint8_t> alloc = std::allocator<uint8_t>());

            int CalculateAverageLumaForOverlap(P1::ImageSdk::RawImage& image);
            
            /** @brief Setup a fine calibration. A finecalibration is a binary blob setup by the stitcher itself that can speed up the stitching process. 
            * @param fineCalibrationData is a pointer to the data where the fine calibration to setup is stored.
            * @param fineCalibrationLength is an integer that tells how much memory the finecalibration is using
            */
            void SetFineCalibration(uint8_t* fineCalibrationData, uint32_t fineCalibrationLength);
            /** @brief Get a pointer to the fine calibration data from the stitcher*/
            uint8_t* GetFineCalibrationData();
            /** @brief Get an integer with the length of the fine calibration data in the stitcher*/
            uint32_t GetFineCalibrationLength();     

            /** @brief Get the last result of the stitcher. This can be used to get info about errors and warnings that had an impact on the stitching. Errors will cause the stitcher to throw an excetion*/
            StitcherResult GetLastResult();

        private:
            P1::ImageSdk::CStitching* mStitcher = nullptr;
        };
    }
}

#endif // _P1_IMAGESDK_STITCHING_HPP_
