///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022-2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxafcinterface.h
/// @brief AFC - Flicker Correction Gain algorithms interfaces
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXAFCINTERFACE_H
#define CAMXAFCINTERFACE_H

#include "chi.h"
#include "chistatsinterfacedefs.h"
#include "chistatsdebug.h"
#include "chiafcommon.h"
#include "camxutils.h"
#include "camxosutils.h"
#include <complex>
#include "chistatspropertydefines.h"

#define GainLUTMaxCount 128
#define DarkBrightThresholdMaxCount 4

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

// Data structures that are exposed to OEM must be packed to have the expected layout.
#pragma pack(push, CDK_PACK_SIZE)

/// @brief Operation modes for the AFC algorithm.
typedef enum
{
    AFCAlgoOperationModeVideo,                        ///< Video / Preview Mode
    AFCAlgoOperationModeSnapshot,                     ///< Snapshot Mode
    AFClgoOperationModeCount,                         ///< Maximum number of operation modes.
} AFCAlgoOperationModeType;

/// @brief AEC information consumed by the AFC algorithm.
typedef struct
{
    BOOL             isAECsettled;                           ///< Indicates whether the AEC is settled.
                                                             ///
                                                             ///  @valuesbul
                                                             ///  - 0 -- FALSE
                                                             ///  - 1 -- TRUE @tablebulletend

    FLOAT            luxIDx;                                 ///< Current index of the lux value.
    FLOAT            realGain[MaxNumOfInputExposures];       ///< Current gain from the AEC.
    FLOAT            currentExpTime[MaxNumOfInputExposures]; ///< Current exposure time from the AEC.
    AECFlashInfoType flashInfo;                              ///< Type of flash: main or preflash.
    FLOAT            compenADRCGain;                         ///< DRC value from AEC.
    FLOAT            compensationDarkBoostGain;              ///< Compensation for dark boost gain.
    FLOAT            LEDInfluenceRatio;                      ///< LED Influence ratio
} AFCAECInfo;

/// @brief Autofocus output information consumed by the AFC.
typedef struct
{
    BOOL                isValid;             ///< Indicates whether autofocus information is valid.
    BOOL                isAFSearching;       ///< Indicates whether autofocus is actively searching.
                                             ///
                                             ///  @valuesbul
                                             ///  - 0 -- FALSE
                                             ///  - 1 -- TRUE @tablebulletend

    AFLensPositionInfo  lensPositionInfo;    ///< Information about the lens position and movement type.
} AFCAFInfo;

/// @brief Sensor information consumed by the AFC.
typedef struct
{
    FLOAT  maxFPS;                              ///< Maximum number of frames per second from the sensor for this mode.
    UINT   binningTypeH;                        ///< Horizontal binning.
    UINT   binningTypeV;                        ///< Vertical binning.
    UINT   numLinesPerFrame;                    ///< Number of lines per frame (frameLengthLines).
    FLOAT  rowSumTime[MaxNumOfInputExposures];  ///< Time taken to generate from the first pixel of the first line to the
                                                ///  last pixel of the last line.
    FLOAT  curFPS;                              ///< Number of frames per second in the current use case.
    UINT32 sensorHeight;                        ///< Height of the sensor.
    UINT32 sensorWidth;                         ///< Width of the sensor.
    HDRTypeValues   hdrMode;                    ///< Type of HDR MFHD/SHDR
} AFCSensorInfo;

/// @brief Frame information consumed by the AFC.
typedef struct
{
    UINT64                 requestId;                               ///< Request
    UINT64                 timeStamps[MaxNumOfInputExposures];      ///< Frame Time Stamps
    AFCAECInfo             aecInfo;                                 ///< AEC Info
    AFCAFInfo              afInfo;                                  ///< AF Info
    AFCSensorInfo          sensorInfo;                              ///< Sensor Info
    FLOAT                  flickerFrequency;                        ///< Flicker Frequency Computed by AFD
    BOOL                   isFlickerDetected;                       ///< Flicker Detected Flag Computed by AFD
    StatisticsAntibanding  AFDMode;                                 ///< AFD Mode
    StatsGyroInfo          gyroData;                                ///< Gyro Data
    UINT64                 flickerFlagID;                           ///< Request ID on which flicker is analyzed
} AFCFrameInfo;

/// @brief Defines manual override settings that are set to the AFD algorithm.
typedef struct
{
    // All the override flags will be added here
    // These setting will be used to override tuning settings
    UINT32 profile3A;                       ///< 3A profiling value.
    BOOL   enable3ADebugData;               ///< Flag to enable or disable 3A debug data.
    BOOL   enable3ADebugDataCustomFilter;   ///< Flag to enable or disable customized tag filter
} AFCAlgoOverrideSetting;

/// @brief FCG Config
typedef struct
{
    BOOL                enable;                                         ///< Enable Flag for Module
    UINT8               gainTableSize;                                  ///< Size of the Gain Table
    FLOAT               gainLUT[GainLUTMaxCount];                       ///< LUT Table
    FLOAT               LUTSampleRate;                                  ///< Sample rate for LUT
    FLOAT               phaseIdxR;                                      ///< Phase Index R
    FLOAT               phaseIdxG;                                      ///< Phase Index G
    FLOAT               phaseIdxB;                                      ///< Phase Index B
    FLOAT               scaleR;                                         ///< Scale for Color R
    FLOAT               scaleG;                                         ///< Scale for Color G
    FLOAT               scaleB;                                         ///< Scale for Color B
    FLOAT               offsetR;                                        ///< Offset for Color R
    FLOAT               offsetG;                                        ///< Offset for Color G
    FLOAT               offsetB;                                        ///< Offset for Color B
    UINT8               interpolationType;                              ///< Type of Interpolation
    UINT8               pixelScreeningEnable;                           ///< Enable flag for Pixel Screening
    UINT8               quadSyncEnable;                                 ///< Enable flag for Quad Sync
    UINT32              darkThreshold1[DarkBrightThresholdMaxCount];    ///< Lower Threshold 1 for Pixel Screening
    UINT32              darkThreshold2[DarkBrightThresholdMaxCount];    ///< Lower Threshold 2 for Pixel Screening
    UINT32              brightThreshold1[DarkBrightThresholdMaxCount];  ///< Upper Threshold 1 for Pixel Screening
    UINT32              brightThreshold2[DarkBrightThresholdMaxCount];  ///< Upper Threshold 2 for Pixel Screening
    FLOAT               nextFramesPhaseIdxR[AFCNumFutureFrameData];     ///< Phase Index R for Future Frames
    FLOAT               nextFramesPhaseIdxG[AFCNumFutureFrameData];     ///< Phase Index G for Future Frames
    FLOAT               nextFramesPhaseIdxB[AFCNumFutureFrameData];     ///< Phase Index B for Future Frames
} AFCAlgoFCGConfig;

/// @brief AFC Flicker Info
typedef struct
{
    FCGStateType            FCGState;                ///<  Current FCG State
    BOOL                    isFlickerDetected;       ///< Is Flicker Detected
    UINT64                  minExpTimeToCorrect;     ///<  Min exposure time required to correct banding
} AFCFlickerInfoType;

/// @brief Types of Process input parameters for the AFC algorithm.
typedef enum
{
    AFCAlgoInputTypeInvalid         = -1,       ///< Type is invalid or unknown.
    AFCAlgoInputBayerRowSum,                    ///< The Bayer row sum stats
                                                ///  Payload: #StatsBayerRowSum.
    AFCAlgoInputTypeDebugData,                  ///< The AFC debug data
                                                ///  Payload: #StatsDataPointer.
    AFCInputTypeCount,                          ///< Total number of parameters.
} AFCAlgoInputType;

/// @brief Base structure of a Process input parameter for the AFC algorithm instance. This structure is used with
///        #AFCAlgoInputList.
typedef struct
{
    VOID*                   pAFCInput;          ///< Pointer to the parameter payload.
    UINT32                  sizeOfAFCInput;     ///< Size of the input payload data.
    AFCAlgoInputType        inputType;          ///< Type of input payload.
                                                ///  @newpagetable
} AFCAlgoInput;

/// @brief List of Process input parameters that are passed to #AFCAlgorithm::AFCProcess().
typedef struct
{
    AFCAlgoInput*           pAFCInputs;         ///< Pointer to the array of parameters.
    UINT32                  inputCount;         ///< Number of elements in the array.
} AFCAlgoInputList;

/// @brief Types of Process output parameters for the AFC algorithm.
typedef enum
{
    AFCAlgoOutputTypeInvalid            = -1,       ///< Type is invalid or unknown.
    AFCAlgoOutputFCGConfig,                         ///< Array of FCG Config
                                                    ///  Payload AFCAlgoFCGConfig
    AFCAlgoOutputTemporalContext,                   ///< StatsTemporalContext
                                                    ///  Payload StatsTemporalContext (Short Exposure)
    AFCAlgoOutputFlickerInfo,                       ///< Flicker Information computed by AFC
                                                    ///  Payload AFCFlickerInfoType
    AFCOutputTypeCount                              ///< Total number of parameters.
} AFCAlgoOutputType;

/// @brief Base structure of a Process output parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoOutputList.
typedef struct
{
    VOID*                   pAFCOutput;              ///< Pointer to the payload that is the result of the query.
                                                     ///  The type of data depends on the value of outputType. The
                                                     ///  algorithm implementer must do a deep copy to the given memory.
    UINT32                  sizeOfAFCOutput;         ///< Size of the payload data (in bytes).
    UINT32                  sizeOfWrittenAFCOutput;  ///< Size of the payload data that is written back.
                                                     ///  If there is no output, set this value to 0.
    AFCAlgoOutputType   outputType;                  ///< Type of parameter that is passed to the algorithm.
} AFCAlgoOutput;

/// @brief List of Process output parameters that are passed to #AFCAlgorithm::AFCProcess().
typedef struct
{
    AFCAlgoOutput*      pAFCOutputs;            ///< Pointer to the array of parameters.
    UINT32              outputCount;        ///< Number of elements in the array.
} AFCAlgoOutputList;

/// @brief Types of Get input parameters for the AFC algorithm.
typedef enum
{
    AFCAlgoGetParamInputTypeInvalid = -1,           ///< Type is invalid or unknown.
    AFCAlgoGetParamInputTypeCount,                  ///< Total number of parameters.
} AFCAlgoGetParamInputType;

/// @brief Base structure of a Get input parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoGetParamInputList.
typedef struct
{
    VOID*                           pGetParamInput;         ///< Pointer to the parameter payload.
    UINT32                          sizeOfGetParamInput;    ///< Size of the payload data (in bytes).
    AFCAlgoGetParamInputType        getParamInputType;      ///< Type of input payload.
} AFCAlgoGetParamInput;

/// @brief List of Get input parameters for an AFC algorithm instance. This list is passed to #AFCAlgoGetParam.
typedef struct
{
    AFCAlgoGetParamInput*       pGetParamInputs;     ///< Pointer to the array of parameters.
    UINT32                      getParamInputCount;  ///< Number of elements in the array.
} AFCAlgoGetParamInputList;

/// @brief Types of Get output parameters for the AFC algorithm.
typedef enum
{
    AFCAlgoGetParamOutputTypeInvalid = -1,              ///< Type is invalid or unknown.
    AFCAlgoGetParamOutputTypeCount,                     ///< Total number of parameters.
} AFCAlgoGetParamOutputType;

/// @brief Base structure of a Get output parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoGetParamOutputList.
typedef struct
{
    VOID*                           pGetParamOutput;                ///< Pointer to the payload that is the result of the
                                                                    ///  query. The type of data depends on the value of
                                                                    ///  getParamOutputType.
    UINT32                          sizeOfGetParamOutput;           ///< Size of the payload data (in bytes).
    UINT32                          sizeOfWrittenGetParamOutput;    ///< Size of the payload (in bytes) that is written back.
                                                                    ///  If there is no output, set this value to 0.
    AFCAlgoGetParamOutputType   getParamOutputType;                 ///< Type of parameter that is passed to the algorithm.
} AFCAlgoGetParamOutput;

/// @brief List of Get output parameters for an AFC algorithm instance. This structure is used with #AFCAlgoGetParam.
typedef struct
{
    AFCAlgoGetParamOutput*      pGetParamOutputs;           ///< Pointer to the array of outputs.
    UINT32                          getParamOutputCount;    ///< Number of elements in pGetParamOutputs.
                                                            ///  @newpagetable
} AFCAlgoGetParamOutputList;

/// @brief List of Get parameters that are passed to #AFCAlgorithm::AFCGetParam().
typedef struct
{
    AFCAlgoGetParamInputList    inputInfoList;   ///< Input data that is necessary to support the query.
    AFCAlgoGetParamOutputList   outputInfoList;  ///< Output metadata that is returned as a result of the query.
} AFCAlgoGetParam;

/// @brief Types of Set parameters for the AFC algorithm.
typedef enum
{
    AFCAlgoSetParamTypeInvalid          = -1,           ///< Type is unknown or invalid.
    AFCAlgoSetParamChromatixData,                       ///< The chromatix tuning header for AFC
                                                        ///  Payload: #StatsTuningData
    AFCAlgoSetParamFrameInfo,                           ///< Frame Info
                                                        ///  Payload: #AFCFrameInfo
    AFCAlgoSetParamTemporalContext,                     ///< Temporal Context Information
                                                        ///  Payload: #StatsTemporalContext
    AFCAlgoSetParamPipelineDelay,                       ///< Pipeline Delay
                                                        ///  Payload type: UINT8
    AFCAlgoSetParamCameraInfo,                          ///< CameraInfo
                                                        ///  Payload: #StatsCameraInfo
    AFCDumpDataFlag,                                    ///< AFC Data
                                                        ///  Payload type: BOOL
    AFCAlgoSetParamOverrideSettings,                    ///< AFC Override Settings
                                                        ///  Payload type: AFCAlgoOverrideSetting
    AFCAlgoSetParamTypeCount,                           ///< Total number of parameters.
} AFCAlgoSetParamType;

/// @brief Base structure of a Set parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoSetParamList.
typedef struct
{
    VOID*                    pAFCSetParam;          ///< Pointer to the parameter payload.
    UINT32                   sizeOfSetParam;        ///< Size of the payload data (in bytes).
    AFCAlgoSetParamType      setParamType;          ///< Type of parameter that is passed to the algorithm.
} AFCAlgoSetParam;

/// @brief List of Set parameters that are passed to #AFCAlgorithm::AFCSetParam().
typedef struct
{
    AFCAlgoSetParam*        pAFCSetParams;    ///< Pointer to the array of parameters.
    UINT32                  setParamsCount;   ///< Number of elements in the array.
} AFCAlgoSetParamList;

/// @brief Parameters used when creating an AFC algorithm instance.
typedef enum
{
    AFCCreateParamsTypeInvalid      = -1,           ///< Type is unknown or invalid.
    AFCCreateParamsTypeOperationMode,                ///< Payload: AFCAlgoOperationModeType
    AFCCreateParamsTypeLogger,                      ///< Payload: Logger function structure
    AFCCreateParamsTypeCameraInfo,                  ///< Payload: #StatsCameraInfo
    AFCCreateParamsTypeCount,                       ///< Total number of parameters.
    AFCCreateParamsTypeMax          = 0x7FFFFFFF    ///< Indicates the last item in the definition.
} AFCAlgoCreateParamType;

/// @brief Base structure of a Create parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoCreateParamList.
typedef struct
{
    VOID*                       pCreateParam;           ///< Pointer to the parameter payload.
    UINT32                      sizeOfCreateParam;      ///< Size of the payload data (in bytes).
    AFCAlgoCreateParamType      createParamType;        ///< Type of parameter that is passed to the algorithm.
} AFCAlgoCreateParam;

/// @brief List of Create parameters that are passed to CREATEAFC().
typedef struct
{
    AFCAlgoCreateParam*     pCreateParams;          ///< Pointer to the array of parameters.
    UINT32                  createParamsCount;      ///< Number of elements in the array.
} AFCAlgoCreateParamList;

/// @brief Types of Destroy parameters for the AFC algorithm.
typedef enum
{
    AFCDestroyParamTypeInvalid               = -1,  ///< Type is invalid or unknown.
    AFCDestroyParamTypeCameraID,                    ///< Identifier for the camera.
    AFCDestroyParamTypeCount,                       ///< Total number of parameters.
} AFCAlgoDestroyParamType;

/// @brief Base structure of a Destroy parameter for an AFC algorithm instance. This structure is used with
///        #AFCAlgoDestroyParamList.
typedef struct
{
    AFCAlgoDestroyParamType destroyParamType;       ///< Type of parameter that is passed to the algorithm.
    VOID*                       pParam;             ///< Pointer to the parameter payload.
    UINT32                      sizeOfParam;        ///< Size of the payload data (in bytes).
} AFCAlgoDestroyParam;

/// @brief List of Destroy parameters that are passed to #AFCAlgorithm::AFCDestroy().
typedef struct
{
    AFCAlgoDestroyParam*    pParamList;         ///< Pointer to the array of parameters.
    UINT32                  paramCount;         ///< Number of elements in the array.
} AFCAlgoDestroyParamList;

/// @brief Represents AFC algorithm settings controlled from the camxsettings.xml file.
typedef struct
{
    BOOL                        profile;   ///< Indicates whether profiling is enabled.
                                           ///
                                           ///  @valuesbul
                                           ///  - 0 -- FALSE
                                           ///  - 1 -- TRUE @tablebulletend

    UINT8                       dump;      ///< Dumps the debug data.
} AFCAlgoSettings;


/// @brief Function wrapper for the Statistics AFC algorithm.
typedef struct /** @cond */ AFCAlgorithm /** @endcond */
{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AFCProcess @endcond
    ///
    /// @brief Runs the AFC algorithm on the given inputs.
    ///
    /// @datatypes
    /// #AFCAlgoInputList \n
    /// #AFCAlgoOutputList
    ///
    /// @param[in] pAFCAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pInputs           Pointer to the statistics inputs interface.
    /// @param[in] pOutputs          Pointer to statistics data that the algorithm outputs.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult (*AFCProcess)(
        AFCAlgorithm*              pAFCAlgorithm,
        const AFCAlgoInputList*    pInputs,
        AFCAlgoOutputList*         pOutputs);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AFCSetParam @endcond
    ///
    /// @brief Sets configuration parameters to the AFC algorithm.
    ///
    /// @datatypes
    /// #AFCAlgoSetParamList
    ///
    /// @param[in] pAFCAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pSetParams        Pointer to the input parameter list.
    ///                              Each element in the list is of type #AFCAlgoSetParam.
    ///
    /// @return #CDKResultSuccess. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*AFCSetParam)(
        AFCAlgorithm*                pAFCAlgorithm,
        const AFCAlgoSetParamList*   pSetParams);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AFCGetParam @endcond
    ///
    /// @brief Retrieves the most up-to-date AFC algorithm information. Typically, the output is updated after calling
    ///        AFCProcess().
    ///
    /// @datatypes
    /// #AFCAlgoGetParam
    ///
    /// @param[in]  pAFCAlgorithm     Pointer to the algorithm instance.
    /// @param[out] pGetParam         Pointer to the metadata and associated data that is necessary to support the query.
    ///
    /// @return #CDKResultSuccess.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CDKResult(*AFCGetParam)(
        AFCAlgorithm*       pAFCAlgorithm,
        AFCAlgoGetParam*    pGetParam);

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// @cond AFCDestroy @endcond
    ///
    /// @brief Destroys a derived instance of the AFC interface.
    ///
    /// @datatypes
    /// #AFCAlgoDestroyParamList
    ///
    /// @param[in] pAFCAlgorithm     Pointer to the algorithm instance.
    /// @param[in] pDestroyParams    Pointer to the list of parameters.
    ///
    /// @return None. @newpage
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*AFCDestroy)(
        AFCAlgorithm*                    pAFCAlgorithm,
        const AFCAlgoDestroyParamList*   pDestroyParams);

} AFCAlgorithm;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @cond CreateAFC @endcond
///
/// @brief Creates an instance of the AFC algorithm.
///
/// @datatypes
/// #AFCAlgoCreateParamList \n
/// #AFCAlgorithm
///
/// @param[in] pCreateParams      Pointer to the parameters.
/// @param[in] ppAFCAlgorithm     Double pointer  to the created algorithm instance.
///
/// @return #CDKResultSuccess.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef CDKResult (*CREATEAFC)(
    const AFCAlgoCreateParamList*   pCreateParams,
    AFCAlgorithm**                  ppAFCAlgorithm);

#pragma pack(pop)

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // CAMXAFCINTERFACE_H
