#pragma once

#include "../encoder/encoder_all.h"
#include <string>

enum ENCODER_TYPE {
  TE_TRACK_DENSITY_ENCODER,
  TRACK_DENSITY_ENCODER_V2,
  TRACK_SEGMENT_ENCODER,
  TRACK_INTERLEAVED_ENCODER,
  TRACK_INTERLEAVED_W_HEADER_ENCODER,
  TRACK_ENCODER,
  TRACK_UNQUANTIZED_ENCODER,
  TRACK_DENSITY_ENCODER,
  TRACK_BAR_FILL_DENSITY_ENCODER,
  NO_ENCODER
};

ENCODER* getEncoder(ENCODER_TYPE et) {
  switch (et) {
    case TE_TRACK_DENSITY_ENCODER: return new TeTrackDensityEncoder();
    case TRACK_DENSITY_ENCODER_V2: return new TrackDensityEncoderV2();
    case TRACK_SEGMENT_ENCODER: return new TrackSegmentEncoder();
    case TRACK_INTERLEAVED_ENCODER: return new TrackInterleavedEncoder();
    case TRACK_INTERLEAVED_W_HEADER_ENCODER: return new TrackInterleavedWHeaderEncoder();
    case TRACK_ENCODER: return new TrackEncoder();
    case TRACK_UNQUANTIZED_ENCODER: return new TrackUnquantizedEncoder();
    case TRACK_DENSITY_ENCODER: return new TrackDensityEncoder();
    case TRACK_BAR_FILL_DENSITY_ENCODER: return new TrackBarFillDensityEncoder();
    case NO_ENCODER: return NULL;
  }
}

ENCODER_TYPE getEncoderType(string &s) {
  if (s == "TE_TRACK_DENSITY_ENCODER") return TE_TRACK_DENSITY_ENCODER;
  if (s == "TRACK_DENSITY_ENCODER_V2") return TRACK_DENSITY_ENCODER_V2;
  if (s == "TRACK_SEGMENT_ENCODER") return TRACK_SEGMENT_ENCODER;
  if (s == "TRACK_INTERLEAVED_ENCODER") return TRACK_INTERLEAVED_ENCODER;
  if (s == "TRACK_INTERLEAVED_W_HEADER_ENCODER") return TRACK_INTERLEAVED_W_HEADER_ENCODER;
  if (s == "TRACK_ENCODER") return TRACK_ENCODER;
  if (s == "TRACK_UNQUANTIZED_ENCODER") return TRACK_UNQUANTIZED_ENCODER;
  if (s == "TRACK_DENSITY_ENCODER") return TRACK_DENSITY_ENCODER;
  if (s == "TRACK_BAR_FILL_DENSITY_ENCODER") return TRACK_BAR_FILL_DENSITY_ENCODER;
  return NO_ENCODER;
}

int getEncoderSize(ENCODER_TYPE et) {
  ENCODER *encoder = getEncoder(et);
  if (!encoder) {
    return 0;
  }
  int size = encoder->rep->max_token();
  delete encoder;
  return size;
}