// Copyright 2014 PDFium Authors. All rights reserved.
// 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 <memory>
#include <set>
#include <vector>

#include "core/fxge/fx_font.h"
#include "core/fxge/fx_freetype.h"

class CFX_CTTGSUBTable {
 public:
  CFX_CTTGSUBTable();
  explicit CFX_CTTGSUBTable(FT_Bytes gsub);
  virtual ~CFX_CTTGSUBTable();

  bool IsOk() const;
  bool LoadGSUBTable(FT_Bytes gsub);
  bool GetVerticalGlyph(uint32_t glyphnum, uint32_t* vglyphnum);

 private:
  struct tt_gsub_header {
    uint32_t Version;
    uint16_t ScriptList;
    uint16_t FeatureList;
    uint16_t LookupList;
  };

  struct TLangSys {
    TLangSys();
    ~TLangSys();

    uint16_t LookupOrder;
    uint16_t ReqFeatureIndex;
    std::vector<uint16_t> FeatureIndices;

   private:
    TLangSys(const TLangSys&) = delete;
    TLangSys& operator=(const TLangSys&) = delete;
  };

  struct TLangSysRecord {
    TLangSysRecord() : LangSysTag(0) {}

    uint32_t LangSysTag;
    TLangSys LangSys;

   private:
    TLangSysRecord(const TLangSysRecord&) = delete;
    TLangSysRecord& operator=(const TLangSysRecord&) = delete;
  };

  struct TScript {
    TScript();
    ~TScript();

    uint16_t DefaultLangSys;
    std::vector<TLangSysRecord> LangSysRecords;

   private:
    TScript(const TScript&) = delete;
    TScript& operator=(const TScript&) = delete;
  };

  struct TScriptRecord {
    TScriptRecord() : ScriptTag(0) {}

    uint32_t ScriptTag;
    TScript Script;

   private:
    TScriptRecord(const TScriptRecord&) = delete;
    TScriptRecord& operator=(const TScriptRecord&) = delete;
  };

  struct TScriptList {
    TScriptList();
    ~TScriptList();

    std::vector<TScriptRecord> ScriptRecords;

   private:
    TScriptList(const TScriptList&) = delete;
    TScriptList& operator=(const TScriptList&) = delete;
  };

  struct TFeature {
    TFeature();
    ~TFeature();

    uint16_t FeatureParams;
    std::vector<uint16_t> LookupListIndices;

   private:
    TFeature(const TFeature&) = delete;
    TFeature& operator=(const TFeature&) = delete;
  };

  struct TFeatureRecord {
    TFeatureRecord() : FeatureTag(0) {}

    uint32_t FeatureTag;
    TFeature Feature;

   private:
    TFeatureRecord(const TFeatureRecord&) = delete;
    TFeatureRecord& operator=(const TFeatureRecord&) = delete;
  };

  struct TFeatureList {
    TFeatureList();
    ~TFeatureList();

    std::vector<TFeatureRecord> FeatureRecords;

   private:
    TFeatureList(const TFeatureList&) = delete;
    TFeatureList& operator=(const TFeatureList&) = delete;
  };

  enum TLookupFlag {
    LOOKUPFLAG_RightToLeft = 0x0001,
    LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002,
    LOOKUPFLAG_IgnoreLigatures = 0x0004,
    LOOKUPFLAG_IgnoreMarks = 0x0008,
    LOOKUPFLAG_Reserved = 0x00F0,
    LOOKUPFLAG_MarkAttachmentType = 0xFF00,
  };

  struct TCoverageFormatBase {
    TCoverageFormatBase() : CoverageFormat(0) {}
    explicit TCoverageFormatBase(uint16_t format) : CoverageFormat(format) {}
    virtual ~TCoverageFormatBase() {}

    uint16_t CoverageFormat;

   private:
    TCoverageFormatBase(const TCoverageFormatBase&);
    TCoverageFormatBase& operator=(const TCoverageFormatBase&);
  };

  struct TCoverageFormat1 : public TCoverageFormatBase {
    TCoverageFormat1();
    ~TCoverageFormat1() override;

    std::vector<uint16_t> GlyphArray;

   private:
    TCoverageFormat1(const TCoverageFormat1&) = delete;
    TCoverageFormat1& operator=(const TCoverageFormat1&) = delete;
  };

  struct TRangeRecord {
    TRangeRecord();

    friend bool operator>(const TRangeRecord& r1, const TRangeRecord& r2) {
      return r1.Start > r2.Start;
    }

    uint16_t Start;
    uint16_t End;
    uint16_t StartCoverageIndex;

   private:
    TRangeRecord(const TRangeRecord&) = delete;
  };

  struct TCoverageFormat2 : public TCoverageFormatBase {
    TCoverageFormat2();
    ~TCoverageFormat2() override;

    std::vector<TRangeRecord> RangeRecords;

   private:
    TCoverageFormat2(const TCoverageFormat2&) = delete;
    TCoverageFormat2& operator=(const TCoverageFormat2&) = delete;
  };

  struct TDevice {
    TDevice() : StartSize(0), EndSize(0), DeltaFormat(0) {}

    uint16_t StartSize;
    uint16_t EndSize;
    uint16_t DeltaFormat;

   private:
    TDevice(const TDevice&) = delete;
    TDevice& operator=(const TDevice&) = delete;
  };

  struct TSubTableBase {
    TSubTableBase() : SubstFormat(0) {}
    explicit TSubTableBase(uint16_t format) : SubstFormat(format) {}
    virtual ~TSubTableBase() {}

    uint16_t SubstFormat;

   private:
    TSubTableBase(const TSubTableBase&) = delete;
    TSubTableBase& operator=(const TSubTableBase&) = delete;
  };

  struct TSingleSubstFormat1 : public TSubTableBase {
    TSingleSubstFormat1();
    ~TSingleSubstFormat1() override;

    std::unique_ptr<TCoverageFormatBase> Coverage;
    int16_t DeltaGlyphID;

   private:
    TSingleSubstFormat1(const TSingleSubstFormat1&) = delete;
    TSingleSubstFormat1& operator=(const TSingleSubstFormat1&) = delete;
  };

  struct TSingleSubstFormat2 : public TSubTableBase {
    TSingleSubstFormat2();
    ~TSingleSubstFormat2() override;

    std::unique_ptr<TCoverageFormatBase> Coverage;
    std::vector<uint16_t> Substitutes;

   private:
    TSingleSubstFormat2(const TSingleSubstFormat2&) = delete;
    TSingleSubstFormat2& operator=(const TSingleSubstFormat2&) = delete;
  };

  struct TLookup {
    TLookup();
    ~TLookup();

    uint16_t LookupType;
    uint16_t LookupFlag;
    std::vector<std::unique_ptr<TSubTableBase>> SubTables;

   private:
    TLookup(const TLookup&) = delete;
    TLookup& operator=(const TLookup&) = delete;
  };

  struct TLookupList {
    TLookupList();
    ~TLookupList();

    std::vector<TLookup> Lookups;

   private:
    TLookupList(const TLookupList&) = delete;
    TLookupList& operator=(const TLookupList&) = delete;
  };

  bool Parse(FT_Bytes scriptlist, FT_Bytes featurelist, FT_Bytes lookuplist);
  void ParseScriptList(FT_Bytes raw, TScriptList* rec);
  void ParseScript(FT_Bytes raw, TScript* rec);
  void ParseLangSys(FT_Bytes raw, TLangSys* rec);
  void ParseFeatureList(FT_Bytes raw, TFeatureList* rec);
  void ParseFeature(FT_Bytes raw, TFeature* rec);
  void ParseLookupList(FT_Bytes raw, TLookupList* rec);
  void ParseLookup(FT_Bytes raw, TLookup* rec);
  std::unique_ptr<TCoverageFormatBase> ParseCoverage(FT_Bytes raw);
  void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1* rec);
  void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2* rec);
  void ParseSingleSubst(FT_Bytes raw, std::unique_ptr<TSubTableBase>* rec);
  void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1* rec);
  void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2* rec);

  bool GetVerticalGlyphSub(uint32_t glyphnum,
                           uint32_t* vglyphnum,
                           TFeature* Feature);
  bool GetVerticalGlyphSub2(uint32_t glyphnum,
                            uint32_t* vglyphnum,
                            TLookup* Lookup);
  int GetCoverageIndex(TCoverageFormatBase* Coverage, uint32_t g) const;

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

  std::set<uint32_t> m_featureSet;
  bool m_bFeautureMapLoad;
  bool loaded;
  tt_gsub_header header;
  TScriptList ScriptList;
  TFeatureList FeatureList;
  TLookupList LookupList;
};

#endif  // CORE_FPDFAPI_FONT_CFX_CTTGSUBTABLE_H_
