// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FPDFAPI_FONT_CFX_CTTGSUBTABLE_H_
#define CORE_FPDFAPI_FONT_CFX_CTTGSUBTABLE_H_

#include <stdint.h>

#include <set>
#include <vector>

#include "core/fxcrt/data_vector.h"
#include "core/fxge/freetype/fx_freetype.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/base/span.h"

class CFX_CTTGSUBTable {
 public:
  explicit CFX_CTTGSUBTable(pdfium::span<const uint8_t> gsub);
  ~CFX_CTTGSUBTable();

  uint32_t GetVerticalGlyph(uint32_t glyphnum) const;

 private:
  using FeatureIndices = DataVector<uint16_t>;
  using ScriptRecord = std::vector<FeatureIndices>;

  struct FeatureRecord {
    FeatureRecord();
    ~FeatureRecord();

    uint32_t feature_tag = 0;
    DataVector<uint16_t> lookup_list_indices;
  };

  struct RangeRecord {
    RangeRecord();

    uint16_t start = 0;
    uint16_t end = 0;
    uint16_t start_coverage_index = 0;
  };

  // GlyphArray for format 1.
  // RangeRecords for format 2.
  using CoverageFormat = absl::
      variant<absl::monostate, DataVector<uint16_t>, std::vector<RangeRecord>>;

  struct SubTable {
    SubTable();
    SubTable(const SubTable& that) = delete;
    SubTable& operator=(const SubTable& that) = delete;
    SubTable(SubTable&& that) noexcept;
    SubTable& operator=(SubTable&& that) noexcept;
    ~SubTable();

    CoverageFormat coverage;
    // DeltaGlyphID for format 1.
    // Substitutes for format 2.
    absl::variant<absl::monostate, int16_t, DataVector<uint16_t>> table_data;
  };

  struct Lookup {
    using SubTables = std::vector<SubTable>;

    Lookup();
    Lookup(const Lookup& that) = delete;
    Lookup& operator=(const Lookup& that) = delete;
    Lookup(Lookup&& that) noexcept;
    Lookup& operator=(Lookup&& that) noexcept;
    ~Lookup();

    uint16_t lookup_type = 0;
    SubTables sub_tables;
  };

  bool LoadGSUBTable(pdfium::span<const uint8_t> gsub);
  void Parse(pdfium::span<const uint8_t> scriptlist,
             pdfium::span<const uint8_t> featurelist,
             pdfium::span<const uint8_t> lookuplist);
  void ParseScriptList(pdfium::span<const uint8_t> raw);
  ScriptRecord ParseScript(const uint8_t* raw);
  FeatureIndices ParseLangSys(const uint8_t* raw);
  void ParseFeatureList(pdfium::span<const uint8_t> raw);
  DataVector<uint16_t> ParseFeatureLookupListIndices(const uint8_t* raw);
  void ParseLookupList(pdfium::span<const uint8_t> raw);
  Lookup ParseLookup(const uint8_t* raw);
  CoverageFormat ParseCoverage(const uint8_t* raw);
  SubTable ParseSingleSubst(const uint8_t* raw);

  absl::optional<uint32_t> GetVerticalGlyphSub(const FeatureRecord& feature,
                                               uint32_t glyphnum) const;
  absl::optional<uint32_t> GetVerticalGlyphSub2(const Lookup& lookup,
                                                uint32_t glyphnum) const;
  int GetCoverageIndex(const CoverageFormat& coverage, uint32_t g) const;

  uint8_t GetUInt8(const uint8_t*& p) const;
  int16_t GetInt16(const uint8_t*& p) const;
  uint16_t GetUInt16(const uint8_t*& p) const;
  int32_t GetInt32(const uint8_t*& p) const;
  uint32_t GetUInt32(const uint8_t*& p) const;

  std::set<uint32_t> feature_set_;
  std::vector<ScriptRecord> script_list_;
  std::vector<FeatureRecord> feature_list_;
  std::vector<Lookup> lookup_list_;
};

#endif  // CORE_FPDFAPI_FONT_CFX_CTTGSUBTABLE_H_
