-- LoomControl.mesa Edited by Sweet on June 13, 1979  10:56 AM

DIRECTORY
  CursorDefs: FROM "cursordefs" USING [SetCursor, textPointer],
  DisplayDefs: FROM "displaydefs" USING [Dimension],
  LoomDefs: FROM "loomdefs",
  PBKDefs: FROM "PBKDefs" USING [EnterExit],
  PBKInputDefs: FROM "PBKInputDefs" USING [SetNopPNRs],
  ParameterDefs: FROM "ParameterDefs" USING [
    DestroyParameterSubwindowEtc,
    DisplayParameterItem, DisplayParameterSubwindow, ParameterItemDescriptor,
    ParameterItemHandle],
  PressMyDefs: FROM "pressmydefs" USING [OutScreen],
  SegmentDefs: FROM "SegmentDefs" USING [FileNameError],
  StreamDefs: FROM "StreamDefs" USING [
    AccessOptions, Append, NewByteStream, NewWordStream, Read,
    StreamHandle, Write],
  StringDefs: FROM "StringDefs" USING [AppendChar, AppendString],
  SystemDefs: FROM "SystemDefs" USING [
    AllocateHeapString, FreeHeapNode, FreeHeapString],
  ToolsDefs: FROM "ToolsDefs" USING [
    FreeToolsNode, FreeToolsString, SetToolsDestroyProc],
  ToolsFontDefs: FROM "ToolsFontDefs" USING [
    ComputeStringWidth, FAptr, GetToolsFont],
  WindowDefs: FROM "WindowDefs" USING [
    CreateSubwindow, CreateWindow, DestroySubwindow,
    DestroyWindowEtc, DrawWindowFrame, DrawWindowNameFrame,
    ReplaceStringToPlaceInSubwindow, PaintWindow, RefreshSequencer,
    ShadeBoxInSubwindow,
    StandardAdjustProc, SubwindowHandle, SubwindowPlace, WindowBox,
    WindowHandle, BlackenBoxInSubwindow, WhitenBoxInSubwindow];

LoomControl: PROGRAM
  IMPORTS CursorDefs, LoomDefs, ParameterDefs, PBKInputDefs, PressMyDefs, SegmentDefs, StreamDefs,
    StringDefs, SystemDefs, ToolsDefs, ToolsFontDefs, WindowDefs 
  EXPORTS LoomDefs =
    
BEGIN OPEN DisplayDefs, ParameterDefs, WindowDefs, StreamDefs, LoomDefs;

  StdPedal: PUBLIC PROCEDURE [
    sw: SubwindowHandle, items: ParameterItemDescriptor, index: CARDINAL] =
    BEGIN
    PostLine[NIL];
    poString ← SetString[poString, woString];
    [] ← DisplayParameterItem[parameterSW, poParmNum];
    END;

  UpDown: PUBLIC PROCEDURE [
    sw: SubwindowHandle, items: ParameterItemDescriptor, index: CARDINAL] =
    BEGIN
    i: CARDINAL;
    l: CARDINAL ← poString.length;
    PostLine[NIL];
    IF 2*l-2 > poString.maxlength THEN
      BEGIN
      ns: STRING ← SystemDefs.AllocateHeapString[2*l+10];
      StringDefs.AppendString[ns, poString];
      SystemDefs.FreeHeapString[poString];
      poString ← ns;
      END;
    FOR i IN [0..l-2) DO poString[l+i] ← poString[l-2-i]; ENDLOOP;
    poString.length ← 2*l-2;
    [] ← DisplayParameterItem[parameterSW, poParmNum];
    END;

  SetString: PROCEDURE [s1, s2: STRING] RETURNS [rs: STRING] =
    BEGIN
    IF s1.maxlength >= s2.length THEN rs ← s1
    ELSE
      BEGIN OPEN SystemDefs;
      FreeHeapString[s1];
      rs ← AllocateHeapString[s2.length];
      END;
    rs.length ← 0;
    StringDefs.AppendString[rs, s2];
    END;

Repaint: PUBLIC PROCEDURE [
  sw: SubwindowHandle, items: ParameterItemDescriptor ← NULL, index: CARDINAL ← NULL] =
  BEGIN
  PostLine[NIL];
  RepaintAllWeave[];
  END;

autoRepaint: PUBLIC BOOLEAN ← FALSE;

DisplayWeaveWindowContents: PUBLIC PROCEDURE [
  window: WindowHandle,
  wBox: WindowBox,
  refreshSequencer: RefreshSequencer]
  RETURNS [WindowBox] =
  BEGIN
  sw: SubwindowHandle = window.subwindowChain;
  font: ToolsFontDefs.FAptr;
  fontHeight: INTEGER;

  [font: font, height: fontHeight] ← ToolsFontDefs.GetToolsFont[];
  IF window.size = tiny THEN
    BEGIN
    name: STRING ← "Weaving"L;
    DrawWindowFrame[window];
    [] ← ReplaceStringToPlaceInSubwindow[
      sw,
      [x: (sw.box.dims.w-ToolsFontDefs.ComputeStringWidth[name, font])/2,
      y: (sw.box.dims.h-fontHeight)/2],
      name,
      font];
    sw.box ← [[0,0], [0,0]];
    END
  ELSE 
    BEGIN
    IF autoRepaint THEN RepaintAllWeave[] 
    ELSE DrawWindowNameFrame[weaveWindow, "Weaving"L];
    END;
  RETURN [wBox]; 
  END;
  
-- control stuff
  
controlWindow: PUBLIC WindowHandle ← CreateWindow[
  normal: [[10,0], [500, 210]],
  tiny: [[128,400], [128, 32]],
  displayProc: DisplayControlWindowContents,
  adjustProc: StandardAdjustProc];
  
Load: PUBLIC PROCEDURE [
  sw: SubwindowHandle, items: ParameterItemDescriptor, index: CARDINAL] =
  BEGIN
  PostLine[NIL];
  ReadFile[
    GetFile[name: input, access: Read, size: byte !
      NoName => GOTO noInput;
      SegmentDefs.FileNameError => BEGIN NoFile[input]; GOTO return; END]];
  RETURN
  EXITS
    noInput => PostLine["No input file specified"];
    return => NULL;
  END;

Dump: PUBLIC PROCEDURE [
  sw: SubwindowHandle, items: ParameterItemDescriptor, index: CARDINAL] =
  BEGIN
  PostLine[NIL];
  WriteFile[
    GetFile[name: output, access: Write+Append, size: byte !
      NoName => GOTO noOutput]];
  RETURN
  EXITS
    noOutput => PostLine["No output file specified"];
  END;

Press: PUBLIC PROCEDURE [
  sw: SubwindowHandle, items: ParameterItemDescriptor ← NULL, index: CARDINAL ← NULL] =
  BEGIN
  PostLine[NIL];
  IF output = NIL OR output.length = 0 THEN GO TO noOutput;
  PressMyDefs.OutScreen[output];
  RETURN
  EXITS
    noOutput => PostLine["No output file specified"];
  END;

NoFile: PROCEDURE [name: STRING] =
  BEGIN OPEN StringDefs;
  s: STRING ← [60];
  AppendString[to: s, from: name];
  AppendString[to: s, from: " cannout be found!"L];
  PostLine[s];
  RETURN
  END;
  
NoName: SIGNAL = CODE;

GetFile: PROCEDURE [name: STRING, access: AccessOptions, size: {byte, word}]
  RETURNS [StreamHandle] =
  BEGIN
  nameAndExt: STRING ← [30];
  i: CARDINAL; dotSeen: BOOLEAN ← FALSE;
  IF name = NIL OR name.length = 0 THEN ERROR NoName;
  FOR i IN [0..name.length) DO
    StringDefs.AppendChar[nameAndExt, name[i]];
    IF name[i] = '. THEN dotSeen ← TRUE;
    ENDLOOP;
  IF ~dotSeen THEN StringDefs.AppendString[nameAndExt, ".weave"];
  RETURN[
    IF size = byte THEN NewByteStream[nameAndExt,access]
    ELSE NewWordStream[nameAndExt,access]]
  END;


PostLine: PUBLIC PROCEDURE [s: STRING] =
  BEGIN 
  font: ToolsFontDefs.FAptr;
  fontHeight: INTEGER;
  [font: font, height: fontHeight] ← ToolsFontDefs.GetToolsFont[];
  WhitenBoxInSubwindow[msgSW, [[0,0],[msgSW.box.dims.w,fontHeight]]];
  IF s # NIL THEN [] ← ReplaceStringToPlaceInSubwindow[msgSW, [3,0], s, font]
  END;
  
-- Tools Environment Required Procedures

DisplayControlWindowContents: PROCEDURE [
  window: WindowHandle,
  wBox: WindowBox,
  refreshSequencer: RefreshSequencer]
  RETURNS [WindowBox] =
  BEGIN
  sw: SubwindowHandle = window.subwindowChain;
  font: ToolsFontDefs.FAptr;
  fontHeight: INTEGER;
  [font: font, height: fontHeight] ← ToolsFontDefs.GetToolsFont[];
  IF window.size = tiny THEN
    BEGIN
    name: STRING ← "LoomTool"L;
    DrawWindowFrame[window];
    IF msgSW # NIL THEN MakeToolInactive[];
    [] ← ReplaceStringToPlaceInSubwindow[
      sw,
      [x: (sw.box.dims.w-ToolsFontDefs.ComputeStringWidth[name, font])/2,
      y: (sw.box.dims.h-fontHeight)/2],
      name,
      font];
    sw.box ← [[0,0], [0,0]];
    END
  ELSE
    BEGIN
    DrawWindowNameFrame[window, "Loom Tool 5.0"L];
    IF msgSW = NIL THEN MakeToolActive[];
    msgSW.box ← sw.box;
    msgSW.box.dims.h ← fontHeight;
    graySW.box ← sw.box;
    graySW.box.place.y ← sw.box.place.y + fontHeight + 2;
    graySW.box.dims.h ← fontHeight;
    BlackenBoxInSubwindow[sw, [[0, fontHeight+1], [sw.box.dims.w, 1]]];
    DisplayGrays[];
    parameterSW.box ← sw.box;
    parameterSW.box.place.y ← graySW.box.place.y + fontHeight + 2;
    parameterSW.box.dims.h ← sw.box.dims.h - 2*fontHeight - 4;
    BlackenBoxInSubwindow[sw, [[0, 2*fontHeight+2], [sw.box.dims.w, 1]]];
    DisplayParameterSubwindow[parameterSW];
    END;
  RETURN [wBox]; 
  END;
  
  DisplayGrays: PROCEDURE =
    BEGIN
    x, dx: CARDINAL;
    c: ColorName;
    s: STRING ← [1];
    font: ToolsFontDefs.FAptr;
    fontHeight: INTEGER;

    [font: font, height: fontHeight] ← ToolsFontDefs.GetToolsFont[];
    x ← 1;
    s.length ← 1;
    FOR c IN ColorName DO
      s[0] ← c;
      dx ← ToolsFontDefs.ComputeStringWidth[s, font];
      [] ← ReplaceStringToPlaceInSubwindow[graySW, [x, 0], s, font];
      x ← x + dx;
      BlackenBoxInSubwindow[graySW, [[x, 0], [1, graySW.box.dims.h]]];
      ShadeBoxInSubwindow[graySW,
        [[x+1, 0], [10, fontHeight]],
        GrayData[c]];
        BlackenBoxInSubwindow[graySW, [[x+11, 0], [1, graySW.box.dims.h]]];
      x ← x+12;
      ENDLOOP;
    END;
  
EnterPNR: PROCEDURE [sw: SubwindowHandle, dir: PBKDefs.EnterExit] =
  BEGIN
  IF dir = enter THEN CursorDefs.SetCursor[CursorDefs.textPointer];
  END;
  
MakeToolActive: PROCEDURE =
  BEGIN 
  weaveWindow ← CreateWindow[
    normal: [[10,210], [500, 500]],
    tiny: [[256,400], [128, 32]],
    displayProc: DisplayWeaveWindowContents,
    adjustProc: StandardAdjustProc];
  MakeMeAParameterSubwindow[];
  msgSW ← CreateSubwindow[controlWindow, [[0,0], [10, 10]], NIL];
  graySW ← CreateSubwindow[controlWindow, [[0,0], [10, 10]], NIL];
  PBKInputDefs.SetNopPNRs[controlWindow.subwindowChain];
  PBKInputDefs.SetNopPNRs[msgSW];
  PBKInputDefs.SetNopPNRs[graySW];
  weaveWindow.subwindowChain.pnrs.cursorPNR ← EnterPNR;
  MakeMyMenu[];
  PaintWindow[weaveWindow];
  END;

MakeToolInactive: PUBLIC PROCEDURE  =
  BEGIN OPEN SystemDefs; 
  i: CARDINAL;
  DestroyParameterSubwindowEtc[parameterSW];
  FreeMyMenu[];
  DestroyWindowEtc[weaveWindow];
  FOR i IN [0..nParams) DO
    FreeHeapString[parameterItems[i].tag];
    FreeHeapNode[parameterItems[i]];
    ENDLOOP;
  FreeHeapNode[BASE[parameterItems]];
  DestroySubwindow[parameterSW];
  DestroySubwindow[msgSW];
  DestroySubwindow[graySW];
  msgSW ← NIL;
  titleString ← ToolsDefs.FreeToolsString[titleString];
  input ← ToolsDefs.FreeToolsString[input];
  output ← ToolsDefs.FreeToolsString[output];
  woString ← ToolsDefs.FreeToolsString[woString];
  poString ← ToolsDefs.FreeToolsString[poString];
  warpSizeString ← ToolsDefs.FreeToolsString[warpSizeString];
  weftSizeString ← ToolsDefs.FreeToolsString[weftSizeString];
  overlapString ← ToolsDefs.FreeToolsString[overlapString];
  BEGIN
  p: Pedal;
  FOR p IN Pedal DO tieup[p] ← ToolsDefs.FreeToolsString[tieup[p]]; ENDLOOP;
  END;
  woBase ← ToolsDefs.FreeToolsNode[woBase];
  poBase ← ToolsDefs.FreeToolsNode[poBase];
  END;

nParams: PUBLIC CARDINAL;
poParmNum: PUBLIC CARDINAL;
msgSW: PUBLIC SubwindowHandle ← NIL;
parameterSW: PUBLIC SubwindowHandle;
graySW: PUBLIC SubwindowHandle;
input: PUBLIC STRING ← NIL;
output: PUBLIC STRING ← NIL;
titleString: PUBLIC STRING ← NIL;

-- Mainline code

ToolsDefs.SetToolsDestroyProc[DestroyThisTool];
START LoomDisplay;
START LoomSetup;

END. -- of LoomControl