/*
 * Copyright (c) 2024, Alliance for Open Media. All rights reserved.
 *
 * Encoder tools configuration - runtime control of coding tools
 */

#ifndef AOM_AV1_ENCODER_TOOLS_CONFIG_H_
#define AOM_AV1_ENCODER_TOOLS_CONFIG_H_

#include <stdint.h>
#include "av1/common/enums.h"

#ifdef __cplusplus
extern "C" {
#endif

// Partition tools config
typedef struct {
  uint8_t partition_none;
  uint8_t partition_horz;
  uint8_t partition_vert;
  uint8_t partition_split;  // quad
  uint8_t partition_horz_a;
  uint8_t partition_horz_b;
  uint8_t partition_vert_a;
  uint8_t partition_vert_b;
  uint8_t partition_horz_4;
  uint8_t partition_vert_4;
} PartitionToolsCfg;

// Intra prediction modes config
typedef struct {
  uint8_t dc_pred;
  uint8_t v_pred;
  uint8_t h_pred;
  uint8_t d45_pred;
  uint8_t d135_pred;
  uint8_t d113_pred;
  uint8_t d157_pred;
  uint8_t d203_pred;
  uint8_t d67_pred;
  uint8_t smooth_pred;
  uint8_t smooth_v_pred;
  uint8_t smooth_h_pred;
  uint8_t paeth_pred;
} IntraToolsCfg;

// Inter prediction (reference frames) config
typedef struct {
  uint8_t last_frame;
  uint8_t last2_frame;
  uint8_t last3_frame;
  uint8_t golden_frame;
  uint8_t bwdref_frame;
  uint8_t altref2_frame;
  uint8_t altref_frame;
  uint8_t compound;  // bi-prediction
} InterToolsCfg;

// Inter prediction mode types config (single + compound modes)
typedef struct {
  // Single-ref modes
  uint8_t nearestmv;
  uint8_t nearmv;
  uint8_t globalmv;
  uint8_t newmv;
  // Compound modes
  uint8_t nearest_nearestmv;
  uint8_t near_nearmv;
  uint8_t new_newmv;
  uint8_t nearest_newmv;
  uint8_t new_nearestmv;
  uint8_t near_newmv;
  uint8_t new_nearmv;
  uint8_t global_globalmv;
} InterModesCfg;

// Compound prediction types config
typedef struct {
  uint8_t average;   // COMPOUND_AVERAGE
  uint8_t distwtd;   // COMPOUND_DISTWTD
  uint8_t wedge;     // COMPOUND_WEDGE
  uint8_t diffwtd;   // COMPOUND_DIFFWTD
} CompoundTypesCfg;

// Transform sizes config (square only; rect controlled by --enable-rect-tx)
typedef struct {
  uint8_t tx_4x4;
  uint8_t tx_8x8;
  uint8_t tx_16x16;
  uint8_t tx_32x32;
  uint8_t tx_64x64;
} TxSizesCfg;

// Transform types config
typedef struct {
  uint8_t dct_dct;
  uint8_t adst_dct;
  uint8_t dct_adst;
  uint8_t adst_adst;
  uint8_t flipadst_dct;
  uint8_t dct_flipadst;
  uint8_t flipadst_flipadst;
  uint8_t adst_flipadst;
  uint8_t flipadst_adst;
  uint8_t idtx;
  uint8_t v_dct;
  uint8_t h_dct;
  uint8_t v_adst;
  uint8_t h_adst;
  uint8_t v_flipadst;
  uint8_t h_flipadst;
} TransformToolsCfg;

// Main tools configuration structure
typedef struct {
  int loaded;  // 1 if config was loaded from file
  PartitionToolsCfg partition;
  IntraToolsCfg intra;
  InterToolsCfg inter;
  InterModesCfg inter_modes;
  CompoundTypesCfg compound_types;
  TransformToolsCfg transform;
  TxSizesCfg tx_sizes;
} EncoderToolsCfg;

// Initialize with all tools enabled (default)
void aom_tools_cfg_init(EncoderToolsCfg *cfg);

// Load configuration from CSV file
// Returns 0 on success, -1 on error
int aom_tools_cfg_load(EncoderToolsCfg *cfg, const char *filename);

// Print current configuration to stderr
void aom_tools_cfg_print(const EncoderToolsCfg *cfg);

// Query functions for encoder
int aom_tools_cfg_partition_enabled(const EncoderToolsCfg *cfg, PARTITION_TYPE p);
int aom_tools_cfg_intra_mode_enabled(const EncoderToolsCfg *cfg, PREDICTION_MODE m);
int aom_tools_cfg_ref_frame_enabled(const EncoderToolsCfg *cfg, int ref_frame);
int aom_tools_cfg_tx_type_enabled(const EncoderToolsCfg *cfg, TX_TYPE t);
int aom_tools_cfg_compound_enabled(const EncoderToolsCfg *cfg);
int aom_tools_cfg_inter_mode_enabled(const EncoderToolsCfg *cfg, PREDICTION_MODE m);
int aom_tools_cfg_compound_type_enabled(const EncoderToolsCfg *cfg, int compound_type);
int aom_tools_cfg_tx_size_enabled(const EncoderToolsCfg *cfg, TX_SIZE s);

// Global config instance (set by encoder init)
extern EncoderToolsCfg g_encoder_tools_cfg;

#ifdef __cplusplus
}
#endif

#endif  // AOM_AV1_ENCODER_TOOLS_CONFIG_H_
