/* Simple debugging component. Temporary */

#include "ttdebug.h"
#include "tttables.h"
#include "ttobjs.h"


#ifdef DEBUG_LEVEL_TRACE
  char  tt_trace_levels[trace_max];
#endif

#if defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE )

#include <stdio.h>
#include <stdarg.h>
#include <string.h>


  static String  tempStr[128];

  static const String*  OpStr[256] =
  {
    "SVTCA y",       /* Set vectors to coordinate axis y    */
    "SVTCA x",       /* Set vectors to coordinate axis x    */
    "SPvTCA y",      /* Set Proj. vec. to coord. axis y     */
    "SPvTCA x",      /* Set Proj. vec. to coord. axis x     */
    "SFvTCA y",      /* Set Free. vec. to coord. axis y     */
    "SFvTCA x",      /* Set Free. vec. to coord. axis x     */
    "SPvTL //",      /* Set Proj. vec. parallel to segment  */
    "SPvTL +",       /* Set Proj. vec. normal to segment    */
    "SFvTL //",      /* Set Free. vec. parallel to segment  */
    "SFvTL +",       /* Set Free. vec. normal to segment    */
    "SPvFS",         /* Set Proj. vec. from stack           */
    "SFvFS",         /* Set Free. vec. from stack           */
    "GPV",           /* Get projection vector               */
    "GFV",           /* Get freedom vector                  */
    "SFvTPv",        /* Set free. vec. to proj. vec.        */
    "ISECT",         /* compute intersection                */

    "SRP0",          /* Set reference point 0               */
    "SRP1",          /* Set reference point 1               */
    "SRP2",          /* Set reference point 2               */
    "SZP0",          /* Set Zone Pointer 0                  */
    "SZP1",          /* Set Zone Pointer 1                  */
    "SZP2",          /* Set Zone Pointer 2                  */
    "SZPS",          /* Set all zone pointers               */
    "SLOOP",         /* Set loop counter                    */
    "RTG",           /* Round to Grid                       */
    "RTHG",          /* Round to Half-Grid                  */
    "SMD",           /* Set Minimum Distance                */
    "ELSE",          /* Else                                */
    "JMPR",          /* Jump Relative                       */
    "SCvTCi",        /* Set CVT                             */
    "SSwCi",         /*                                     */
    "SSW",           /*                                     */

    "DUP",
    "POP",
    "CLEAR",
    "SWAP",
    "DEPTH",
    "CINDEX",
    "MINDEX",
    "AlignPTS",
    "INS_$28",
    "UTP",
    "LOOPCALL",
    "CALL",
    "FDEF",
    "ENDF",
    "MDAP[-]",
    "MDAP[r]",

    "IUP[y]",
    "IUP[x]",
    "SHP[0]",
    "SHP[1]",
    "SHC[0]",
    "SHC[1]",
    "SHZ[0]",
    "SHZ[1]",
    "SHPIX",
    "IP",
    "MSIRP[0]",
    "MSIRP[1]",
    "AlignRP",
    "RTDG",
    "MIAP[-]",
    "MIAP[r]",

    "NPushB",
    "NPushW",
    "WS",
    "RS",
    "WCvtP",
    "RCvt",
    "GC[0]",
    "GC[1]",
    "SCFS",
    "MD[0]",
    "MD[1]",
    "MPPEM",
    "MPS",
    "FlipON",
    "FlipOFF",
    "DEBUG",

    "LT",
    "LTEQ",
    "GT",
    "GTEQ",
    "EQ",
    "NEQ",
    "ODD",
    "EVEN",
    "IF",
    "EIF",
    "AND",
    "OR",
    "NOT",
    "DeltaP1",
    "SDB",
    "SDS",

    "ADD",
    "SUB",
    "DIV",
    "MUL",
    "ABS",
    "NEG",
    "FLOOR",
    "CEILING",
    "ROUND[G]",
    "ROUND[B]",
    "ROUND[W]",
    "ROUND[?]",
    "NROUND[G]",
    "NROUND[B]",
    "NROUND[W]",
    "NROUND[?]",

    "WCvtF",
    "DeltaP2",
    "DeltaP3",
    "DeltaC1",
    "DeltaC2",
    "DeltaC3",
    "SROUND",
    "S45Round",
    "JROT",
    "JROF",
    "ROFF",
    "INS_$7B",
    "RUTG",
    "RDTG",
    "SANGW",
    "AA",

    "FlipPT",
    "FlipRgON",
    "FlipRgOFF",
    "INS_$83",
    "INS_$84",
    "ScanCTRL",
    "SDPVTL[0]",
    "SDPVTL[1]",
    "GetINFO",
    "IDEF",
    "ROLL",
    "MAX",
    "MIN",
    "ScanTYPE",
    "IntCTRL",
    "INS_$8F",

    "INS_$90",
    "INS_$91",
    "INS_$92",
    "INS_$93",
    "INS_$94",
    "INS_$95",
    "INS_$96",
    "INS_$97",
    "INS_$98",
    "INS_$99",
    "INS_$9A",
    "INS_$9B",
    "INS_$9C",
    "INS_$9D",
    "INS_$9E",
    "INS_$9F",

    "INS_$A0",
    "INS_$A1",
    "INS_$A2",
    "INS_$A3",
    "INS_$A4",
    "INS_$A5",
    "INS_$A6",
    "INS_$A7",
    "INS_$A8",
    "INS_$A9",
    "INS_$AA",
    "INS_$AB",
    "INS_$AC",
    "INS_$AD",
    "INS_$AE",
    "INS_$AF",

    "PushB[0]",
    "PushB[1]",
    "PushB[2]",
    "PushB[3]",
    "PushB[4]",
    "PushB[5]",
    "PushB[6]",
    "PushB[7]",
    "PushW[0]",
    "PushW[1]",
    "PushW[2]",
    "PushW[3]",
    "PushW[4]",
    "PushW[5]",
    "PushW[6]",
    "PushW[7]",

    "MDRP[G]",
    "MDRP[B]",
    "MDRP[W]",
    "MDRP[?]",
    "MDRP[rG]",
    "MDRP[rB]",
    "MDRP[rW]",
    "MDRP[r?]",
    "MDRP[mG]",
    "MDRP[mB]",
    "MDRP[mW]",
    "MDRP[m?]",
    "MDRP[mrG]",
    "MDRP[mrB]",
    "MDRP[mrW]",
    "MDRP[mr?]",
    "MDRP[pG]",
    "MDRP[pB]",

    "MDRP[pW]",
    "MDRP[p?]",
    "MDRP[prG]",
    "MDRP[prB]",
    "MDRP[prW]",
    "MDRP[pr?]",
    "MDRP[pmG]",
    "MDRP[pmB]",
    "MDRP[pmW]",
    "MDRP[pm?]",
    "MDRP[pmrG]",
    "MDRP[pmrB]",
    "MDRP[pmrW]",
    "MDRP[pmr?]",

    "MIRP[G]",
    "MIRP[B]",
    "MIRP[W]",
    "MIRP[?]",
    "MIRP[rG]",
    "MIRP[rB]",
    "MIRP[rW]",
    "MIRP[r?]",
    "MIRP[mG]",
    "MIRP[mB]",
    "MIRP[mW]",
    "MIRP[m?]",
    "MIRP[mrG]",
    "MIRP[mrB]",
    "MIRP[mrW]",
    "MIRP[mr?]",
    "MIRP[pG]",
    "MIRP[pB]",

    "MIRP[pW]",
    "MIRP[p?]",
    "MIRP[prG]",
    "MIRP[prB]",
    "MIRP[prW]",
    "MIRP[pr?]",
    "MIRP[pmG]",
    "MIRP[pmB]",
    "MIRP[pmW]",
    "MIRP[pm?]",
    "MIRP[pmrG]",
    "MIRP[pmrB]",
    "MIRP[pmrW]",
    "MIRP[pmr?]"
  };


  const String* Cur_U_Line( void* _exec )
  {
    String  s[32];

    Int  op, i, n;

    PExecution_Context  exec;


    exec = _exec;

    op = exec->code[exec->IP];

    sprintf( tempStr, "%s", OpStr[op] );

    if ( op == 0x40 )
    {
      n = exec->code[exec->IP + 1];
      sprintf( s, "(%d)", n );
      strncat( tempStr, s, 8 );

      if ( n > 20 ) n = 20; /* limit output */

      for ( i = 0; i < n; i++ )
      {
        sprintf( s, " $%02hx", exec->code[exec->IP + i + 2] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( op == 0x41 )
    {
      n = exec->code[exec->IP + 1];
      sprintf( s, "(%d)", n );
      strncat( tempStr, s, 8 );

      if ( n > 20 ) n = 20; /* limit output */

      for ( i = 0; i < n; i++ )
      {
        sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 2],
                                    exec->code[exec->IP + i*2 + 3] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( (op & 0xF8) == 0xB0 )
    {
      n = op - 0xB0;

      for ( i = 0; i <= n; i++ )
      {
        sprintf( s, " $%02hx", exec->code[exec->IP + i + 1] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( (op & 0xF8) == 0xB8 )
    {
      n = op-0xB8;

      for ( i = 0; i <= n; i++ )
      {
        sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 1],
                                    exec->code[exec->IP + i*2 + 2] );
        strncat( tempStr, s, 8 );
      }
    }

    return (String*)tempStr;
  }


  /* the Print() function is defined in ttconfig.h;  */
  /* it defaults to vprintf on systems which have it */

  void  TT_Message( const String*  fmt, ... )
  {
    va_list  ap;

    va_start( ap, fmt );
    Print( fmt, ap );
    va_end( ap );
  }


  void  TT_Panic( const String*  fmt, ... )
  {
    va_list  ap;

    va_start( ap, fmt );
    Print( fmt, ap );
    va_end( ap );

    exit( EXIT_FAILURE );
  }

#endif /* defined( DEBUG_LEVEL_ERROR ) || defined( DEBUG_LEVEL_TRACE ) */

#if defined( DEBUG_LEVEL_TRACE )

  /* use this function to set the values of tt_trace_levels */

  void  set_tt_trace_levels( int  index, char  value )
  {
    tt_trace_levels[index] = value;
  }

#endif

/* END */
