! APM data structure manager for CIFSYS.

%own %integer TANK SIZE = 512
%own %integer %array LAYERS (1:MAX LAYERS)
%own %integer %array OFFSETS (1:MAX LAYERS)

%routine ADD (%integer SYM)
   ! This adds SYM to the internal CIF representation
   ! The fact that a valid layer is being used should have been checked by CIF PARSER.
   INTEGER (LAYERS(CLAYER)) = SYM
   LAYERS (CLAYER) = LAYERS (CLAYER) + 4
{print string ("Added "); write (sym,0); newline
%end

%routine ADD POINT (%record (POINTFM) %name P)
   RECORD (LAYERS(CLAYER)) = P
   LAYERS (CLAYER) = LAYERS (CLAYER) + 8
{print string ("Add point "); write (P_X,1); write (P_y,1); newline
%end

%routine ADD TRANS (%real %array %name RA(0:8))
   ! Add the top 2 x 2 of the transformation array.
   %integer I

   %for I = 0, 3, 6 %cycle
        REAL (LAYERS(CLAYER)) = RA(I)
        REAL (LAYERS(CLAYER)+4) = RA(I+1)
        LAYERS (CLAYER) = LAYERS (CLAYER) + 8
   %repeat
%end

%integer %fn GET (%integer %name I)
   I = I + 4
   %result = INTEGER (I-4)
%end

%routine GET POINT (%integer %name I, %record (POINTFM) %name P)
{print string ("Get point "); write (integer(I),1); write (integer(I+4),1); newline
   POINT TRANSFORM (RECORD (I), P)
   I = I + 8
%end

%routine GET VECTOR (%integer %name I, %record (POINTFM) %name V)
   VECTOR TRANSFORM (RECORD (I), V)
   I = I + 8
%end

%routine GET TRANS (%integer %name I, %real %array %name RA(0:8))
   RA (0) = REAL(I);      RA (1) = REAL(I+4);    RA (2) = 0
   RA (3) = REAL(I+8);    RA (4) = REAL(I+12);   RA (5) = 0
   RA (6) = REAL(I+16);   RA (7) = REAL(I+20);   RA (8) = 1
   I = I + 24
%end

%routine GET DATA SPACE (%integer FACTOR)
   %integer A, I

   A = 0
   A = A + PERCENTS (I) %for I = 1, 1, N LAYERS
   %signal 13, TOO LARGE PERCENTAGE %if A > 100
   PERCENTS (N LAYERS) = PERCENTS (N LAYERS) + 100 - A %if A < 100

   TANK SIZE = FACTOR
   LAYERS (1) = HEAP GET (TANK SIZE)
   ! LAYERS (1) now points to the start of the virtual area.
   %for I = 2, 1, N LAYERS %cycle
        LAYERS (I) = (LAYERS (I-1) +  TANK SIZE * PERCENTS(I-1) // 100) & (\1)
   %repeat
   OFFSETS(I) = LAYERS (I) %for I = 1, 1, N LAYERS
%end

%end %of %file
