/*
 * Copyright © 2018  Ebrahim Byagowi
 * Copyright © 2018  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod
 */

#ifndef HB_AAT_LAYOUT_KERX_TABLE_HH
#define HB_AAT_LAYOUT_KERX_TABLE_HH

#include "hb-open-type-private.hh"
#include "hb-aat-layout-common-private.hh"

#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x')


namespace AAT {

using namespace OT;


struct KerxFormat0Records
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  protected:
  GlyphID	left;
  GlyphID	right;
  FWORD		value;
  public:
  DEFINE_SIZE_STATIC (6);
};

struct KerxSubTableFormat0
{
  // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf
  // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  // {
  //   hb_glyph_pair_t pair = {left, right};
  //   int i = pairs.bsearch (pair);
  //   if (i == -1)
  //     return 0;
  //   return pairs[i].get_kerning ();
  // }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
      c->check_array (records, records[0].static_size, nPairs));
  }

  protected:
  // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
  // needed here to use HBUINT32 instead
  HBUINT32 nPairs;	/* The number of kerning pairs in this subtable */
  HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs,
                         * multiplied by the size in bytes of an entry in the subtable. */
  HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less
                           * than or equal to the value of nPairs. */
  HBUINT32 rangeShift;	/* The value of nPairs minus the largest power of two less than or equal to nPairs. */
  KerxFormat0Records records[VAR]; /* VAR=nPairs */
  public:
  DEFINE_SIZE_ARRAY (16, records);
};

struct KerxSubTableFormat1
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
      stateHeader.sanitize (c));
  }

  protected:
  StateTable<HBUINT16>		stateHeader;
  LOffsetTo<ArrayOf<HBUINT16> >	valueTable;
  public:
  DEFINE_SIZE_STATIC (20);
};

// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>?
struct KerxClassTable
{
  inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
  }

  protected:
  HBUINT16		firstGlyph;	/* First glyph in class range. */
  ArrayOf<HBUINT16>	classes;	/* Glyph classes. */
  public:
  DEFINE_SIZE_ARRAY (4, classes);
};

struct KerxSubTableFormat2
{
  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
  {
    unsigned int l = (this+leftClassTable).get_class (left);
    unsigned int r = (this+leftClassTable).get_class (left);
    unsigned int offset = l * rowWidth + r * sizeof (FWORD);
    const FWORD *arr = &(this+array);
    if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
      return 0;
    const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
    if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
      return 0;
    return *v;
  }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
      rowWidth.sanitize (c) &&
		  leftClassTable.sanitize (c, this) &&
		  rightClassTable.sanitize (c, this) &&
		  array.sanitize (c, this));
  }

  protected:
  HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
  LOffsetTo<KerxClassTable>
		leftClassTable;	/* Offset from beginning of this subtable to
				 * left-hand class table. */
  LOffsetTo<KerxClassTable>
		rightClassTable;/* Offset from beginning of this subtable to
				 * right-hand class table. */
  LOffsetTo<FWORD>
		array;		/* Offset from beginning of this subtable to
				 * the start of the kerning array. */
  public:
  DEFINE_SIZE_STATIC (16);
};

struct KerxSubTableFormat4
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
      rowWidth.sanitize (c) &&
		  leftClassTable.sanitize (c, this) &&
		  rightClassTable.sanitize (c, this) &&
		  array.sanitize (c, this));
  }

  protected:
  HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
  LOffsetTo<KerxClassTable>
		leftClassTable;	/* Offset from beginning of this subtable to
				 * left-hand class table. */
  LOffsetTo<KerxClassTable>
		rightClassTable;/* Offset from beginning of this subtable to
				 * right-hand class table. */
  LOffsetTo<FWORD>
		array;		/* Offset from beginning of this subtable to
				 * the start of the kerning array. */
  public:
  DEFINE_SIZE_STATIC (16);
};

struct KerxSubTableFormat6
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
      rowIndexTable.sanitize (c, this) &&
      columnIndexTable.sanitize (c, this) &&
      kerningArray.sanitize (c, this) &&
      kerningVector.sanitize (c, this));
  }

  protected:
  HBUINT32	flags;
  HBUINT16	rowCount;
  HBUINT16	columnCount;
  LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
  LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
  LOffsetTo<Lookup<HBUINT16> >	kerningArray;
  LOffsetTo<Lookup<HBUINT16> >	kerningVector;
  public:
  DEFINE_SIZE_STATIC (24);
};

enum coverage_flags_t
{
  COVERAGE_VERTICAL_FLAG	= 0x80u,
  COVERAGE_CROSSSTREAM_FLAG	= 0x40u,
  COVERAGE_VARIATION_FLAG	= 0x20u,
  COVERAGE_PROCESS_DIRECTION	= 0x10u,
};

struct KerxTable
{
  inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
  {
    TRACE_APPLY (this);
    /* TODO */
    return_trace (false);
  }

  inline unsigned int get_size (void) const { return length; }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (!c->check_struct (this))
      return_trace (false);

    switch (format) {
    case 0: return u.format0.sanitize (c);
    case 1: return u.format1.sanitize (c);
    case 2: return u.format2.sanitize (c);
    case 4: return u.format4.sanitize (c);
    case 6: return u.format6.sanitize (c);
    default:return_trace (false);
    }
  }

protected:
  HBUINT32	length;
  HBUINT8	coverage;
  HBUINT16	unused;
  HBUINT8	format;
  HBUINT32	tupleIndex;
  union {
  KerxSubTableFormat0	format0;
  KerxSubTableFormat1	format1;
  KerxSubTableFormat2	format2;
  KerxSubTableFormat4	format4;
  KerxSubTableFormat6	format6;
  } u;
public:
  DEFINE_SIZE_MIN (12);
};

struct SubtableGlyphCoverageArray
{
  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  protected:
  HBUINT32	length;
  HBUINT32	coverage;
  HBUINT32	tupleCount;
  public:
  DEFINE_SIZE_STATIC (12);
};

struct kerx
{
  static const hb_tag_t tableTag = HB_AAT_TAG_KERX;

  inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
  {
    TRACE_APPLY (this);
    const KerxTable &table = StructAfter<KerxTable> (*this);
    return_trace (table.apply (c, ankr));
  }

  inline bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (!(c->check_struct (this)))
     return_trace (false);

    /* TODO: Something like `morx`s ChainSubtable should be done here instead */
    const KerxTable *table = &StructAfter<KerxTable> (*this);
    if (!(table->sanitize (c)))
      return_trace (false);

    for (unsigned int i = 0; i < nTables - 1; ++i)
    {
      table = &StructAfter<KerxTable> (*table);
      if (!(table->sanitize (c)))
        return_trace (false);
    }

    // If version is less than 3, we are done here; otherwise better to check footer also
    if (version < 3)
      return_trace (true);

    // TODO: Investigate why this just work on some fonts no matter of version
    // const SubtableGlyphCoverageArray &footer =
    //   StructAfter<SubtableGlyphCoverageArray> (*table);
    // return_trace (footer.sanitize (c));

    return_trace (true);
  }

  protected:
  HBUINT16		version;
  HBUINT16		padding;
  HBUINT32		nTables;
/*KerxTable tables[VAR];*/
/*SubtableGlyphCoverageArray coverage_array;*/
  public:
  DEFINE_SIZE_STATIC (8);
};

} /* namespace AAT */


#endif /* HB_AAT_LAYOUT_KERX_TABLE_HH */
