unit NuGraph;

interface

type
  TTextAlignment = (TxA_Left, TxA_Center, TxA_Right);

  PNGWindow = ^TNGWindow;

  TNGWindow = object(TWindow)
    { Client-visible state: }
    color: TColorRef;
    hAlign: TTextAlignment;
    vAlign: TTextalignment;

    { Drawing methods: }
    procedure Dot(x, y: integer);
    procedure Line(x0, y0, x1, y1: integer);
    procedure Rectangle(x0, y0, x1, y1: integer);
    procedure Triangle(x0, y0, x1, y1, x2, y2: integer);
    procedure Text(x, y: integer; text: string);
  end;

implementation

uses
  WinTypes, WinProcs, WObjects, Strings;

{--------------- Display List ------------}

type
  ElementKind = (EK_Dot, EK_Line, EK_Rect, EK_Tri, EK_Text);

  PNGElement = ^TNGElement;

  PNGText = ^TNGText;

  TNGElement = record
    next: PNuGraphElement;
    case kind: ElementKind of
    EK_Dot:
      ( dot: record
          color: TColorRef;
          x, y: integer;
        end;
      );
    EK_Line:
      ( line: record
          color: TColorRef;
          x0, y0, x1, y1: integer;
        end;
      );
    EK_Rect:
      ( rect: record
          color: TColorRef;
          x0, y0, x1, y1: integer
        end;
      );
    EK_Tri:
      ( tri: record
          color: TColorRef;
          x0, y0, x1, y1, x2, y2: integer;
        end;
      );
    EK_Text:
      ( text: record
          color: TColorRef;
          x, y: integer;
          hAlign, vAlign: TTextAlignment;
          text: PNGText;
        end;
      );
  end;

  TNGText = record
    s: string[63]
  end;

  PNGImpWindow = ^TNGImpWindow;

  TNGImpWindow = object(TNGWindow)

    { Display list: }
    fst, lst: PNuGraphElement;

    { Internal methods: }
    constructor Init(AParent: PWindowsObject; Title: PChar);
    procedure ClearWindow(DC: HDC);
    procedure PaintElement(DC: HDC; el: PNuGraphElement);

    { Windows methods: }
    procedure GetWindowClass(var WndClass: TWndClass); virtual;
    procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
    procedure SetUpWindow; virtual;
    procedure WMDestroy(var Message: TMessage); virtual wm_Destroy;
    procedure WMLButtonDown(var Message: TMessage); virtual wm_LButtonDown;
    procedure WMLButtonUp(var Message: TMessage); virtual wm_LButtonUp;
    procedure WMTimer(var Message: TMessage); virtual wm_Timer + wm_First;
    procedure WMSize(var Message: TMessage); virtual wm_Size;
  end;

  TApp = object(TApplication)
    procedure InitMainWindow; virtual;
  end;

{--------------- Plain procedures ------------}

{--------------- TNuGraphWindow -----------------}

constructor TNuGraphWindow.Init(AParent: PWindowsObject; Title: PChar);
  begin
    TWindow.Init(AParent, Title);
    color := RGB(255, 255, 255);
    hAlign := HTA_Left;
    vAlign := VTA_Bottom;
    KillAllDrops;
    fst := nil; lst := nil;
    Attr.Style := WS_Caption or WS_SysMenu or WS_MinimizeBox;
  end;

procedure TNGImplWindow.ClearWindow(DC: HDC);
  var
    oldBrush, newBrush: HBrush;
  begin
    newBrush := GetStockObject(White_brush);
    oldBrush := SelectObject(DC, newBrush);
    Rectangle(DC, 0, 0, WWidth, WHeight);
    SelectObject(DC, oldBrush);
  end;

procedure TNGImplWindow.PaintElement(DC: HDC; var el: TNGElement);
  var
    oldPen: HPen;
  begin
    if d.active
    and (d.ax <> -1) and (d.ay <> -1)
    and (d.bx <> -1) and (d.by <> -1) then
      begin
        oldPen := SelectObject(DC, t.paintPen);
        MoveTo(DC, d.ax, d.ay);
        LineTo(DC, d.bx, d.by);

        SelectObject(DC, oldPen);
        DeleteObject(paintPen)
      end;
  end;

procedure TNGImplWindow.GetWindowClass(var WndClass: TWndClass);
  begin
    TWindow.GetWindowClass(WndClass);
    WndClass.Style := 0;
    WndClass.hbrBackGround := GetStockObject(Black_Brush);
    WndClass.lpszMenuName := 'Menu';
    WndClass.hIcon := LoadIcon(hInstance, 'MainIcon');
  end;

procedure TNGImplWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
  var p: PNGElement;
  begin
    ClearWindow(PaintDC);
    p:= fst;
    while p # nil do
      PaintElement(PaintDC, p^);
      p := p^.next
    end;
  end;

procedure TNGImplWindow.WMDestroy(var Message: TMessage);
  var p, q: PNGElement;;
  begin
    KillTimer(HWindow, 1);
    TWindow.WMDestroy(Message);
    p := fst; fst := nil; lst := nil;
    while p # nil do
      q := p^.next;
      DeleteElement(p);
      p := q
    end
  end;

procedure TNGImplWindow.WMLButtonDown(var Message: TMessage);
  var
    Point: TPoint;
  begin
    Point.X := LoWord(Message.lParam);
    Point.Y := HiWord(Message.lParam);
    MessageBeep(0);
  end;

procedure TNGImplWindow.WMLButtonUp(var Message: TMessage);
  var
    Point: TPoint;
  begin
    Point.X := LoWord(Message.lParam);
    Point.Y := HiWord(Message.lParam);
    MessageBeep(0);
  end;

procedure TNGImplWindow.WMSize(var Message: TMessage);
  begin
    if IsIconic(HWindow) then
      KillTimer(HWindow, 1)
    else
      if SetTimer(HWindow, 1, trunc(1000*DeltaT), nil) = 0 then
        begin
	  MessageBox(HWindow, 'No Timers Left', 'Error', mb_Ok);
	  Halt(1);
        end;
    end;

procedure TNGImplWindow.WMTimer(var Message: TMessage);
  var
    DC: HDC;
    i: integer;
    nStarted: integer;
  begin
    DC := GetDC(HWindow);
    nStarted := 0;
    for i := 0 to NDrops-1 do
      StepDrop(DC, drop[i], tap[drop[i].tap], nStarted);
    ReleaseDC(HWindow, DC);
  end;

{--------------- TApp ------------------------}

procedure TApp.InitMainWindow;
begin
  MainWindow := New(PNGImplWindow, Init(nil, '>Squirt<'));
end;

{-------------Main Program--------------------}

var
  App: TApp;
begin
  App.Init('UrkGame');
  App.Run;
  App.Done;
end.

procedure SetFillStyle(style: FillStyle; color: integer);
  begin
    curFillStyle := style;
    curFillColor := color
  end;

procedure SetColor(color: integer);
  begin
    curColor := color
  end;

procedure SetTextJustify(hjust, vjust: TextJustfication);
  begin
    curHJust := hjust;
    curVJust := vjust
  end;

procedure Rectangle(x0, y0, x1, y1: integer);
  begin


procedure Line(x0, y0, x1, y1: integer);

procedure OutTextXY(x, y: integer; text: string);

end.
