-- ALEOps.mesa 
--   Edited by Sweet, January 26, 1981  1:28 PM

DIRECTORY
  AltoDisplay,
  String,
  Table,
  Window,
  WindowFont;

ALEOps: DEFINITIONS =
  BEGIN

  -- copied symbol table stuff

  Password: CARDINAL = 8201;
  nTables: CARDINAL = 7;

  HVLength: PRIVATE CARDINAL = 71;
  HVIndex: TYPE = CARDINAL [0..HVLength);

  HTRecord: TYPE = RECORD [
    anyInternal, anyPublic: BOOLEAN,
    link: HTIndex,
    ssIndex: CARDINAL];

  HTIndex: TYPE = CARDINAL [0..Table.Limit/2);
  HTNull: HTIndex = FIRST[HTIndex];
  htType: Table.Selector = 2;
  ssType: Table.Selector = 3;

  -- points, lines, etc.

  FontSize: TYPE = {small, large};
  LabelMode: TYPE = {portrait, landscape};

  Label: TYPE = RECORD [
    free: BOOLEAN ← FALSE,
    selected: BOOLEAN ← TRUE,
    font: FontSize ← small,
    hti: HTIndex,
    mode: LabelMode ← portrait,
    thread: LBIndex ← LBNull,
    selNext: LBIndex ← LBNull,
    pos: APosition];
  LBIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO Label;
  LBHandle: TYPE = POINTER TO Label;
  LBNull: LBIndex = LAST[LBIndex];
  lbType: Table.Selector = 4;

  ALEHeader: TYPE = RECORD [ --rework asap
    diagLines: LTIndex ← LTNull,
    labels: LBIndex ← LBNull,
    freePoint: PTIndex ← PTNull,
    freeLine: LTIndex ← LTNull,
    freeLabel: LBIndex ← LBNull,
    selectedLines: LTIndex ← LTNull,
    selectedPoints, nextSelPoint: PTIndex ← PTNull,
    selectedLabels: LBIndex ← LBNull];

  State: TYPE = RECORD [
    displayTicks: BOOLEAN,
    showingLabels: BOOLEAN,
    grain: [0..4],
    magnify: [-3..4],
    minMagnify: [-3..4],
    currentWidth: LineWidth,
    currentTexture: LineTexture,
    currentLabelMode: LabelMode,
    currentFont: FontSize,
    sixteenthsPerFoot: [1..16],
    blowup: [1..4]];

  Coordinate: TYPE = AltoDisplay.Coordinate;

  ADistance: TYPE = LONG INTEGER;
  APosition: TYPE = RECORD [x,y: ADistance];
  RPosition: TYPE = RECORD [x,y: ADistance];
  ABox: TYPE = RECORD [x1, x2, y1, y2: ADistance];
  inch: ADistance = 16;

  Point: TYPE = RECORD [
    free, selected: BOOLEAN ← FALSE,
    lines: LTIndex ← LTNull,
    thread: PTIndex ← PTNull,
    selNext: PTIndex ← PTNull,
    pos: APosition];
  PTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO Point;
  PTHandle: TYPE = POINTER TO Point;
  PTNull: PTIndex = LAST[PTIndex];
  ptType: Table.Selector = 0;
  ltType: Table.Selector = 1;

  LineColor: TYPE = {white, grey, black};
  GreyColor: ARRAY LineColor OF Window.GreyArray = [
    [0, 0, 0, 0],
    [125252B,52525B,125252B, 52525B],
    [177777B, 177777B, 177777B, 177777B]];

  LineWidth: TYPE = [1..4];
  LineTexture: TYPE = {d2, d4, d6, solid};
  LineClass: TYPE = {horiz, shallow, steep, vert};
  Line: TYPE = RECORD [
    free: BOOLEAN ← FALSE,
    selected: BOOLEAN ← TRUE,
    p1: PTIndex,
    width: LineWidth,
    p2: PTIndex,
    texture: LineTexture,
    p1Chain: LTIndex,
    class: LineClass,
    p2Chain: LTIndex,
    thread: LTIndex ← LTNull,
    selNext: LTIndex ← LTNull];
  LTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO Line;
  LTHandle: TYPE = POINTER TO Line;
  LTNull: LTIndex = LAST[LTIndex];

  FreeNode: TYPE = RECORD [
    free: BOOLEAN ← TRUE, 
    fill: [0..1] ← NULL, 
    next: Table.Base RELATIVE POINTER [0..Table.Limit)]; -- TO UNSPECIFIED
  FNIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO FreeNode;
  FNNull: FNIndex = LAST[FNIndex];

  Bounds: TYPE = RECORD [min, max: ADistance];
  HorizRec: TYPE = RECORD [
    maxW: LineWidth ← 1,
    lines: LTIndex ← LTNull,
    points: PTIndex ← PTNull,
    l, p: Bounds ← [min: LAST[ADistance], max: 0],
    y: ADistance];
  hrType: Table.Selector = 5;

  VertRec: TYPE = RECORD [
    maxW: LineWidth ← 1,
    lines: LTIndex ← LTNull,
    l: Bounds ← [min: LAST[ADistance], max: 0],
    x: ADistance];
  vrType: Table.Selector = 6;


  RedrawObject: TYPE = RECORD [
    next: Redraw,
    var: SELECT tag: * FROM
      label => [font: FontSize, mode: LabelMode, hti: HTIndex, pos: APosition],
      line => [width: LineWidth, texture: LineTexture, pos1, pos2: APosition],
      ENDCASE];
  Redraw: TYPE = POINTER TO RedrawObject;

  PointScan: TYPE = PROCEDURE [p: PTIndex, pth: PTHandle] RETURNS [stop: BOOLEAN];
  LineScan: TYPE = PROCEDURE [l: LTIndex, lth: LTHandle] RETURNS [stop: BOOLEAN];
  LabelScan: TYPE = PROCEDURE [lb: LBIndex, lbh: LBHandle] RETURNS [stop: BOOLEAN];

  CursorShape: TYPE = {point, source, dest, select, origin, upper, lower, selPt};

  PaddleRec: TYPE = MACHINE DEPENDENT RECORD [
    alpha(0): BOOLEAN,
    beta(1): BOOLEAN,
    move(2): BOOLEAN,
    draw(3): BOOLEAN,
    adj(4): BOOLEAN];

  MouseState: TYPE = {clear, red, yellow, blue, upper, lower, sourceN,
    sourceE, sourceS, sourceW, destN, destE, destS, destW};
  TrackMode: TYPE = {fast, slow, inch, fine};
  SelectionMode: TYPE = {new, add, sub, box};
  MaxX: INTEGER = AltoDisplay.MaxBitsPerLine;
  MaxY: INTEGER = AltoDisplay.MaxScanLines;

  FeedbackBox: Window.Box = [[x: 0, y: 0], [w: 576, h: 32]];
  FrameBox: Window.Box = [[x: 0, y: 32], [w: 576, h: 736]];
  PictureBox: Window.Box = [[x: 0, y: 0], [w: 20000, h: 20000]];
  originBox: Window.Box = [[x: -5, y: -5], [w: 11, h: 11]];
  sourceBox: Window.Box = [[x: 0, y: 0], [w: 8, h: 9]];
  destBox: Window.Box = [[x: 0, y: 0], [w: 8, h: 9]];
  upperBox, lowerBox: Window.Box = [[0,0], [8,8]];

  Opcode: TYPE = {
    drawSource, drawDest, drawOrigin, undrawSource, undrawDest,
    setGrain, setMinMagnify, showTicks, draw, drawRect, move,
    copy, delete, undelete, zoomIn, zoomOut, setOrigin, sourceToClose,
    destToClose, newSelection, addSelection, subSelection, boxSelection,
    readIn, writeOut, pressOut, collectLabel, slide, mergeIn, reset, repaint,
    drawUpper, drawLower, undrawUpper, undrawLower, redrawSelections,
    xlateAndRotate, dimensionSelection, jamOut};

  Operation: TYPE = RECORD [ SELECT op: Opcode FROM
    drawUpper, drawLower, drawSource, drawDest, drawOrigin =>
      [place: Window.Place],
    delete, undelete, zoomOut, undrawSource, undrawDest, showTicks, reset,
    undrawUpper, undrawLower, repaint, redrawSelections => [],
    setOrigin, slide => [pos: APosition],
    move, copy => [delta: APosition],
    zoomIn => [p1, p2: APosition],
    sourceToClose, destToClose => [pos: APosition],
    newSelection, addSelection, subSelection => [pos: APosition],
    draw, drawRect => [from, to: APosition],
    boxSelection => [pos1, pos2: APosition],
    xlateAndRotate => [source, dest: APosition],
    dimensionSelection => [pos: APosition, feet: BOOLEAN],
    setGrain, setMinMagnify => [val: CARDINAL],
    collectLabel => [c: CHARACTER, pos: APosition],
    readIn, writeOut, mergeIn, pressOut, jamOut => [file: STRING],
    ENDCASE];

  state: State;

  Short: PROC [ADistance] RETURNS [INTEGER];
  MulDiv: PROC [a, b, c: LONG INTEGER] RETURNS [LONG INTEGER];
  Hypot: PROC [a, b: LONG INTEGER] RETURNS [LONG INTEGER];

  GiveBackKeys: PUBLIC PROC;
  Confirm: PROC RETURNS [BOOLEAN];
  Cursors: ARRAY CursorShape OF AltoDisplay.CursorBits;
  Relative: PROC [aPos: APosition] RETURNS [RPosition];
  Absolute: PROC [rPos: RPosition] RETURNS [APosition];
  PicturePlace: PROC [aPos: APosition] RETURNS [Window.Place];
  APosForPlace: PROC [place: Window.Place] RETURNS [APosition];
  ADistanceForDots: 
    PROC [dots: INTEGER, mag: [-3..4] ← state.magnify] RETURNS [ADistance];
  DotsForADistance: 
    PROC [dist: ADistance, mag: [-3..4] ← state.magnify] RETURNS [INTEGER];
  ARoundToInch: PROC [aPos: APosition] RETURNS [APosition];
  GetOriginPos: PROC [BOOLEAN] RETURNS [APosition];
  ASetOriginPos: PROC [APosition];
  GetSourcePos: PROC [BOOLEAN] RETURNS [RPosition];
  ASetSourcePos: PROC [APosition];
  GetDestPos: PROC [BOOLEAN] RETURNS [RPosition];
  ASetDestPos: PROC [APosition];
  GetCmd: PROC RETURNS [cmd: Operation];
  cornerPos: APosition;
  StartMouseHandler: PROC;


  StartDisplay: PROC;
  BitmapBox: Window.Box;
  feedbackWindow, frameWindow, pictureWindow: Window.Handle;
  originWindow, sourceWindow, destWindow, upperWindow, lowerWindow:
    Window.Handle;
  originValueBox, sourceValueBox, destValueBox, textBox: Window.Box;
  Disjoint: PROC [b1, b2: POINTER TO Window.Box] RETURNS [BOOLEAN];
  ZoomDetail: PROC [pos1, pos2: APosition];
  ZoomGlobal: PROC;
  DisplayBoxTicks: PUBLIC PROC [on: BOOLEAN];
  SlideCorner: PROC [pos: APosition];
  MarksIn: PROC;
  MarksOut: PROC;
  smallFontAscent: INTEGER;
  largeFontAscent: INTEGER;
  smallFont, largeFont: WindowFont.Handle;

  Rubout: SIGNAL;
  PaintText: PROC;
  ReadChar: PROC RETURNS [CHARACTER];
  OutChar: PROC [CHARACTER];
  OutString: PROC [STRING];
  ReadString: PROC [STRING];
  ClearText: PROC;
  CollectLabel: PROC [c: CHARACTER, pos: APosition];
  AllLabels: PROC [action: LabelScan] RETURNS [LBIndex];
  PosOfLabel: PROC [lb: LBIndex] RETURNS [APosition];
  SSDrawLabel: PUBLIC PROC [ss: String.SubString, pos: APosition, font: FontSize, mode: LabelMode];
  DrawLabel: PROC [s: STRING, pos: APosition];
  InsertLabel: PROC [hti: HTIndex, pos: APosition, font: FontSize, mode: LabelMode] RETURNS [LBIndex];
  BoxForLabel: PROC [lb: LBIndex] RETURNS [Window.Box];
  PaintLabel: PROC [lb: LBIndex];
  DeleteLabel: PROC [lb: LBIndex];
  ResetHash: PROC;
  InitHash: PROC;
  SubStringForLabel: PROC [ss: String.SubString, lb: LBIndex];
  ReadPicture: PROC [file: STRING];
  WritePicture: PROC [file: STRING];
  pictureChanged: BOOLEAN;
  SetupLand: PROC;

  InitLines: PROC;
  ResetLines: PROC;
  ResetPicture: PROC;
  Load: PROC [file: STRING];
  Store: PROC [file: STRING];
  header: ALEHeader;
  hArray: DESCRIPTOR FOR ARRAY OF HorizRec;
  vArray: DESCRIPTOR FOR ARRAY OF VertRec;
  lastH, lastV: INTEGER;
  FindHList: PROC [y: ADistance, addNew: BOOLEAN ← FALSE] RETURNS [hi: INTEGER];
  FindVList: PROC [x: ADistance, addNew: BOOLEAN ← FALSE] RETURNS [vi: INTEGER];
  LinesInABox: PROC [box: POINTER TO ABox, action: LineScan, completely: BOOLEAN ← FALSE] RETURNS [LTIndex];
  AllPoints: PROC [action: PointScan] RETURNS [PTIndex];
  AllLines: PROC [action: LineScan] RETURNS [LTIndex];
  SelectedPoints: PROC [action: PointScan] RETURNS [PTIndex];
  SelectedLines: PROC [action: LineScan] RETURNS [LTIndex];
  SelectedLabels: PROC [action: LabelScan] RETURNS [LBIndex];
  UnSelChainLabel: PROC [lb: LBIndex];
  ABoxForBox: PUBLIC PROC [box: Window.Box] RETURNS [ABox];
  LinesThru: PROC [p: PTIndex, action: LineScan] RETURNS [LTIndex];
  BoxForLine: PROC [l: LTIndex] RETURNS [Window.Box];
  DimSelection: PROC [pos: APosition, feet: BOOLEAN];
  DisplayLine: PROC [l: LTIndex, box: Window.Box];
  MaybeDisplayLine: PROC [l: LTIndex];
  DrawLine: PROC [pos1, pos2: APosition, selected: BOOLEAN ← TRUE];
  ClearSelections: PROC;
  PosOf: PUBLIC PROC [p: PTIndex] RETURNS [APosition];
  BoxForPoint: PROC [p: PTIndex] RETURNS [Window.Box];
  PointsOf: PUBLIC PROC [l: LTIndex] RETURNS [p1, p2: PTIndex];
  WidthOf: PUBLIC PROC [l: LTIndex] RETURNS [[1..4]];
  AddSelection: PROC [pos: APosition];
  SubSelection: PROC [pos: APosition];
  DeleteSelections: PROC;
  SourceToClosePoint: PROC [pos: APosition];
  DestToClosePoint: PROC [pos: APosition];
  SelectInBox: PROC [pos1, pos2: APosition];
  MoveSelections: PROC [delta: APosition];
  MoveAndRotate: PROC [source, dest: APosition];
  CopySelections: PROC [delta: APosition];
  UndeleteItems: PROC;
  RedrawItems: PROC [Redraw];
  RedrawSelections: PROC;
  DeleteLine: PROC [l: LTIndex];
  ChopUpLine: PROC [l: LTIndex, box: POINTER TO ABox, pproc: PROC [
    pos1, pos2: APosition, 
      class: LineClass, 
      color: LineColor, 
      lWidth: LineWidth, 
      lengthen: [0..4], 
      box: POINTER TO ABox]];

  ALELinesBNotify: Table.Notifier;

  ShouldLengthen: PROC [LTIndex] RETURNS [[0..4]];
  PressPicture: PROC [STRING];
  PressPictureInABox: PROC [STRING, ABox];
  Sqrt: PROC [LONG CARDINAL] RETURNS [CARDINAL];
  JamPicture: PROC [file: STRING];

  Helvetica8, Helvetica14, Gacha10: PROGRAM;

  END.