/*
 * Copyright © 2018  Ebrahim Byagowi
 *
 *  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.
 */

#ifndef HB_OT_STAT_TABLE_HH
#define HB_OT_STAT_TABLE_HH

#include "hb-open-type.hh"
#include "hb-ot-layout-common.hh"

/*
 * STAT -- Style Attributes
 * https://docs.microsoft.com/en-us/typography/opentype/spec/stat
 */
#define HB_OT_TAG_STAT HB_TAG('S','T','A','T')


namespace OT {

enum
{
  OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001,	/* If set, this axis value table
						 * provides axis value information
						 * that is applicable to other fonts
						 * within the same font family. This
						 * is used if the other fonts were
						 * released earlier and did not include
						 * information about values for some axis.
						 * If newer versions of the other
						 * fonts include the information
						 * themselves and are present,
						 * then this record is ignored. */
  ELIDABLE_AXIS_VALUE_NAME = 0x0002		/* If set, it indicates that the axis
						 * value represents the “normal” value
						 * for the axis and may be omitted when
						 * composing name strings. */
  // Reserved = 0xFFFC				/* Reserved for future use — set to zero. */
};

struct StatAxisRecord
{
  int cmp (hb_tag_t key) const { return tag.cmp (key); }

  hb_ot_name_id_t get_name_id () const { return nameID; }

  hb_tag_t get_axis_tag () const { return tag; }

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

  protected:
  Tag		tag;		/* A tag identifying the axis of design variation. */
  NameID	nameID;		/* The name ID for entries in the 'name' table that
				 * provide a display string for this axis. */
  HBUINT16	ordering;	/* A value that applications can use to determine
				 * primary sorting of face names, or for ordering
				 * of descriptors when composing family or face names. */
  public:
  DEFINE_SIZE_STATIC (8);
};

struct AxisValueFormat1
{
  unsigned int get_axis_index () const { return axisIndex; }
  float get_value ()             const { return value.to_float (); }

  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }

  hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
  {
    unsigned axis_idx = get_axis_index ();
    return axis_records[axis_idx].get_axis_tag ();
  }

  bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
  {
    hb_tag_t axis_tag = get_axis_tag (axis_records);
    float axis_value = get_value ();

    if (!user_axes_location->has (axis_tag) ||
        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
      return true;

    return false;
  }

  bool subset (hb_subset_context_t *c,
               const hb_array_t<const StatAxisRecord> axis_records) const
  {
    TRACE_SUBSET (this);
    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;

    if (keep_axis_value (axis_records, user_axes_location))
      return_trace (c->serializer->embed (this));

    return_trace (false);
  }

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

  protected:
  HBUINT16	format;		/* Format identifier — set to 1. */
  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
				 * identifying the axis of design variation
				 * to which the axis value record applies.
				 * Must be less than designAxisCount. */
  HBUINT16	flags;		/* Flags — see below for details. */
  NameID	valueNameID;	/* The name ID for entries in the 'name' table
				 * that provide a display string for this
				 * attribute value. */
  F16DOT16	value;		/* A numeric value for this attribute value. */
  public:
  DEFINE_SIZE_STATIC (12);
};

struct AxisValueFormat2
{
  unsigned int get_axis_index () const { return axisIndex; }
  float get_value ()             const { return nominalValue.to_float (); }

  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }

  hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
  {
    unsigned axis_idx = get_axis_index ();
    return axis_records[axis_idx].get_axis_tag ();
  }

  bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
  {
    hb_tag_t axis_tag = get_axis_tag (axis_records);
    float axis_value = get_value ();

    if (!user_axes_location->has (axis_tag) ||
        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
      return true;

    return false;
  }

  bool subset (hb_subset_context_t *c,
               const hb_array_t<const StatAxisRecord> axis_records) const
  {
    TRACE_SUBSET (this);
    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;

    if (keep_axis_value (axis_records, user_axes_location))
      return_trace (c->serializer->embed (this));

    return_trace (false);
  }

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

  protected:
  HBUINT16	format;		/* Format identifier — set to 2. */
  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
				 * identifying the axis of design variation
				 * to which the axis value record applies.
				 * Must be less than designAxisCount. */
  HBUINT16	flags;		/* Flags — see below for details. */
  NameID	valueNameID;	/* The name ID for entries in the 'name' table
				 * that provide a display string for this
				 * attribute value. */
  F16DOT16	nominalValue;	/* A numeric value for this attribute value. */
  F16DOT16	rangeMinValue;	/* The minimum value for a range associated
				 * with the specified name ID. */
  F16DOT16	rangeMaxValue;	/* The maximum value for a range associated
				 * with the specified name ID. */
  public:
  DEFINE_SIZE_STATIC (20);
};

struct AxisValueFormat3
{
  unsigned int get_axis_index () const { return axisIndex; }
  float get_value ()             const { return value.to_float (); }

  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }

  hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const
  {
    unsigned axis_idx = get_axis_index ();
    return axis_records[axis_idx].get_axis_tag ();
  }

  bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
  {
    hb_tag_t axis_tag = get_axis_tag (axis_records);
    float axis_value = get_value ();

    if (!user_axes_location->has (axis_tag) ||
        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
      return true;

    return false;
  }

  bool subset (hb_subset_context_t *c,
               const hb_array_t<const StatAxisRecord> axis_records) const
  {
    TRACE_SUBSET (this);
    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;

    if (keep_axis_value (axis_records, user_axes_location))
      return_trace (c->serializer->embed (this));

    return_trace (false);
  }

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

  protected:
  HBUINT16	format;		/* Format identifier — set to 3. */
  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
				 * identifying the axis of design variation
				 * to which the axis value record applies.
				 * Must be less than designAxisCount. */
  HBUINT16	flags;		/* Flags — see below for details. */
  NameID	valueNameID;	/* The name ID for entries in the 'name' table
				 * that provide a display string for this
				 * attribute value. */
  F16DOT16	value;		/* A numeric value for this attribute value. */
  F16DOT16	linkedValue;	/* The numeric value for a style-linked mapping
				 * from this value. */
  public:
  DEFINE_SIZE_STATIC (16);
};

struct AxisValueRecord
{
  unsigned int get_axis_index () const { return axisIndex; }
  float get_value ()             const { return value.to_float (); }

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

  protected:
  HBUINT16	axisIndex;	/* Zero-base index into the axis record array
				 * identifying the axis to which this value
				 * applies. Must be less than designAxisCount. */
  F16DOT16	value;		/* A numeric value for this attribute value. */
  public:
  DEFINE_SIZE_STATIC (6);
};

struct AxisValueFormat4
{
  const AxisValueRecord &get_axis_record (unsigned int axis_index) const
  { return axisValues.as_array (axisCount)[axis_index]; }

  bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
  {
    hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount);

    for (const auto& rec : axis_value_records)
    {
      unsigned axis_idx = rec.get_axis_index ();
      float axis_value = rec.get_value ();
      hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag ();

      if (user_axes_location->has (axis_tag) &&
          fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f)
        return false;
    }

    return true;
  }

  bool subset (hb_subset_context_t *c,
               const hb_array_t<const StatAxisRecord> axis_records) const
  {
    TRACE_SUBSET (this);
    const hb_hashmap_t<hb_tag_t, float> *user_axes_location = &c->plan->user_axes_location;
    if (!keep_axis_value (axis_records, user_axes_location))
      return_trace (false);

    unsigned total_size = min_size + axisCount * AxisValueRecord::static_size;
    auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size);
    if (unlikely (!out)) return_trace (false);
    hb_memcpy (out, this, total_size);
    return_trace (true);
  }

  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) &&
                          axisValues.sanitize (c, axisCount)));
  }

  protected:
  HBUINT16	format;		/* Format identifier — set to 4. */
  HBUINT16	axisCount;	/* The total number of axes contributing to
				 * this axis-values combination. */
  HBUINT16	flags;		/* Flags — see below for details. */
  NameID	valueNameID;	/* The name ID for entries in the 'name' table
				 * that provide a display string for this
				 * attribute value. */
  UnsizedArrayOf<AxisValueRecord>
		axisValues;	/* Array of AxisValue records that provide the
				 * combination of axis values, one for each
				 * contributing axis. */
  public:
  DEFINE_SIZE_ARRAY (8, axisValues);
};

struct AxisValue
{
  bool get_value (unsigned int axis_index) const
  {
    switch (u.format)
    {
    case 1: return u.format1.get_value ();
    case 2: return u.format2.get_value ();
    case 3: return u.format3.get_value ();
    case 4: return u.format4.get_axis_record (axis_index).get_value ();
    default:return 0;
    }
  }

  unsigned int get_axis_index () const
  {
    switch (u.format)
    {
    case 1: return u.format1.get_axis_index ();
    case 2: return u.format2.get_axis_index ();
    case 3: return u.format3.get_axis_index ();
    /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */
    default:return -1;
    }
  }

  hb_ot_name_id_t get_value_name_id () const
  {
    switch (u.format)
    {
    case 1: return u.format1.get_value_name_id ();
    case 2: return u.format2.get_value_name_id ();
    case 3: return u.format3.get_value_name_id ();
    case 4: return u.format4.get_value_name_id ();
    default:return HB_OT_NAME_ID_INVALID;
    }
  }

  template <typename context_t, typename ...Ts>
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
  {
    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
    TRACE_DISPATCH (this, u.format);
    switch (u.format) {
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
    case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
    default:return_trace (c->default_return_value ());
    }
  }

  bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
                        hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
  {
    switch (u.format)
    {
    case 1: return u.format1.keep_axis_value (axis_records, user_axes_location);
    case 2: return u.format2.keep_axis_value (axis_records, user_axes_location);
    case 3: return u.format3.keep_axis_value (axis_records, user_axes_location);
    case 4: return u.format4.keep_axis_value (axis_records, user_axes_location);
    default:return false;
    }
  }

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

    switch (u.format)
    {
    case 1: return_trace (u.format1.sanitize (c));
    case 2: return_trace (u.format2.sanitize (c));
    case 3: return_trace (u.format3.sanitize (c));
    case 4: return_trace (u.format4.sanitize (c));
    default:return_trace (true);
    }
  }

  protected:
  union
  {
  HBUINT16		format;
  AxisValueFormat1	format1;
  AxisValueFormat2	format2;
  AxisValueFormat3	format3;
  AxisValueFormat4	format4;
  } u;
  public:
  DEFINE_SIZE_UNION (2, format);
};

struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>>
{
  bool subset (hb_subset_context_t *c,
               unsigned axisValueCount,
               unsigned& count,
               const hb_array_t<const StatAxisRecord> axis_records) const
  {
    TRACE_SUBSET (this);
    auto *out = c->serializer->start_embed (this);
    if (unlikely (!out)) return_trace (false);

    auto axisValueOffsets = as_array (axisValueCount);
    count = 0;
    for (const auto& offset : axisValueOffsets)
    {
      if (!offset) continue;
      auto o_snap = c->serializer->snapshot ();
      auto *o = c->serializer->embed (offset);
      if (!o) return_trace (false);
      if (!o->serialize_subset (c, offset, this, axis_records))
      {
        c->serializer->revert (o_snap);
        continue;
      }
      count++;
    }

    return_trace (count);
  }
};

struct STAT
{
  static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;

  bool has_data () const { return version.to_int (); }

  bool get_value (hb_tag_t tag, float *value) const
  {
    unsigned int axis_index;
    if (!get_design_axes ().lfind (tag, &axis_index)) return false;

    hb_array_t<const Offset16To<AxisValue>> axis_values = get_axis_value_offsets ();
    for (unsigned int i = 0; i < axis_values.length; i++)
    {
      const AxisValue& axis_value = this+axis_values[i];
      if (axis_value.get_axis_index () == axis_index)
      {
	if (value)
	  *value = axis_value.get_value (axis_index);
	return true;
      }
    }
    return false;
  }

  unsigned get_design_axis_count () const { return designAxisCount; }

  hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
  {
    if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
    const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
    return axis_record.get_name_id ();
  }

  unsigned get_axis_value_count () const { return axisValueCount; }

  hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
  {
    if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
    const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
    return axis_value.get_value_name_id ();
  }

  void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
                         hb_set_t *nameids_to_retain /* OUT */) const
  {
    if (!has_data ()) return;

    + get_design_axes ()
    | hb_map (&StatAxisRecord::get_name_id)
    | hb_sink (nameids_to_retain)
    ;

    auto designAxes = get_design_axes ();

    + get_axis_value_offsets ()
    | hb_map (hb_add (&(this + offsetToAxisValueOffsets)))
    | hb_filter ([&] (const AxisValue& _)
                 { return _.keep_axis_value (designAxes, user_axes_location); })
    | hb_map (&AxisValue::get_value_name_id)
    | hb_sink (nameids_to_retain)
    ;
  }

  bool subset (hb_subset_context_t *c) const
  {
    TRACE_SUBSET (this);
    STAT *out = c->serializer->embed (this);
    if (unlikely (!out)) return_trace (false);

    auto designAxes = get_design_axes ();
    for (unsigned i = 0; i < (unsigned)designAxisCount; i++)
      if (unlikely (!c->serializer->embed (designAxes[i])))
          return_trace (false);

    if (designAxisCount)
      c->serializer->check_assign (out->designAxesOffset, this->get_size (),
                                   HB_SERIALIZE_ERROR_INT_OVERFLOW);

    unsigned count = 0;
    out->offsetToAxisValueOffsets.serialize_subset (c, offsetToAxisValueOffsets, this,
                                                    axisValueCount, count, designAxes);
    return_trace (c->serializer->check_assign (out->axisValueCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) &&
			  version.major == 1 &&
			  version.minor > 0 &&
			  designAxesOffset.sanitize (c, this, designAxisCount) &&
			  offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
  }

  protected:
  hb_array_t<const StatAxisRecord> const get_design_axes () const
  { return (this+designAxesOffset).as_array (designAxisCount); }

  hb_array_t<const Offset16To<AxisValue>> const get_axis_value_offsets () const
  { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }


  protected:
  FixedVersion<>version;	/* Version of the stat table
				 * initially set to 0x00010002u */
  HBUINT16	designAxisSize;	/* The size in bytes of each axis record. */
  HBUINT16	designAxisCount;/* The number of design axis records. In a
				 * font with an 'fvar' table, this value must be
				 * greater than or equal to the axisCount value
				 * in the 'fvar' table. In all fonts, must
				 * be greater than zero if axisValueCount
				 * is greater than zero. */
  NNOffset32To<UnsizedArrayOf<StatAxisRecord>>
		designAxesOffset;
				/* Offset in bytes from the beginning of
				 * the STAT table to the start of the design
				 * axes array. If designAxisCount is zero,
				 * set to zero; if designAxisCount is greater
				 * than zero, must be greater than zero. */
  HBUINT16	axisValueCount;	/* The number of axis value tables. */
  NNOffset32To<AxisValueOffsetArray>
		offsetToAxisValueOffsets;
				/* Offset in bytes from the beginning of
				 * the STAT table to the start of the design
				 * axes value offsets array. If axisValueCount
				 * is zero, set to zero; if axisValueCount is
				 * greater than zero, must be greater than zero. */
  NameID	elidedFallbackNameID;
				/* Name ID used as fallback when projection of
				 * names into a particular font model produces
				 * a subfamily name containing only elidable
				 * elements. */
  public:
  DEFINE_SIZE_STATIC (20);
};


} /* namespace OT */


#endif /* HB_OT_STAT_TABLE_HH */
