-- ReplicateMain.mesa
-- a program to run within Chipmonk

-- modified by E. McCreight, February 23, 1982  11:36 AM
-- written by E. McCreight, September 23, 1981  6:57 PM

DIRECTORY
  ChipUserInt,
  ppddefs,
  ppdefs,
  RomMakerDefs;

ReplicateMain: PROGRAM
  IMPORTS ChipUserInt, ppddefs, ppdefs, RomMakerDefs =
  BEGIN OPEN ChipUserInt, ppddefs, ppdefs, RomMakerDefs;

--  C e l l - R e l a t e d   a n d   P r o c e d u r e s

  Offset: PROCEDURE[p: Point ← [0, 0],
    cell: listPtr ← NIL, cellSize: Point ← [0,0],
    dir: Direction, rep: Point ← [0, 0],
    midCell: listPtr ← NIL, midCellSize: Point ← [0,0],
    midGap: Point ← [0, 0], includeTerminalMid: BOOLEAN ← TRUE]
    RETURNS [Point] =
    BEGIN
    midRep: Point ← IF includeTerminalMid THEN rep ELSE
      [x: rep.x-1, y: rep.y-1];
    IF cell#NIL THEN cellSize ← CellSize[cell.ob];
    midCellSize ← IF midCell#NIL THEN CellSize[midCell.ob, dir]
      ELSE DirSize[midCellSize, dir];
    RETURN[[x: p.x+rep.x*DirSize[cellSize, dir].x+
        MidCellRep[midGap.x, midRep.x, cellSize.x]*
          midCellSize.x,
      y: p.y+rep.y*DirSize[cellSize, dir].y+
        MidCellRep[midGap.y, midRep.y, cellSize.y]*
          midCellSize.y]];
    END;


  CellsPerGap: PROCEDURE[gap, sizePerCell: locNum] RETURNS[INTEGER] =
    {RETURN[(gap+sizePerCell-1)/sizePerCell] -- ceiling --};


  MidCellRep: PROCEDURE[gap, nCells, sizePerCell: locNum] RETURNS[INTEGER] =
    BEGIN
    cellsPerGap: INTEGER ← CellsPerGap[gap, sizePerCell];
    RETURN[IF cellsPerGap=0 THEN 0 ELSE nCells/cellsPerGap];
    END;


  PlaceList: PROCEDURE[to: listPtr ← NIL, lp: listPtr, cellSize: Point,
    rep: Point ← [0,0], midCellSize: Point ← [0,0],
    midGap: Point ← [0,0]] RETURNS[listPtr] =
    BEGIN
    cp: Point ← Offset[cellSize: cellSize, dir: diagonal, rep: rep,
      midCellSize: midCellSize, midGap: midGap];
    WHILE lp#NIL DO
      to ← copyObject[lp: lp, mp: to, xoff: cp.x, yoff: cp.y];
      lp ← lp.nxt;
      ENDLOOP;
    RETURN[to];
    END;


  -- M a i n   P r o g r a m

  BEGIN
  ENABLE
    BEGIN
    Punt => GOTO Exit;  -- for exits
    UNWIND => ColorOn[];
    END;

  hRep, vRep, hSize, vSize: locNum;
  selRect, boundary: Rect;
  selList, selListTail, copyList: listPtr ← NIL;
  useBoundingBox: BOOLEAN;

  lpp: LONG POINTER TO listPtr;

  ColorOff[];

  hRep ← RequestInteger["Replicate selected items"L,
    "How many times horizontally?"L];
  vRep ← RequestInteger["Replicate selected items"L,
    "How many times vertically?"L];

  IF NOT (useBoundingBox ←
    HeSaysYes["Should I take the pitch from the"L,
    "bounding box of the selected items?"L]) THEN
    BEGIN
    IF HeSaysYes["OK, then should I take the pitch from the"L,
      "gap between mark and cursor?"] THEN
      {hSize ← xx-markPnt.x; vSize ← yy-markPnt.y}
    ELSE {Explain["That's all I know how to do!"L]; GOTO Exit};
    END;

  lpp ← @masterList;
  WHILE lpp↑#NIL DO
    IF lpp↑.selected THEN
      BEGIN
      lp: listPtr ← lpp↑;
      lpp↑ ← lp.nxt;
      lp.nxt ← selList;
      selRect ← IF selList=NIL THEN getRect[lp] ELSE
        mergeRects[selRect, getRect[lp]];
      selList ← lp;
      IF selListTail=NIL THEN selListTail ← lp;
      END
    ELSE lpp ← @lpp↑.nxt;
    ENDLOOP;

  IF selList=NIL THEN
    {Explain["No selections!"L]; GOTO Exit};

  IF useBoundingBox THEN
    {hSize ← selRect.x2-selRect.x1; vSize ← selRect.y2-selRect.y1};

  FOR h: locNum IN [0..hRep) DO FOR v: locNum IN [0..vRep) DO
    IF h#0 OR v#0 THEN
      BEGIN
      copyList ← PlaceList[to: copyList, lp: selList,
        cellSize: [x: hSize, y: vSize], rep: [x: h, y: v]];
      END;
    ENDLOOP ENDLOOP;

  selListTail.nxt ← copyList;
  copyList ← NIL;
  boundary ← getRect[selList];
  WHILE selList#NIL DO
    lp: listPtr ← selList;
    selList ← lp.nxt;
    lp.selected ← TRUE;
    boundary ← mergeRects[boundary, getRect[lp]];
    masterList ← insertList[masterList, lp];
    ENDLOOP;

  reDrawRect[boundary, 0, TRUE, TRUE, FALSE];

  EXITS Exit => NULL;
  END;

  -- give back all the storage we allocated

  ColorOn[];
  anyChanges ← sinceIOchanges ← TRUE;

  END. -- of ReplicateMain