

/*
 *  HP4L.CPX
 *
 *  Author: Arvin Schnell
 *  Version: 1.00  9.9.1994
 *
 *  Read HP4L.TXT for copying conditions.
 */


#include <gemfast.h>
#include <vdibind.h>
#include <aesbind.h>
#include <string.h>
#include <ctype.h>
#include <osbind.h>


/* used in hp4l.rsh */
#define BYTE char
#define WORD int
#define LONG long

#include "hp4l.rsh"
#include "hp4l.h"

#include "xcontrol.h"



#ifndef DEBUG_INFO
#define DEBUG(x)
#else
#define DEBUG(x) debug(x)
#endif



/* prototypes */

CPX_INFO* cpx_init( CPX_PARAMS *params );
int cpx_call( GRECT *rect );
OBJECT *get_treeaddr( int tree_index );
void popup_button( int button );
void redraw_object( OBJECT *tree, int object );
void set_button( int button );
void init_printer( void );
void upper( char *s );
void send( char text[] );
void debug( char text[] );




/* global variables */

typedef struct {
  int boot;
  int econo;        /* 0 = Off, 1 = On */
  int ret;          /* 0 = Off, 1 = Light, 2 = Medium, 3 = Dark */
  int density;      /* 0 = 1 (Light), .. , 4 = 5 (Dark) */
} STATUS;

extern STATUS status;     /* in start.s */
STATUS newstatus;

char boot_text[2][8] = { "Off", "On" };
char econo_text[2][8] = { "Off", "On" };
char ret_text[4][8] = { "Off", "Light", "Medium", "Dark" };
char density_text[5][8] = { "1", "2", "3", "4", "5" };


CPX_INFO cpx_info = { cpx_call, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
CPX_PARAMS *cpx_params;

OBJECT *form;





void redraw_object( OBJECT *tree, int object )
{
  GRECT *clip_ptr, clip, rect;
  
  objc_offset( tree, object, &rect.g_x, &rect.g_y );
  rect.g_w = tree[object].ob_width;
  rect.g_h = tree[object].ob_height;
  
  clip_ptr = (cpx_params->firstrect)( &rect );
  
  while( clip_ptr )
  {
    clip = *clip_ptr;
    
    objc_draw( tree, object, MAX_DEPTH, clip.g_x, clip.g_y, clip.g_w, clip.g_h );
    
    clip_ptr = (cpx_params->nextrect)();
  }
}



OBJECT *get_treeaddr( int tree_index )
{
  int i, j = 0;
  
  for( i = 0; i <= tree_index; i++ )
    while( rs_object[j++].ob_next != -1 );
  
  return( &rs_object[--j] );
}




CPX_INFO* cpx_init( CPX_PARAMS *p )
{
  cpx_params = p;
  
  DEBUG( "HP4L: cpx_init" );
  
  if( cpx_params->booting )
  {
    if( status.boot )
    {
      newstatus = status;
      init_printer();
    }
    
    return( (CPX_INFO *) 1L );
  }
  
  if( !cpx_params->rsc_init )
  {
    (*cpx_params->rsh_fix)( NUM_OBS, NUM_FRSTR, NUM_FRIMG, NUM_TREE,
        rs_object, rs_tedinfo, rs_strings, rs_iconblk, rs_bitblk,
        rs_frstr, rs_frimg, rs_trindex, rs_imdope );
    
    form = get_treeaddr( FORM );
    
    /* readback from printer would be better of course, but I think 
       it's not possible with the Atari ST. Therefore the values 
       displayed in the cpx may not be the actual settings of the 
       printer! */
    
    newstatus = status;
  }
  
  return( &cpx_info );
}




int cpx_call( GRECT *rect )
{
  int msg[8];
  int button, quit;
  
  DEBUG( "HP4L: cpx_call" );
  
  form[ROOT].ob_x = rect->g_x;
  form[ROOT].ob_y = rect->g_y;
  
  set_button( BOOT );
  set_button( ECONO );
  set_button( RET );
  set_button( DENSITY );
  
  objc_draw( form, ROOT, MAX_DEPTH, rect->g_x, rect->g_y, rect->g_w, rect->g_h );
  
  for( quit = 0; !quit; )
  {
    button = (*cpx_params->form_do)( form, ROOT, msg );
    
    if( button >= 0 )
      button &= 0x7fff;
    
    switch( button )
    {
      case OK:
        init_printer();
      case CANCEL:
        quit = 1;
        break;
      
      case SAVE:
        if( (*cpx_params->alert_do)( 0 ) == CPX_OKBUTTON )
        {
          (*cpx_params->cpx_save)( &newstatus, sizeof( STATUS ) );
          
          /* cpx_save saves the information in the file on disk but 
             not in memory, so we have to do this on our own (only 
             necessary when the cpx resides in memory) */
          
          status = newstatus;
        
        }
        break;
      
      case ECONO: case RET: case DENSITY: case BOOT:
        popup_button( button );
        break;
      
      case CPX_MESSAGE:
        switch( msg[0] )
        {
          case WM_CLOSED:
            init_printer();
          case AC_CLOSE:
            quit = 1;
            break;
        }
        break;
    }
    
    if( button >= 0 )
    {
      form[button].ob_state &= (~SELECTED);
      redraw_object( form, button );
    }
  
  }
  return( 0 );
}



void popup_button( int button )
{
  char popup_str[5][20], *popup_ptr[5];
  int num_items, index, i, len_items;
  GRECT button_rect, window_rect;
  
  for( i = 0; i < 5; i++ )
    strcpy( popup_str[i], "  " );
  
  switch( button )
  {
    case BOOT:
      num_items = 2; len_items = 6;
      index = newstatus.boot;
      for( i = 0; i < num_items; i++ )
        strcat( popup_str[i], boot_text[i] );
      break;
    
    case ECONO:
      num_items = 2; len_items = 6;
      index = newstatus.econo;
      for( i = 0; i < num_items; i++ )
        strcat( popup_str[i], econo_text[i] );
      break;
    
    case RET:
      num_items = 4; len_items = 9;
      index = newstatus.ret;
      for( i = 0; i < num_items; i++ )
        strcat( popup_str[i], ret_text[i] );
      break;
    
    case DENSITY:
      num_items = 5; len_items = 4;
      index = newstatus.density;
      for( i = 0; i < num_items; i++ )
        strcat( popup_str[i], density_text[i] );
      break;
    
    default:        /* better safe than sorry */
      return;
  }
  
  for( i = 0; i < num_items; i ++ )
  {
    strcat( popup_str[i], "     " );
    popup_str[i][len_items] = '\0';
    popup_ptr[i] = popup_str[i];
  }
  
  objc_offset( form, button, &button_rect.g_x, &button_rect.g_y );
  button_rect.g_w = form[button].ob_width;
  button_rect.g_h = form[button].ob_height;
  
  objc_offset( form, ROOT, &window_rect.g_x, &window_rect.g_y );
  window_rect.g_w = form[ROOT].ob_width;
  window_rect.g_h = form[ROOT].ob_height;
  
  index = (*cpx_params->popup_do)( popup_ptr, num_items, index, CPX_8x16, &button_rect, &window_rect );
  
  if( index < 0 )
    return;
  
  switch( button )
  {
    case BOOT:
      newstatus.boot = index;
      break;
    
    case ECONO:
      newstatus.econo = index;
      break;
    
    case RET:
      newstatus.ret = index;
      break;
    
    case DENSITY:
      newstatus.density = index;
      break;
  }
  
  set_button( button );
}



void set_button( int button )
{
  /* object type G_BOXTEXT */
  
  switch( button )
  {
    case BOOT:
      ((TEDINFO*)(form[BOOT].ob_spec))->te_ptext = boot_text[newstatus.boot];
      break;
    
    case ECONO:
      ((TEDINFO*)(form[ECONO].ob_spec))->te_ptext = econo_text[newstatus.econo];
      break;
    
    case RET:
      ((TEDINFO*)(form[RET].ob_spec))->te_ptext = ret_text[newstatus.ret];
      break;
    
    case DENSITY:
      ((TEDINFO*)(form[DENSITY].ob_spec))->te_ptext = density_text[newstatus.density];
      break;
  }
}



void upper( char *s )
{
  int i, l;
  
  l = strlen( s );
  
  for( i = 0; i < l; i++ )
    s[i] = toupper( s[i] );
}



void init_printer( void )
{
  /* uppercase is not necessary (only for "@PJL") */
  
  char text[40];
  
  DEBUG( "HP4L: init_printer" );
  
  send( "\033%%-12345X" );
  send( "@PJL\r\n" );
  
  strcpy( text, "@PJL DEFAULT Economode = " );
  strcat( text, econo_text[newstatus.econo] );
  upper( text ); DEBUG( text );
  strcat( text, "\r\n" ); send( text );
  
  strcpy( text, "@PJL DEFAULT Ret = " );
  strcat( text, ret_text[newstatus.ret] );
  upper( text ); DEBUG( text );
  strcat( text, "\r\n" ); send( text );
  
  strcpy( text, "@PJL DEFAULT Density = " );
  strcat( text, density_text[newstatus.density] );
  upper( text ); DEBUG( text );
  strcat( text, "\r\n" ); send( text );
  
  send( "@PJL RESET\r\n" );
  send( "\033%%-12345X" );
}



void send( char text[] )
{
  int i, l;
  
  l = strlen( text );
  
  for( i = 0; i < l; i++ )
  {
    if( !Cprnos() )
    {
      DEBUG( "HP4L: error: printer not ready" );
      return;
    }
    
    Cprnout( text[i] );
  }
}



void debug( char text[] )
{
  int i, l;
  int dev = 2;              /* or what ever you like */
  
  l = strlen( text );
  
  for( i = 0; i < l; i++ )
  {
    if( !Bcostat( dev ) )
      return;
    
    Bconout( dev, text[i] );
  }
  
  Bconout( dev, '\r' );
  Bconout( dev, '\n' );
}

