/*
 * 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"

/*
 * kerx -- Extended Kerning
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kerx.html
 */
#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) &&
		  recordsZ.sanitize (c, 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. */
  UnsizedArrayOf<KerxFormat0Records>
		recordsZ;	/* VAR=nPairs */
  public:
  DEFINE_SIZE_ARRAY (16, recordsZ);
};

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 */
