(***********)
(* Graphic *)
(***********)

datatype colour = rgb of int * int * int;

val black   = rgb(0,0,0);
val red     = rgb(255,0,0);
val green   = rgb(0,255,0);
val blue    = rgb(0,0,255);
val yellow  = rgb(255,255,0);
val cyan    = rgb(0,255,255);
val magenta = rgb(255,0,255);
val white   = rgb(255,255,255);

abstype picture
   = a000 of real
   | a001 of real
   | a002 of colour * picture
   | a003 of real * picture
   | a004 of real * picture
   | a005 of real * picture
   | a006 of real * real * picture
   | a007 of picture * picture
   | a008 of int
   | a009 of int
   | a010 of real
with
  nonfix convertToPicture 154 1;
  fun convertToPicture(x:picture):picture = convertToPicture x;
  fun circle r      = convertToPicture(a000 r);       (* circle: radius r, origin at centre *)
  fun square x      = convertToPicture(a001 x);       (* square: side x, origin in middle *)
  fun paint(c, p)   = convertToPicture(a002(c, p));   (* force colour of entire sub-object *)
  fun scale(r, p)   = convertToPicture(a003(r, p));   (* multiply size of ofject by r *)
  fun scalex(r, p)  = convertToPicture(a004(r, p));   (* multiply size in x direction only *)
  fun rotate(a, p)  = convertToPicture(a005(a, p));   (* rotate a (degrees, clockwise) *)
  fun shift(x, y, p)= convertToPicture(a006(x, y, p));(* translate object by (x, y) *)
  fun add(p1, p2)   = convertToPicture(a007(p1, p2)); (* form composite picture *)
  val nullpic       = convertToPicture(a008(0));      (* a null image *)
  val point         = convertToPicture(a009(0));      (* an isolated point *)
  fun line(z)       = convertToPicture(a010(z));      (* horizontal line, length z, centred *)
end;

