/*
 * Copyright (C) 2007,2008,2009  Red Hat, Inc.
 *
 *  This is part of HarfBuzz, an OpenType Layout engine 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.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_H
#define HB_OT_LAYOUT_COMMON_PRIVATE_H

#include "hb-ot-layout-open-private.h"


/*
 *
 * OpenType Layout Common Table Formats
 *
 */


/*
 * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
 */

template <typename Type>
struct Record {
  Tag		tag;		/* 4-byte Tag identifier */
  OffsetTo<Type>
		offset;		/* Offset from beginning of object holding
				 * the Record */
};

template <typename Type>
struct RecordListOf : ArrayOf<Record<Type> > {
  inline const Type& operator [] (unsigned int i) const {
    if (HB_UNLIKELY (i >= this->len)) return Null(Type);
    return this+this->array[i].offset;
  }
  inline const Tag& get_tag (unsigned int i) const {
    if (HB_UNLIKELY (i >= this->len)) return Null(Tag);
    return this->array[i].tag;
  }
};


struct Script;
typedef Record<Script> ScriptRecord;
ASSERT_SIZE (ScriptRecord, 6);
struct LangSys;
typedef Record<LangSys> LangSysRecord;
ASSERT_SIZE (LangSysRecord, 6);
struct Feature;
typedef Record<Feature> FeatureRecord;
ASSERT_SIZE (FeatureRecord, 6);


struct LangSys {

  inline const unsigned int get_feature_index (unsigned int i) const {
    return featureIndex[i];
  }
  inline unsigned int get_feature_count (void) const {
    return featureIndex.len;
  }

  inline const bool has_required_feature (void) const {
    return reqFeatureIndex != 0xffff;
  }
  /* Returns NO_INDEX if none */
  inline int get_required_feature_index (void) const {
    if (reqFeatureIndex == 0xffff)
      return NO_INDEX;
   return reqFeatureIndex;;
  }

  Offset	lookupOrder;	/* = Null (reserved for an offset to a
				 * reordering table) */
  USHORT	reqFeatureIndex;/* Index of a feature required for this
				 * language system--if no required features
				 * = 0xFFFF */
  ArrayOf<USHORT>
		featureIndex;	/* Array of indices into the FeatureList */
};
ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF");


struct Script {

  inline const LangSys& get_lang_sys (unsigned int i) const {
    if (i == NO_INDEX) return get_default_lang_sys ();
    return this+langSys[i].offset;
  }
  inline unsigned int get_lang_sys_count (void) const {
    return langSys.len;
  }
  inline const Tag& get_lang_sys_tag (unsigned int i) const {
    return langSys[i].tag;
  }

  // LONGTERMTODO bsearch
  DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys);	/* find_lang_sys_index (), get_lang_sys_by_tag (tag) */

  inline const bool has_default_lang_sys (void) const {
    return defaultLangSys != 0;
  }
  inline const LangSys& get_default_lang_sys (void) const {
    return this+defaultLangSys;
  }

  private:
  OffsetTo<LangSys>
		defaultLangSys;	/* Offset to DefaultLangSys table--from
				 * beginning of Script table--may be Null */
  ArrayOf<LangSysRecord>
		langSys;	/* Array of LangSysRecords--listed
				 * alphabetically by LangSysTag */
};
ASSERT_SIZE (Script, 4);

typedef RecordListOf<Script> ScriptList;
ASSERT_SIZE (ScriptList, 2);


struct Feature {

  inline const unsigned int get_lookup_index (unsigned int i) const {
    return lookupIndex[i];
  }
  inline unsigned int get_lookup_count (void) const {
    return lookupIndex.len;
  }

  /* TODO: implement get_feature_parameters() */
  /* TODO: implement FeatureSize and other special features? */
  Offset	featureParams;	/* Offset to Feature Parameters table (if one
				 * has been defined for the feature), relative
				 * to the beginning of the Feature Table; = Null
				 * if not required */
  ArrayOf<USHORT>
		lookupIndex;	/* Array of LookupList indices */
};
ASSERT_SIZE (Feature, 4);

typedef RecordListOf<Feature> FeatureList;
ASSERT_SIZE (FeatureList, 2);


struct LookupFlag : USHORT {
  static const unsigned int RightToLeft		= 0x0001u;
  static const unsigned int IgnoreBaseGlyphs	= 0x0002u;
  static const unsigned int IgnoreLigatures	= 0x0004u;
  static const unsigned int IgnoreMarks		= 0x0008u;
  static const unsigned int Reserved		= 0x00F0u;
  static const unsigned int MarkAttachmentType	= 0xFF00u;
};
ASSERT_SIZE (LookupFlag, 2);

struct LookupSubTable {
  private:
  USHORT	format;		/* Subtable format.  Different for GSUB and GPOS */
};
ASSERT_SIZE (LookupSubTable, 2);

struct Lookup {

  inline const LookupSubTable& get_subtable (unsigned int i) const {
    return this+subTable[i];
  }
  inline unsigned int get_subtable_count (void) const {
    return subTable.len;
  }

  inline bool is_right_to_left	(void) const { return lookupFlag & LookupFlag::RightToLeft; }
  inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; }
  inline bool ignore_ligatures	(void) const { return lookupFlag & LookupFlag::IgnoreLigatures; }
  inline bool ignore_marks	(void) const { return lookupFlag & LookupFlag::IgnoreMarks; }
  inline unsigned int get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }

  inline unsigned int get_type (void) const { return lookupType; }
  inline unsigned int get_flag (void) const { return lookupFlag; }

  USHORT	lookupType;	/* Different enumerations for GSUB and GPOS */
  USHORT	lookupFlag;	/* Lookup qualifiers */
  OffsetArrayOf<LookupSubTable>
		subTable;	/* Array of SubTables */
};
ASSERT_SIZE (Lookup, 6);

template <typename Type>
struct OffsetListOf : OffsetArrayOf<Type> {
  inline const Type& operator [] (unsigned int i) const {
    if (HB_UNLIKELY (i >= this->len)) return Null(Type);
    return this+this->array[i];
  }
};

typedef OffsetListOf<Lookup> LookupList;
ASSERT_SIZE (LookupList, 2);


/*
 * Coverage Table
 */

struct CoverageFormat1 {

  friend struct Coverage;

  private:
  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
    if (HB_UNLIKELY (glyph_id > 0xFFFF))
      return NOT_COVERED;
    GlyphID gid;
    gid = glyph_id;
    // TODO: bsearch
    unsigned int num_glyphs = glyphArray.len;
    for (unsigned int i = 0; i < num_glyphs; i++)
      if (gid == glyphArray[i])
        return i;
    return NOT_COVERED;
  }

  USHORT	coverageFormat;	/* Format identifier--format = 1 */
  ArrayOf<GlyphID>
		glyphArray;	/* Array of GlyphIDs--in numerical order */
};
ASSERT_SIZE (CoverageFormat1, 4);

struct CoverageRangeRecord {

  friend struct CoverageFormat2;

  private:
  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
    if (glyph_id >= start && glyph_id <= end)
      return (unsigned int) startCoverageIndex + (glyph_id - start);
    return NOT_COVERED;
  }

  private:
  GlyphID	start;			/* First GlyphID in the range */
  GlyphID	end;			/* Last GlyphID in the range */
  USHORT	startCoverageIndex;	/* Coverage Index of first GlyphID in
					 * range */
};
ASSERT_SIZE_DATA (CoverageRangeRecord, 6, "\000\001");

struct CoverageFormat2 {

  friend struct Coverage;

  private:
  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
    // TODO: bsearch
    unsigned int count = rangeRecord.len;
    for (unsigned int i = 0; i < count; i++) {
      unsigned int coverage = rangeRecord[i].get_coverage (glyph_id);
      if (coverage != NOT_COVERED)
        return coverage;
    }
    return NOT_COVERED;
  }

  USHORT	coverageFormat;	/* Format identifier--format = 2 */
  ArrayOf<CoverageRangeRecord>
		rangeRecord;	/* Array of glyph ranges--ordered by
				 * Start GlyphID. rangeCount entries
				 * long */
};
ASSERT_SIZE (CoverageFormat2, 4);

struct Coverage {
  unsigned int get_coverage (hb_codepoint_t glyph_id) const {
    switch (u.format) {
    case 1: return u.format1->get_coverage(glyph_id);
    case 2: return u.format2->get_coverage(glyph_id);
    default:return NOT_COVERED;
    }
  }

  inline unsigned int operator() (hb_codepoint_t glyph_id) const {
    return get_coverage (glyph_id);
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  CoverageFormat1	format1[];
  CoverageFormat2	format2[];
  } u;
};
ASSERT_SIZE (Coverage, 2);


/*
 * Class Definition Table
 */

struct ClassDefFormat1 {

  friend struct ClassDef;

  private:
  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
    if ((unsigned int) (glyph_id - startGlyph) < classValue.len)
      return classValue[glyph_id - startGlyph];
    return 0;
  }

  USHORT	classFormat;		/* Format identifier--format = 1 */
  GlyphID	startGlyph;		/* First GlyphID of the classValueArray */
  ArrayOf<USHORT>
		classValue;		/* Array of Class Values--one per GlyphID */
};
ASSERT_SIZE (ClassDefFormat1, 6);

struct ClassRangeRecord {

  friend struct ClassDefFormat2;

  private:
  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
    if (glyph_id >= start && glyph_id <= end)
      return classValue;
    return 0;
  }

  private:
  GlyphID	start;		/* First GlyphID in the range */
  GlyphID	end;		/* Last GlyphID in the range */
  USHORT	classValue;	/* Applied to all glyphs in the range */
};
ASSERT_SIZE_DATA (ClassRangeRecord, 6, "\000\001");

struct ClassDefFormat2 {

  friend struct ClassDef;

  private:
  inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
    // TODO: bsearch
    unsigned int count = rangeRecord.len;
    for (unsigned int i = 0; i < count; i++) {
      int classValue = rangeRecord[i].get_class (glyph_id);
      if (classValue > 0)
        return classValue;
    }
    return 0;
  }

  USHORT	classFormat;	/* Format identifier--format = 2 */
  ArrayOf<ClassRangeRecord>
		rangeRecord;	/* Array of glyph ranges--ordered by
				 * Start GlyphID */
};
ASSERT_SIZE (ClassDefFormat2, 4);

struct ClassDef {
  hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
    switch (u.format) {
    case 1: return u.format1->get_class(glyph_id);
    case 2: return u.format2->get_class(glyph_id);
    default:return 0;
    }
  }

  inline unsigned int operator() (hb_codepoint_t glyph_id) const {
    return get_class (glyph_id);
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  ClassDefFormat1	format1[];
  ClassDefFormat2	format2[];
  } u;
};
ASSERT_SIZE (ClassDef, 2);


/*
 * Device Tables
 */

struct Device {
  int get_delta (int ppem_size) const {
    if (ppem_size >= startSize && ppem_size <= endSize &&
        deltaFormat >= 1 && deltaFormat <= 3) {
      int s = ppem_size - startSize;
      int f = deltaFormat;

      uint16_t byte = deltaValue[s >> (4 - f)];
      uint16_t bits = byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f));
      uint16_t mask = 0xFFFF >> (16 - (1 << f));

      int delta = bits & mask;

      if (delta >= ((mask + 1) >> 1))
        delta -= mask + 1;

      return delta;
    }
    return 0;
  }

  private:
  USHORT	startSize;	/* Smallest size to correct--in ppem */
  USHORT	endSize;	/* Largest size to correct--in ppem */
  USHORT	deltaFormat;	/* Format of DeltaValue array data: 1, 2, or 3 */
  USHORT	deltaValue[];	/* Array of compressed data */
};
ASSERT_SIZE (Device, 6);


#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_H */
