/*******************************************************************************
*  Copyright 1991-1996 by ORCA Software, Inc.                                  *
*                                                                              *
*  All rights reserved.  May not be reproduced or distributed, in printed or   *
*  electronic form, without permission of ORCA Software, Inc.  May not be      *
*  distributed as object code, separately or linked with other object modules, *
*  without permission.                                                         *
*******************************************************************************/

#define XI_INTERNAL
#define XI_R3_COMPAT
#include "xi.h"
#include "xiutils.h"

#define UNDEFINED 1000
#define BUFFERLEN 200

static char *
bool_to_str( BOOLEAN b )
{
  if ( b )
    return "TRUE";
  else
    return "FALSE";
}

void
xi_event_debug( char *tag, XI_EVENT * xiev, char *s, int len )
{
  char *tmp;
  char str[BUFFERLEN],
  str2[BUFFERLEN];
  int i,
  k;
  int j;
  XI_OBJ *xi_obj;

  static struct
  {
    int type;
    char *desc;
  } event_text[] =
  {
    {
      XIE_CHAR_FIELD, "XIE_CHAR_FIELD  "
    },
    {
      XIE_DBL_FIELD, "XIE_DBL_FIELD   "
    },
    {
      XIE_CHG_FIELD, "XIE_CHG_FIELD   "
    },
    {
      XIE_OFF_FIELD, "XIE_OFF_FIELD   "
    },
    {
      XIE_ON_FIELD, "XIE_ON_FIELD    "
    },
    {
      XIE_OFF_GROUP, "XIE_OFF_GROUP   "
    },
    {
      XIE_ON_GROUP, "XIE_ON_GROUP    "
    },
    {
      XIE_OFF_FORM, "XIE_OFF_FORM    "
    },
    {
      XIE_ON_FORM, "XIE_ON_FORM     "
    },
    {
      XIE_VIR_PAN, "XIE_VIR_PAN     "
    },
    {
      XIE_XVT_EVENT, "XIE_XVT_EVENT   "
    },
    {
      XIE_XVT_POST_EVENT, "XIE_XVT_POST_EVENT"
    },
    {
      XIE_XIN_EVENT, "XIE_XIN_EVENT   "
    },
    {
      XIE_XIN_POST_EVENT, "XIE_XIN_POST_EVENT"
    },
    {
      XIE_INIT, "XIE_INIT        "
    },
    {
      XIE_BUTTON, "XIE_BUTTON      "
    },
    {
      XIE_CHAR_CELL, "XIE_CHAR_CELL   "
    },
    {
      XIE_CLEANUP, "XIE_CLEANUP     "
    },
    {
      XIE_CLOSE, "XIE_CLOSE       "
    },
    {
      XIE_COMMAND, "XIE_COMMAND     "
    },
    {
      XIE_DBL_CELL, "XIE_DBL_CELL    "
    },
    {
      XIE_GET_FIRST, "XIE_GET_FIRST   "
    },
    {
      XIE_GET_LAST, "XIE_GET_LAST    "
    },
    {
      XIE_GET_NEXT, "XIE_GET_NEXT    "
    },
    {
      XIE_GET_PERCENT, "XIE_GET_PERCENT "
    },
    {
      XIE_GET_PREV, "XIE_GET_PREV    "
    },
    {
      XIE_CELL_REQUEST, "XIE_CELL_REQUEST"
    },
    {
      XIE_CHG_CELL, "XIE_CHG_CELL    "
    },
    {
      XIE_OFF_CELL, "XIE_OFF_CELL    "
    },
    {
      XIE_ON_CELL, "XIE_ON_CELL     "
    },
    {
      XIE_OFF_ROW, "XIE_OFF_ROW     "
    },
    {
      XIE_ON_ROW, "XIE_ON_ROW      "
    },
    {
      XIE_OFF_COLUMN, "XIE_OFF_COLUMN  "
    },
    {
      XIE_ON_COLUMN, "XIE_ON_COLUMN   "
    },
    {
      XIE_OFF_LIST, "XIE_OFF_LIST    "
    },
    {
      XIE_ON_LIST, "XIE_ON_LIST     "
    },
    {
      XIE_REC_ALLOCATE, "XIE_REC_ALLOCATE"
    },
    {
      XIE_REC_FREE, "XIE_REC_FREE    "
    },
    {
      XIE_ROW_SIZE, "XIE_ROW_SIZE    "
    },
    {
      XIE_SELECT, "XIE_SELECT      "
    },
    {
      XIE_UPDATE, "XIE_UPDATE      "
    },
    {
      XIE_COL_DELETE, "XIE_COL_DELETE  "
    },
    {
      XIE_COL_MOVE, "XIE_COL_MOVE    "
    },
    {
      XIE_COL_SIZE, "XIE_COL_SIZE    "
    },
    {
      XIE_POST_NAVIGATION, "XIE_POST_NAVIGATION"
    },
    {
      UNDEFINED, "Unknown XI Event"
    }
  };

  static struct
  {
    XinEventType type;
    char *desc;
  } xin_event_text[] =
  {
    {
      XinEventCreate, "XinEventCreate"
    },
    {
      XinEventDestroy, "XinEventDestroy"
    },
    {
      XinEventFocus, "XinEventFocus"
    },
    {
      XinEventResize, "XinEventResize"
    },
    {
      XinEventPaint, "XinEventPaint"
    },
    {
      XinEventCloseButton, "XinEventCloseButton"
    },
    {
      XinEventMouseDown, "XinEventMouseDown"
    },
    {
      XinEventMouseUp, "XinEventMouseUp"
    },
    {
      XinEventMouseMove, "XinEventMouseMove"
    },
    {
      XinEventMouseDouble, "XinEventMouseDouble"
    },
    {
      XinEventCharacter, "XinEventCharacter"
    },
    {
      XinEventVScroll, "XinEventVScroll"
    },
    {
      XinEventHScroll, "XinEventHScroll"
    },
    {
      XinEventMenuCommand, "XinEventMenuCommand"
    },
    {
      XinEventControl, "XinEventControl"
    },
    {
      XinEventTimer, "XinEventTimer"
    },
    {
      XinEventQuit, "XinEventQuit"
    },
    {
      XinEventHelp, "XinEventHelp"
    },
    {
      XinEventFont, "XinEventFont"
    },
    {
      (XinEventType)UNDEFINED, "Unknown Xin Event"
    }
  };

  static struct
  {
    int type;
    char *desc;
  } object_type[] =
  {
    {
      XIT_BTN, "XIT_BTN"
    },
    {
      XIT_CONTAINER, "XIT_CONTAINER"
    },
    {
      XIT_FORM, "XIT_FORM"
    },
    {
      XIT_FIELD, "XIT_FIELD"
    },
    {
      XIT_GROUP, "XIT_GROUP"
    },
    {
      XIT_LINE, "XIT_LINE"
    },
    {
      XIT_RECT, "XIT_RECT"
    },
    {
      XIT_TEXT, "XIT_TEXT"
    },
    {
      XIT_CELL, "XIT_CELL"
    },
    {
      XIT_COLUMN, "XIT_COLUMN"
    },
    {
      XIT_ITF, "XIT_ITF"
    },
    {
      XIT_LIST, "XIT_LIST"
    },
    {
      XIT_ROW, "XIT_ROW"
    },
    {
      UNDEFINED, "Unknown XI Object Type"
    }
  };

  for ( i = 0; event_text[i].type != xiev->type &&
        event_text[i].type != UNDEFINED; ++i )
    ;
  sprintf( str, "%s: %s", tag, event_text[i].desc );
  *str2 = '\0';
  switch ( xiev->type )
  {
#ifdef XI_USE_XVT
    case XIE_XVT_EVENT:
    case XIE_XVT_POST_EVENT:
      sprintf( str2, "  %s", XinXvtEventTextGet( &xiev->v.xvte ) );
      break;
#endif
    case XIE_XIN_EVENT:
    case XIE_XIN_POST_EVENT:
      for ( j = 0; xin_event_text[j].type != xiev->v.xin_event.type &&
            xin_event_text[j].type != UNDEFINED; ++j )
        ;
      sprintf( str2, "  %s", xin_event_text[j].desc );
      break;
    case XIE_COMMAND:
      sprintf( str2, "  tag %d, shift %s, control %s", xiev->v.cmd.tag,
      bool_to_str( xiev->v.cmd.shift ), bool_to_str( xiev->v.cmd.control ) );
      break;
    case XIE_INIT:
    case XIE_BUTTON:
    case XIE_CLOSE:
    case XIE_DBL_CELL:
    case XIE_DBL_FIELD:
    case XIE_CHG_FIELD:
    case XIE_OFF_FIELD:
    case XIE_ON_FIELD:
    case XIE_OFF_GROUP:
    case XIE_ON_GROUP:
    case XIE_OFF_FORM:
    case XIE_ON_FORM:
    case XIE_CHG_CELL:
    case XIE_OFF_CELL:
    case XIE_ON_CELL:
    case XIE_OFF_ROW:
    case XIE_ON_ROW:
    case XIE_OFF_COLUMN:
    case XIE_ON_COLUMN:
    case XIE_OFF_LIST:
    case XIE_ON_LIST:
    case XIE_CLEANUP:
      xi_obj = xiev->v.xi_obj;
      for ( k = 0; object_type[k].type != xi_obj->type &&
            object_type[k].type != UNDEFINED; ++k )
        ;
      switch ( xi_obj->type )
      {
        case XIT_CELL:
          sprintf( str2, "  cid %3d, type %s r %d c %d v %d",
                  xi_obj->cid, object_type[k].desc, xi_obj->v.cell.row,
                  xi_obj->v.cell.column, !xi_obj->v.cell.is_vert_scrolled );
          break;
        case XIT_ROW:
          sprintf( str2, "  cid %3d, type %s  r %d", xi_obj->cid,
                  object_type[k].desc, xi_obj->v.row );
          break;
        default:
          sprintf( str2, "  cid %3d, type %s", xi_obj->cid,
                  object_type[k].desc );
          break;
      }
      break;
    case XIE_CHAR_CELL:
    case XIE_CHAR_FIELD:
      {
        char char_str[20];
        int ch;

        ch = xiev->v.chr.ch;
        switch ( ch )
        {
          case XI_KEY_CLEAR:
            strcpy( char_str, "XI_KEY_CLEAR" );
            break;
          case XI_KEY_DEL:
            strcpy( char_str, "XI_KEY_DEL" );
            break;
          case '\b':
            strcpy( char_str, "BS" );
            break;
          default:
            char_str[0] = ( char ) ch;
            char_str[1] = '\0';
            break;
        }
        xi_obj = xiev->v.chr.xi_obj;
        for ( k = 0; object_type[k].type != xi_obj->type &&
              object_type[k].type != UNDEFINED; ++k )
          ;
        switch ( xi_obj->type )
        {
          case XIT_CELL:
            sprintf( str2,
                    "  cid %3d type %s r %d c %d ch %s shft %d ctrl %d alt %d",
                    xi_obj->cid, object_type[k].desc, xi_obj->v.cell.row,
                    xi_obj->v.cell.column, char_str, xiev->v.chr.shift,
                    xiev->v.chr.control, xiev->v.chr.alt );
            break;
          case XIT_FIELD:
            sprintf( str2, "  cid %3d type %s ch %s shft %d ctrl %d alt %d", xi_obj->cid,
                    object_type[k].desc, char_str, xiev->v.chr.shift,
                    xiev->v.chr.control, xiev->v.chr.alt );
            break;
          default:
            break;
        }
        break;
      }
    case XIE_GET_FIRST:
    case XIE_GET_LAST:
      sprintf( str2, "  data_rec %08.8lx", ( long ) xiev->v.rec_request.data_rec );
      break;
    case XIE_GET_NEXT:
    case XIE_GET_PREV:
      sprintf( str2, "  spec_rec %08.8lx, data_rec %08.8lx",
              ( long ) xiev->v.rec_request.spec_rec, ( long ) xiev->v.rec_request.data_rec );
      break;
    case XIE_CELL_REQUEST:
      sprintf( str2, "  c %2d, rec %08.8lx, len %3d",
      ( int ) xiev->v.cell_request.col_nbr, ( long ) xiev->v.cell_request.rec,
              xiev->v.cell_request.len );
      break;
    case XIE_GET_PERCENT:
      sprintf( str2, "  list->cid %d, record %08.8lx",
              xiev->v.get_percent.list->cid,
              ( long ) xiev->v.get_percent.record );
      break;
    case XIE_SELECT:
      sprintf( str2, "  row %d, selected %d, dbl_click %d shift %d control %d column %d",
              xiev->v.select.xi_obj->v.row, xiev->v.select.selected,
              xiev->v.select.dbl_click, xiev->v.select.shift, xiev->v.select.control, xiev->v.select.column );
      break;
    case XIE_REC_ALLOCATE:
      sprintf( str2, "  list cid %d", xiev->v.rec_allocate.list->cid );
      break;
    case XIE_REC_FREE:
      sprintf( str2, "  list cid %d, record %08.8lx", xiev->v.rec_free.list->cid, xiev->v.rec_free.record );
      break;
    case XIE_ROW_SIZE:
      sprintf( str2, "  row %d, new_size %d", xiev->v.row_size.xi_obj->v.row, xiev->v.row_size.new_row_height );
      break;
    case XIE_VIR_PAN:
      sprintf( str2, "  delta_x %d, delta_y %d, before_pan %d",
              xiev->v.vir_pan.delta_x, xiev->v.vir_pan.delta_y,
              xiev->v.vir_pan.before_pan );
      break;
    case XIE_COL_DELETE:
      sprintf( str2, "  list cid %d, col_nbr %d",
              xiev->v.column.list->cid, xiev->v.column.col_nbr );
      break;
    case XIE_COL_MOVE:
      sprintf( str2, "  list cid %d, col_nbr %d, new_col_nbr %d",
              xiev->v.column.list->cid, xiev->v.column.col_nbr,
              xiev->v.column.new_col_nbr );
      break;
    case XIE_COL_SIZE:
      sprintf( str2, "  list cid %d, col_nbr %d, new_col_width %d, new_col_pixel_width %d",
              xiev->v.column.list->cid, xiev->v.column.col_nbr,
          xiev->v.column.new_col_width, xiev->v.column.new_col_pixel_width );
      break;
    default:
      break;
  }
  tmp = ( char * ) xi_tree_malloc( strlen( str ) + strlen( str2 ) + 2, NULL );
  strcpy( tmp, str );
  strcat( tmp, str2 );
  if ( ( int ) strlen( tmp ) >= len )
    tmp[len] = '\0';
  strcpy( s, tmp );
  xi_tree_free( tmp );
}