-- TARenderImpl.mesa
-- Rick Beach, July 2, 1982 11:45 am
-- Michael Plass, July 20, 1982 1:45 pm
-- Maureen Stone November 22, 1982 2:54 pm

DIRECTORY
 NodeStyle USING [ApplyAll, Create, GetAreaBrightness, GetAreaHue, GetAreaSaturation, GetOutlineBrightness, GetOutlineHue, GetOutlineSaturation, GetPathType, OfStyle, Ref],
 Rope,
 TACaption USING [DisplayText],
 TAPen USING [EstablishPen],
 TAPrivate,
 TAProperties USING [AnArtworkNode, AnArtworkFileName, AnArtworkImage, AnArtworkPath],
 TARender,
 TAShadow USING [EstablishShadow],
 TAStyle,
 TEditInput USING [FreeTree],
 TextEdit USING [GetRope],
 TextNode USING [Forward, NarrowToTextNode, Ref],
 TSOutput USING [Handle];

TARenderImpl: PROGRAM
IMPORTS NodeStyle, TACaption, TAPen, TAPrivate, TAProperties, TAShadow, TAStyle, TEditInput, TextEdit, TextNode
EXPORTS TARender = {

ROPE: TYPE = Rope.ROPE;

NotATiogaArtworkDocument: PUBLIC SIGNAL[fileName: ROPE] = CODE;
NotATiogaArtworkNode: PUBLIC SIGNAL = CODE;
NoJaMGraphicsViewer: SIGNAL = CODE;
DocumentNotFound: PUBLIC SIGNAL[fileName: ROPE] = CODE;

RenderDocument: PUBLIC PROCEDURE [handle: TSOutput.Handle, fileName: ROPE, paint: BOOLEANTRUE] = {
 tiogaRoot: TextNode.Ref;
 nodeStyle: NodeStyle.Ref ← NodeStyle.Create[];
 fromFile: BOOLEAN;
 fileName ← TAPrivate.FixFileName[fileName, ".Artwork"];
 [tiogaRoot, fromFile] ← TAPrivate.GetDocument[fileName !
  TAPrivate.FileNotFound => GOTO BadFile];
 RenderBranch[handle, tiogaRoot, nodeStyle, screen, paint !
  NotATiogaArtworkNode => GOTO NotArtwork];
IF fromFile THEN TEditInput.FreeTree[tiogaRoot];
EXITS
  BadFile => SIGNAL DocumentNotFound[fileName];
  NotArtwork => SIGNAL NotATiogaArtworkDocument[fileName];
 };

RenderBranch: PUBLIC PROCEDURE [handle: TSOutput.Handle, node: TextNode.Ref, nodeStyle: NodeStyle.Ref, kind: NodeStyle.OfStyle, paint: BOOLEANTRUE] = {
 level, levelDelta: INTEGER ← 0;
AnyArtworkProperty: PROCEDURE[node: TextNode.Ref] RETURNS[BOOLEAN] = INLINE {
  RETURN[TAProperties.AnArtworkNode[node] OR
   TAProperties.AnArtworkFileName[node] OR
   TAProperties.AnArtworkImage[node]];
  };
IF ~AnyArtworkProperty[node] THEN SIGNAL NotATiogaArtworkNode;
WHILE node#NIL DO -- note EXIT at end of loop when finished this branch
  TAPrivate.PushDC[];
  IF TAProperties.AnArtworkNode[node] THEN
   RenderNode[handle, node, nodeStyle, kind, paint]
  ELSE IF TAProperties.AnArtworkFileName[node] THEN {
   fileName: ROPE ← TextEdit.GetRope[TextNode.NarrowToTextNode[node]];
   RenderDocument[handle, TAPrivate.FixFileName[fileName, ".Artwork"], paint] }
  ELSE
   TACaption.DisplayText[handle, node, nodeStyle, kind, paint];
  [node, levelDelta] ← TextNode.Forward[node];
  level ← level+levelDelta;
  WHILE levelDelta<=0 DO -- pop enough levels of display context
   TAPrivate.PopDC[];
   levelDelta ← levelDelta+1;
   ENDLOOP;
  IF level<=0 THEN EXIT
  ENDLOOP;
 };

RenderNode: PUBLIC PROCEDURE [handle: TSOutput.Handle, node: TextNode.Ref, nodeStyle: NodeStyle.Ref, kind: NodeStyle.OfStyle, paint: BOOLEANTRUE] = {
 NodeStyle.ApplyAll[nodeStyle, node, kind];
IF TAProperties.AnArtworkPath[node] THEN { -- interpret the pathType style
  IF TAStyle.GetShadowType[nodeStyle]#None THEN
   TAShadow.EstablishShadow[node, nodeStyle];
  SELECT NodeStyle.GetPathType[nodeStyle] FROM
   Filled, FilledAndOutlined => {
    h: REAL ← NodeStyle.GetAreaHue[nodeStyle];
    s: REAL ← NodeStyle.GetAreaSaturation[nodeStyle];
    v: REAL ← NodeStyle.GetAreaBrightness[nodeStyle];
    TAPrivate.SetHSV[h,s,v];
    TAPrivate.ExecuteNode[node];
    TAPrivate.DrawArea[];
    };
   ENDCASE;
  SELECT NodeStyle.GetPathType[nodeStyle] FROM
   Outlined, FilledAndOutlined => {
    h: REAL ← NodeStyle.GetOutlineHue[nodeStyle];
    s: REAL ← NodeStyle.GetOutlineSaturation[nodeStyle];
    v: REAL ← NodeStyle.GetOutlineBrightness[nodeStyle];
    TAPrivate.SetHSV[h,s,v];
    TAPrivate.ExecuteNode[node];
    TAPen.EstablishPen[nodeStyle];
    TAPrivate.OutlinePath[];
    };
   ENDCASE;
  }
ELSE IF TAProperties.AnArtworkImage[node] THEN { -- interpret the AIS file name
  fileName: ROPE ← TextEdit.GetRope[TextNode.NarrowToTextNode[node]];
  TAPrivate.PushReal[0];
  TAPrivate.PushReal[0];
  TAPrivate.SetCP[];
  TAPrivate.DrawImage[fileName];
  }
ELSE
  TAPrivate.ExecuteNode[node];
 };

}.