DEFINITION MODULE PicADT;

(* 
  This module sets up the types and operations needed for maintaining
  a database of picture elements and a set of default entities.
*)

FROM Tools IMPORT String;
FROM Lex   IMPORT TokenType;

EXPORT QUALIFIED
    (* TYPE *)  PtrToPicElement, 
    (* VAR  *)  PicADTDebug    ,
    (* PROC *)  INDimSet   , INDirSubSet, INCompassSet, INBPrimSet, INColorSet,
                DefDimValue, FindElement, CurElement, GetCompassLoc,
                LabElement , Setdashed  , Setdotted , Setchop      ,
                Setinvisible,Setsame    , Setht     , Setwidth     ,
                SetRotation, Setrad     , Setmajax   , Setminax  , Setfrom,
                Setto       , Setat      , SetCompassat, MoveThisWay,
                SetArrowType, SetText    , SetColor, SetLocation, CreateEnode ,
                SetDefDirection, SetDefDimension, SetPicOrigin,
                ChainCurrentElement      , MoveToLocation     ,
                WrapUpPassOne,
                PrintChain, DrawPictures;
                
TYPE PtrToPicElement;  (* HIDDEN in implementation *)
TYPE CompSubRange = [ bottom..west ];
VAR
     PicADTDebug : BOOLEAN;

PROCEDURE INDimSet( dim : TokenType (* in *) ) : BOOLEAN;
      (*
      returns true if dim is in [ arrowlen..rad ]
      *)

PROCEDURE INDirSubSet( dir : TokenType (* in *) ) : BOOLEAN;
      (*
      returns true if dir is in [ up..upright ]
      *)

PROCEDURE INCompassSet( comp : TokenType (* in *) ) : BOOLEAN;
      (*
      returns true if comp  is in [ bottom..west ]
      *)

PROCEDURE INBPrimSet( bp : TokenType (* in *) ) : BOOLEAN;
      (*
      returns true if bp is in [ box..spline ]
      *)
PROCEDURE INColorSet( col : TokenType (* in *) ) : BOOLEAN;
      (*
      returns true if col is in [ black..white ]
      *)

PROCEDURE SetDefDirection(
    Dir : TokenType (* in *) );
    (*
    By default, the pic elements will be generated along the direction
    specified by "Dir".
    *)
PROCEDURE SetDefDimension(
    Dim   : TokenType (* in *);
    Value : REAL      (* in *) );
    (*
    Set the value of the default dimension specified by "Dim" to
    "value"
    *)
PROCEDURE SetPicOrigin(
    X : REAL (* in *);
    Y : REAL (* in *) );
    (*
    The point of origin for PIC is recorded.
    *)
PROCEDURE DefDimValue(
    DefDim : TokenType (* in *) ): REAL;
    (*
    THis FUNCTION returns the value of the specified Default Dimension
    e.g, circlerad, arrowlen, boxht etc.
    *)
PROCEDURE FindElement(
    BasPrimitive : TokenType (* in *);
    PrimCount    : INTEGER   (* in *);
    VAR Found        : BOOLEAN   (* out *);
    VAR Enode        : PtrToPicElement (* out *) );
    (*
    This procedure looks ups "BasPrimitive" in the chain of picture
    elements of the same type as the "BasPrimitive". "PrimCount" indicates
    which one to target. Thus PrimCount = 4 and BasPrimitive = box means
    look up to see if there are 4 or more boxes in the chain of boxes so
    far specified in the PIC program commands. If there are, "Enode" is
    set to point to the fourth box and "Found" is set TRUE. A negative
    "PrimCount" means that the chain is to be searched starting at the last
    last basic primitive in the chain which would be the case for a construct
    like "fourth last box".
    *)
PROCEDURE CurElement( ) : PtrToPicElement;
    (*
    returns pointer to the current PIC element being processed. Every
    new PIC element becomes the current element until a new element
    is created.
    *)
PROCEDURE GetCompassLoc(
        E : PtrToPicElement (* in *);
        Cp: CompSubRange    (* in *);
    VAR X     : REAL            (* out *);
    VAR Y     : REAL            (* out *) );
    (*
    This procedure returns the coordinates of the compass point specified
    by "Cp" of the picture element pointed to by "E".
    *)
PROCEDURE LabElement(
        Lab    : String          (* in  *);
    VAR Enode  : PtrToPicElement (* out *);
    VAR Found  : BOOLEAN         (* out *)  );
    (*
    This procedure looks through the entire database of PIC elements to
    find an element or location that carries the label "Lab". If found,
    "Enode" is set to point to it and "Found" is set TRUE.
    *)
PROCEDURE Setdashed(
    VAR Enode : PtrToPicElement (* in/out *) );
    (*
    The element pointed to by "Enode" is to be drawn with dashed lines.
    *)
PROCEDURE Setdotted(
    VAR Enode : PtrToPicElement (* in/out *) );
    (*
    The element pointed to by "Enode" is to be drawn with dotted lines.
    *)
PROCEDURE Setchop(
    VAR Enode   : PtrToPicElement (* in/out *);
        ChopAmt : REAL            (* in *)     );
    (*
    When drawing lines and arrows, chop the length by "ChopAmt".
    This would come in handy for fine tunning lines etc.
    Makes sense for lines and arrows only.
    *)
PROCEDURE Setinvisible(
    VAR Enode : PtrToPicElement (* in/out *) );
    (*
    The element pointed to by "Enode" is to be drawn with invisible lines.
    *)
PROCEDURE Setsame(
    VAR Enode : PtrToPicElement (* in/out *) );
    (*
    Use the same dimensions as the last pic element for the element pointed
    to by "Enode". Enode must be pointing to the current element.
    The last and this element better be of same type otherwise
    Default dimensions would be set for generating "Enode". Makes sense for
    boxes, ellispes and circles only.
    *)
PROCEDURE Setht(
    VAR Enode : PtrToPicElement (* in/out *);
        Value : REAL            (* in *)     );
    (*
    Sets the BOX ht to "Value", for other types of basic primitives, ht
    doesnot make sense.
    *)
PROCEDURE Setwidth(
    VAR Enode : PtrToPicElement (* in/out *);
        Value : REAL            (* in *)     );
    (*
    Sets the BOX width to "Value", for other types of basic primitives, width
    doesnot make sense.
    *)
PROCEDURE Setrad(
    VAR Enode : PtrToPicElement (* in/out *);
        Value : REAL            (* in *)     );
    (*
    Sets CIRCLE and ARC radius to "Value", for other types of basic 
    primitives, radius doesnot make sense.
    *)
PROCEDURE SetRotation(
    VAR Enode : PtrToPicElement (* in/out *);
        wise  : TokenType       (* in *)     );
    (*
    For ARC only. Sets the rotation to clockwise or anticlockwise.
    *)
PROCEDURE Setmajax(
    VAR Enode : PtrToPicElement (* in/out *);
        Value : REAL            (* in *)     );
    (*
    Sets ELLIPSE major axis to "Value", for other types of basic primitives,
    major axis doesnot make sense.
    *)
PROCEDURE Setminax(
    VAR Enode : PtrToPicElement (* in/out *);
        Value : REAL            (* in *)     );
    (*
    Sets ELLIPSE minor axis to "Value", for other types of basic primitives,
    minor axis doesnot make sense.
    *)
PROCEDURE Setfrom(
    VAR Enode : PtrToPicElement (* in/out *);
        X     : REAL            (* in *)    ;
        Y     : REAL            (* in *)     );
    (*
    For LINES, ARROWS, ARCS and SPLINES, whichever Enode points to, the
    point of origin is set to coordinates X,Y. For other primitives, this
    would not make any sense.
    *)
PROCEDURE Setto(
    VAR Enode : PtrToPicElement (* in/out *);
        X     : REAL            (* in *)    ;
        Y     : REAL            (* in *)     );
    (*
    For LINES, ARROWS, ARCS and SPLINES, whichever Enode points to, the
    point of destination is set to coordinates X,Y. For other primitives, this
    would not make any sense.
    *)
PROCEDURE Setat(
    VAR Enode : PtrToPicElement (* in/out *);
        X     : REAL            (* in *)    ;
        Y     : REAL            (* in *)     );
    (*
    For BOXES, CIRCLES, ELLIPSES, whichever Enode points to, the CENTER of
    primitive is set at coordinates (X,Y). For other primitives, this
    would not make any sense.
    *)
PROCEDURE SetCompassat(
    VAR Enode : PtrToPicElement (* in/out *);
        Cp    : CompSubRange    (* in *)    ;
        X     : REAL            (* in *)    ;
        Y     : REAL            (* in *)     );
    (*
    For BOXES, CIRCLES, ELLIPSES, whichever Enode points to, the Compass point
    specified by "Cp" primitive is set at coordinates (X,Y). 
    Notice that this would make the CENTER of the object and all other compass
    points relocate. For other primitives, this would not make any sense.
    *)
PROCEDURE MoveThisWay(
    VAR Enode    : PtrToPicElement (* in/out *);
        WhichWay : TokenType       (* in *);
        dist     : REAL            (* in *);
        X        : REAL            (* in *);
        Y        : REAL            (* in *)  );
    (*
    For LINES and ARROWS, whichever Enode points to, the DIRECTION of motion
    is set to "WhichWay" which would be right, left, up, down, downright etc.
    Notice that setting the direction of motion would affect the destination.
    If the previous destination was in a different direction, the new destin-
    ation will be computed and the LENGTH of the arrow or line will set to the
    the distance "dist" or the default length if dist=0.
        For SPLINES, the point "dist" away in the direction "whichway" would
    become one of the GUIDEPOINTS.
        The motion id the direction "whichway" could be followed by the starting
    point, e.g "arrow up from top of last box", in which case the start would
    be set to what "X,Y" contain. Negative X will indicate that
    the start point was not specified.
        For other primitives, this would not make any sense.
    *)
PROCEDURE SetArrowType(
    VAR Enode     : PtrToPicElement (* in/out *);
        WhichType : TokenType       (* in *)     );
    (*
    WhichType can be LeftArrow, RightArrow or TwoWayArrow. The type of arrow
    is recorded. This attribute makes sense for ARROW and ARC only.
    *)
PROCEDURE SetText(
    VAR Enode      : PtrToPicElement (* in/out *);
        TextString : String (* in *)         );
    (*
    If number of text strings for the primitives has not been exceeded, this
    text string will be associated for later display with the PIC element
    pointed to by ENode.
    *)
PROCEDURE SetColor(
    VAR Enode : PtrToPicElement (* in/out *);
        EColor: TokenType       (* in *)     );
    (*
    Set the color with shich the elment will be drawn.
    Colors can be black, red, cyan, magenta, green, blue, orange, yellow,
    white.
    *)
PROCEDURE SetLocation(
    VAR Enode : PtrToPicElement (* in/out *);
        X     : REAL            (* in *)    ;
        Y     : REAL            (* in *)     );
    (*
    This procedure will set the coordinates of the CENTER of primitive
    pointed to by Enode to take on the values (X,Y). This would probably
    be used to associate coordinates with a LABEL.
    *)
PROCEDURE MoveToLocation(
    X   : REAL (* in *);
    Y   : REAL (* in *) );
    (*
    The current cursor, or pen location ( most probably the center of
    a primitive ) will be set to (X,Y). The next primitive generated will
    use this location as reference to determine its location.
    *)
PROCEDURE ChainCurrentElement( );
    (*
    This procedure inserts the current element into the chain of
    pic elements. It sets all the pointers. The very first elements
    is treated as a special case.
    *)
PROCEDURE CreateEnode(
    EType          : TokenType (* in *);
    LabelText      : String  (* in *) ): PtrToPicElement;
    (*
    This procedure creates a new entry for the element specified by
    EType which can be one of the basic element types or a "Label" in
    which case the element is simply a labelled location. After the
    element node is created, the label text is recorded if the elemnt
    was preceded by a label in the original PIC command. Then all
    the dimensions are set to default depending on what type of
    an element this is. For example, for a box, the ht and width
    would be set to default. The origin will be set according to
    the current default direction of movement and the current location
    of the cursor or pen. A pointer to this newly created node is returned
    as the function value.
    *)
PROCEDURE WrapUpPassOne( );
    (*
    If there is any element waiting to chained, it is put in the chain.
    *)
PROCEDURE PrintChain( );
    (*
    Prints elements in all the PicChains.
    *)

PROCEDURE DrawPictures( );
    (*
    Draws all the pictures in the pic chains. The device must have been
    initialized.
    *)
 
END PicADT.
