
/* "UNTIL", a graphics editor,
   Copyright (C) 1985, 1990 California Institute of Technology.
   Original authors: Glenn Gribble, port by Steve DeWeerth
   Unix Port Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425 CU Boulder/Boulder CO 91125. 

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (Version 1, 1989).

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
USA. */


/*******************************************************************************/
/*                                                                             */ 
/*  file contains stuff to deal with menus                                     */
/*  cleaned up by steve - 9 May 1990                                           */
/*                                                                             */ 
/*******************************************************************************/

#include <p2c/p2c.h>

#include "menu_stuff.h"


#ifndef NEWASM_H
#include <p2c/newasm.h>
#endif

#ifndef SYSDEVS_H
#include <p2c/sysdevs.h>
#endif

#ifndef NEWKBD_H
#include <p2c/newkbd.h>
#endif

#ifndef NEWCI_H
#include <p2c/newci.h>
#endif


/* exported global variables */

/* Zoom and offset variables */
double default_zoom;   /* default zoom for empty cells */
double min_zoom, max_zoom;   /* Max, min for center command */
double zoom;   /* Never used in matrix stuff */
long zoom_num, zoom_den, off_x, off_y;
boolean wideArrows, showGrid, draftMode;

/* Show comments in output PS files?*/
Char pensPsSearch[5][fidleng + 1];
vRec gridRec, rotRec, widthRec;

Char fontName[21];

Char origName[10];
Char *origNames;

boolean leftSide;   /* Bogus */



void build_matrix(void)
{
  mat_ident();
  mat_tran((plotArea.xl + plotArea.xh) / 2, (plotArea.yl + plotArea.yh) / 2);
  mat_scale(zoom_num, zoom_num, zoom_den);
  mat_tran(-off_x, -off_y);
}


Static void doShowGrid(void)
{
  long x, y, x1, y1, xt, yt;
  double spacing;

  m_colormode(m_xor);
  m_color(15);

  /* Where is 0,0 in screen space? */
  mat_transform(0, 0, &x1, &y1);

  /* Compute grid spacing in screen coordinates.  If it is not integral, then */
  /* we do not try to draw a grid. */
  if (!grid_hex) {
    spacing = (double)(zoom_num * grid_mul) / zoom_den;
    if (fabs((long)spacing - spacing) > 0.0001)
      printf("\001          Non-integral zoom for grid.  Grid ignored.\n");
    else if (spacing < 4)
      printf("\001          Zoom too small for grid.  Grid ignored.\n");
    else
      m_grid(32, 0, m_across, m_down, (long)spacing, (long)spacing, x1, y1);
  } else {
    for (x = -7; x <= 7; x++) {
      for (y = -7; y <= 7; y++) {
	mat_transform((x * 2 + y) * grid_mul * 4, y * grid_mul * 7, &xt, &yt);
	m_drawpoint(xt, yt);
      }
    }
  }

  /* Draw a blob at 0,0.  We can always do this, regardless of the zoom. */
  m_ellipse(x1, y1, 5, 5, 15);
  m_drawline(x1 - 3, y1 - 3, x1 + 3, y1 + 3);
  m_drawline(x1 + 3, y1 - 3, x1 - 3, y1 + 3);
}


void refresh(void)
{
  gr_bright();
  menu_clip_on();
  build_matrix();
  pr_refresh();
  if (showGrid)
    doShowGrid();
  menu_show();
}


void set_zoom(double newzoom)
{
  long n, d;

  zoom = fabs(newzoom);
  if (zoom > 16)
    zoom = 16.0;
  else if (zoom < 1.0 / 1024)
    zoom = 1.0 / 1024;
  if (showGrid && zoom * grid_mul > 4) {   /* Make sure we can see the grid */
    n = (long)(zoom * grid_mul);
    d = grid_mul;
  } else {
    n = (long)zoom;
    if (n >= 2)
      d = 1;
    else {
      n = (long)(zoom * 64);
      if (n > 2)
	d = 64;
      else {
	n = (long)(zoom * 1024);
	d = 1024;
      }
    }
  }

  if (n % d == 0) {
    n /= d;
    d = 1;
  } 
  else if (d % n == 0) {
    d /= n;
    n = 1;
  }

  zoom_num = n;
  zoom_den = d;
  printf("\001          Zoom =%ld/%ld, was %0.4f(%0.4f), is %0.4f\n", 
          n, d, zoom, newzoom, (double)n / d);
  zoom = (double)n / d;
}


void set_grid(short g)
{
  if (g <= 0)
    g = 1;
  /*curGrid  := g;*/
  grid_mul = g;
  grid_rnd = 0;
}


void a_cleara(void)
{
  putchar('\f');
}


void a_zoomin(void)
{
  set_zoom(zoom * 2);
  refresh();
}


void a_zoomout(void)
{
  set_zoom(zoom * 0.5);
  refresh();
}


/* Translate the display PX, PY pixels */
Static void do_tran(long px, long py)
{
  off_x += px * zoom_den / zoom_num;
  off_y += py * zoom_den / zoom_num;
  refresh();
}


void a_home(void)
{
  off_x = 0;
  off_y = 0;
  set_zoom(default_zoom);
  refresh();
}


void center_display(void)
{
  object *o;
  long dx, dy;
  double newZoom;
  bbrec *WITH;

  update_root_mbb();
  update_root_mbb();
  o = curFigure->guts;
  WITH = &o->bb;
  /*refresh;*/
  off_x = (WITH->xh + WITH->xl) / 2;
  off_y = (WITH->yh + WITH->yl) / 2;
  dx = WITH->xh - WITH->xl;
  dy = WITH->yh - WITH->yl;
  if (dx <= 0 || dy <= 0) {
    newZoom = default_zoom;
    off_x = 0;
    off_y = 0;
  } else if (dx > dy)
    newZoom = (m_across - 100.0) / dx;
  else
    newZoom = (m_down - 40.0) / dy;
  if (zoom > max_zoom)
    newZoom = max_zoom;
  if (zoom < min_zoom)
    newZoom = min_zoom;
  set_zoom(newZoom);
}


void maybeMakeFile(Char *name_)
{
  Char name[fidleng + 1];
  Char c;
  Char figname[fidleng + 1];
  Char *TEMP;

  strcpy(name, name_);
  printf("%s not loaded, create? ", name);
  c = nk_getkey();
  if (c > ' ')
    putchar(c);
  putchar('\n');
  if (c != 'y' && c != 'Y')
    return;
  newci_fixfname(name, "ff", "");
  if (make_filespec(name, established) == NULL)
    printf("Help, I can't make files--tell Glenn!!\007\n");

  strlower(name, name);
  while (strpos2(name, "/", 1) != 0)
    strcpy(name, name + strpos2(name, "/", 1));
  if (strpos2(name, ".", 1) > 1) {
    name[strpos2(name, ".", 1) - 1] = '\0';
/* p2c: menu_stuff.text, line 275:
 * Note: Modification of string length may translate incorrectly [146] */
  }
  printf("Figure name [%s]? ", name);
  fgets(figname, fidleng + 1, stdin);
  TEMP = (char *) strchr(figname, '\n');
  if (TEMP != NULL)
    *TEMP = 0;
  if (*figname == '\0')
    strcpy(figname, name);
  if (make_figure(figname) == NULL)
    printf("Help, I can't make figures--tell Glenn!!\007\n");
}


void a_load(void)
{
  Char s[fidleng + 1];
  Char *TEMP;

  printf("\n\n\n\n\n\n\037\037\037Load/create which file? ");
  fgets(s, fidleng + 1, stdin);
  TEMP = (char *) strchr(s, '\n');
  if (TEMP != NULL)
    *TEMP = 0;
  if (*s == '\0')
    return;
  if (read_in_a_file(s) == NULL)
    maybeMakeFile(s);

  if (curFigure == NULL)
    return;
  center_display();
  gr_bright();
  refresh();
  menu_show();
}


/* Index into a comma-separated string */
Static Char *findStrSub(Char *Result, Char *names_, short subMode)
{
  Char names[256];
  long p;

  strcpy(names, names_);
  while (subMode > 0 && *names != '\0') {
    p = strpos2(names, ",", 1);
    if (p == 0)
      p = strlen(names);
    strcpy(names, names + p);
    subMode--;
  }
  p = strpos2(names, ",", 1);
  if (p != 0) {
    names[p - 1] = '\0';
/* p2c: menu_stuff.text, line 318:
 * Note: Modification of string length may translate incorrectly [146] */
  }
  return strcpy(Result, names);
}


Static short numCommas(Char *s)
{
  short nc, i, FORLIM;

  nc = 0;
  FORLIM = strlen(s);
  for (i = 0; i < FORLIM; i++) {
    if (s[i] == ',')
      nc++;
  }
  return nc;
}


Static void do_font(void)
{
  if (!leftSide) {
    curTextFont++;
    if (curTextFont > numFonts)
      curTextFont = 0;
  } else {
    curTextFont--;
    if (curTextFont <= 0)
      curTextFont = numFonts;
  }
  strcpy(fontName, fonts[curTextFont - 1].dispName);
}


Static void mp_initFont(void)
{
  if (curTextFont < 1 || curTextFont > numFonts)
    curTextFont = 13;
  strcpy(fontName, fonts[curTextFont - 1].dispName);
}


Static short do_vText(Char *s_, short current)
{
  Char s[256];

  strcpy(s, s_);
  if (leftSide) {
    current++;
    if (current > numCommas(s))
      current = 0;
    return current;
  }
  current--;
  if (current < 0)
    current = numCommas(s);
  return current;
}


Static void do_orig(void)
{
  curTextOrig = (centerType)do_vText(origNames, (int)curTextOrig);
  findStrSub(origName, origNames, (int)curTextOrig);
  /*menu_show_item(mp^, true);*/
}


Static short do_vThing(vRec *v, short current)
{
  long i;

  if (leftSide) {
    i = v->num - 1;
    while (i >= 0 && current <= v->arr[i])
      i--;
    if (i < 0)
      i = v->num - 1;
    return (v->arr[i]);
  }
  i = 0;
  while (i < v->num && current >= v->arr[i])
    i++;
  if (i >= v->num)
    i = 0;
  return (v->arr[i]);
}


Static void add_width(void)
{
  widthRec.arr[0] = 0;
  widthRec.arr[1] = 1;
  widthRec.arr[2] = 2;
  widthRec.arr[3] = 4;
  widthRec.arr[4] = 8;
  widthRec.arr[5] = 16;
  widthRec.arr[6] = 32;
  widthRec.arr[7] = 64;
  widthRec.arr[8] = 128;
  widthRec.num = 9;
}


Static void add_rot(void)
{
  rotRec.arr[0] = 4;
  rotRec.arr[1] = 6;
  rotRec.arr[2] = 8;
  rotRec.arr[3] = 12;
  rotRec.arr[4] = 24;
  rotRec.arr[5] = 360;
  rotRec.num = 6;
}


Static void add_grid(void)
{
  gridRec.arr[0] = 1;
  gridRec.arr[1] = 2;
  gridRec.arr[2] = 4;
  gridRec.arr[3] = 8;
  gridRec.arr[4] = 16;
  gridRec.arr[5] = 32;
  gridRec.arr[6] = 64;
  gridRec.num = 7;
}


void do_exit(void)
{
  fileSpec *filp;
  figure *figp;
  boolean first;
  Char TEMP;

  a_cleara();  /* steve */
  gr_dim();
  if (CURRENTCRT == ALPHATYPE)
    printf("\f");
  printf("\001\n\n\n");
  first = true;
  filp = files;
  while (filp != NULL) {
    figp = filp->figures;
    while (figp != NULL) {
      if (figp->changes != 0) {
	if (first)
	  printf("          \201Changes in the following figures: \200");
	if (XPOS + strlen(figp->name) + 10 > nk_screenwidth)
	  printf("\n          ");
	printf("%d in %s, ", figp->changes, figp->name);
	first = false;
      }
      figp = figp->next;
    }
    filp = filp->next;
  }

  boop();
  if (!first)
  {
    printf("\015\n\n\n         Are you sure you want to exit? ");
    TEMP = nk_getkey();
    quit = (TEMP == 'y' || TEMP == 'Y');
    if (CURRENTCRT == ALPHATYPE)
      printf("\f");
  }
  else
    quit = 1;

  if (!quit)
  {
    gr_bright();
    a_cleara();  /* steve */
  }
}
