/*
 * Copyright © 2018 Adobe 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.
 *
 * Adobe Author(s): Michiharu Ariza
 */
#ifndef HB_CFF_INTERP_DICT_COMMON_HH
#define HB_CFF_INTERP_DICT_COMMON_HH

#include "hb-cff-interp-common.hh"
#include <math.h>

namespace CFF {

using namespace OT;

/* an opstr and the parsed out dict value(s) */
struct DictVal : OpStr
{
  inline void init (void)
  {
    single_val.set_int (0);
  }

  inline void fini (void)
  {
  }

  Number              single_val;
};

typedef DictVal NumDictVal;

template <typename VAL> struct DictValues : ParsedValues<VAL> {};

template <typename OPSTR=OpStr>
struct TopDictValues : DictValues<OPSTR>
{
  inline void init (void)
  {
    DictValues<OPSTR>::init ();
    charStringsOffset = 0;
    FDArrayOffset = 0;
  }

  inline void fini (void)
  {
    DictValues<OPSTR>::fini ();
  }

  inline unsigned int calculate_serialized_op_size (const OPSTR& opstr) const
  {
    switch (opstr.op)
    {
      case OpCode_CharStrings:
      case OpCode_FDArray:
        return OpCode_Size (OpCode_longintdict) + 4 + OpCode_Size (opstr.op);

      default:
        return opstr.str.len;
    }
  }

  unsigned int  charStringsOffset;
  unsigned int  FDArrayOffset;
};

struct DictOpSet : OpSet<Number>
{
  static inline void process_op (OpCode op, InterpEnv<Number>& env)
  {
    switch (op) {
      case OpCode_longintdict:  /* 5-byte integer */
        env.argStack.push_longint_from_substr (env.substr);
        break;

      case OpCode_BCD:  /* real number */
        env.argStack.push_real (parse_bcd (env.substr));
        break;

      default:
        OpSet<Number>::process_op (op, env);
        break;
    }
  }

  static inline float parse_bcd (SubByteStr& substr)
  {
    float v = 0.0f;

    bool    neg = false;
    double  int_part = 0;
    long    frac_part = 0;
    unsigned int  frac_count = 0;
    bool    exp_neg = false;
    unsigned int  exp_part = 0;
    enum Part { INT_PART=0, FRAC_PART, EXP_PART } part = INT_PART;
    enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };

    double  value = 0.0;
    unsigned char byte = 0;
    for (unsigned int i = 0;; i++)
    {
      char d;
      if ((i & 1) == 0)
      {
        if (!substr.avail ())
        {
          substr.set_error ();
          return 0.0f;
        }
        byte = substr[0];
        substr.inc ();
        d = byte >> 4;
      }
      else
        d = byte & 0x0F;

      switch (d)
      {
        case RESERVED:
          substr.set_error ();
          return v;

        case END:
          value = (double)(neg? -int_part: int_part);
          if (frac_count > 0)
            value += (frac_part / pow (10.0, (double)frac_count));
          if (exp_part != 0)
          {
            if (exp_neg)
              value /= pow (10.0, (double)exp_part);
            else
              value *= pow (10.0, (double)exp_part);
          }
          return (float)value;

        case NEG:
          if (i != 0)
          {
            substr.set_error ();
            return 0.0f;
          }
          neg = true;
          break;

        case DECIMAL:
          if (part != INT_PART)
          {
            substr.set_error ();
            return v;
          }
          part = FRAC_PART;
          break;

        case EXP_NEG:
          exp_neg = true;
          HB_FALLTHROUGH;
          
        case EXP_POS:
          if (part == EXP_PART)
          {
            substr.set_error ();
            return v;
          }
          part = EXP_PART;
          break;

        default:
          switch (part) {
            default:
            case INT_PART:
              int_part = (int_part * 10) + d;
              break;
            
            case FRAC_PART:
              frac_part = (frac_part * 10) + d;
              frac_count++;
              break;

            case EXP_PART:
              exp_part = (exp_part * 10) + d;
              break;
          }
      }
    }

    return v;
  }

  static inline bool is_hint_op (OpCode op)
  {
    switch (op)
    {
      case OpCode_BlueValues:
      case OpCode_OtherBlues:
      case OpCode_FamilyBlues:
      case OpCode_FamilyOtherBlues:
      case OpCode_StemSnapH:
      case OpCode_StemSnapV:
      case OpCode_StdHW:
      case OpCode_StdVW:
      case OpCode_BlueScale:
      case OpCode_BlueShift:
      case OpCode_BlueFuzz:
      case OpCode_ForceBold:
      case OpCode_LanguageGroup:
      case OpCode_ExpansionFactor:
        return true;
      default:
        return false;
    }
  }
};

template <typename VAL=OpStr>
struct TopDictOpSet : DictOpSet
{
  static inline void process_op (OpCode op, InterpEnv<Number>& env, TopDictValues<VAL> & dictval)
  {
    switch (op) {
      case OpCode_CharStrings:
        dictval.charStringsOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;
      case OpCode_FDArray:
        dictval.FDArrayOffset = env.argStack.pop_uint ();
        env.clear_args ();
        break;
      case OpCode_FontMatrix:
        env.clear_args ();
        break;
      default:
        DictOpSet::process_op (op, env);
        break;
    }
  }
};

template <typename OPSET, typename PARAM, typename ENV=NumInterpEnv>
struct DictInterpreter : Interpreter<ENV>
{
  inline bool interpret (PARAM& param)
  {
    param.init ();
    while (SUPER::env.substr.avail ())
    {
      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
      if (unlikely (SUPER::env.in_error ()))
        return false;
    }
    
    return true;
  }

  private:
  typedef Interpreter<ENV> SUPER;
};

} /* namespace CFF */

#endif /* HB_CFF_INTERP_DICT_COMMON_HH */
