############################################################################
# 
#	File:     pme.icn
# 
#	Subject:  Program to edit pixmaps
# 
#	Author:   Clinton L. Jeffery
#
#	Date:     April 30, 2001
# 
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#	Version:  2.0
#
############################################################################
#
#     A (color) pixmap editor.
#
#     Left, middle, and right buttons draw different colors.
# Press q or ESC to quit; press s to save.  Capital "S" prompts for
# and saves under a new filename.
# Click on the little picture of the mouse to change one of the
# button's colors.  Not very interesting on a monochrome server.
#
############################################################################
#
#  Requires:  Version 9 graphics
#
############################################################################
#
#  Links:  wopen, xcompat
#
############################################################################

link wopen
link xcompat
global w, WIDTH, HEIGHT, XBM, LMARGIN
global colors, colorbinds

procedure main(argv)
   local i, f, s, xpos, ypos, i8, j, j8, j8Plus, e, x, y
   colors := [ "red", "green", "blue" ]
   i := 1
   XBM := ".xpm"
   WIDTH  := 32
   HEIGHT := 32
   if *argv>0 & argv[1][1:5]=="-geo" then {
      i +:= 1
      if *argv>1 then argv[2] ? {
	 WIDTH := integer(tab(many(&digits))) | stop("geo syntax")
	 ="x" | stop("geo syntax")
	 HEIGHT := integer(tab(0)) | stop("geo syntax")
	 i +:= 1
	 }
      }
   LMARGIN := WIDTH
   if LMARGIN < 65 then LMARGIN := 65
   if (*argv >= i) &
      (f := open(s := (argv[i] | (argv[i]||(XBM|".xbm"))))) then {
	close(f)
	w := &window := WOpen("label=PixMap", "image="||s, "cursor=off") |
	   stop("cannot open window")
	WIDTH  <:= WAttrib(w, "width")
	HEIGHT <:= WAttrib(w, "height")
	LMARGIN := WIDTH
	if LMARGIN < 65 then LMARGIN := 65
	pos := WAttrib("pos")
	pos ? {
	   xpos := tab(many(&digits)) | stop(image(pos))
	   =","
	   ypos := tab(0)
	   }
	WAttrib(w, "posx="||xpos, "posy="||ypos,
		"width="||(WIDTH*8+LMARGIN+5), "height="||(HEIGHT*8))
	Event()
	every i := 0 to HEIGHT-1 do {
	   i8 := i*8
	   every j := 0 to WIDTH-1 do {
	      j8 := j*8
	      j8Plus := j8 + LMARGIN + 5
	      CopyArea(w, w, j, i, 1, 1, j8Plus,   i8)
	      CopyArea(w, w, j, i, 1, 1, j8Plus+1, i8)
	      CopyArea(w, w, j8Plus, i8, 2, 1, j8Plus+2,i8)
	      CopyArea(w, w, j8Plus, i8, 4, 1, j8Plus+4, i8)
	      CopyArea(w, w, j8Plus, i8, 8, 1, j8Plus, i8+1)
	      CopyArea(w, w, j8Plus, i8, 8, 2, j8Plus, i8+2)
	      CopyArea(w, w, j8Plus, i8, 8, 4, j8Plus, i8+4)
	      }
	   }
	} else {
	   w := &window := WOpen("label=PixMap", "cursor=off",
				"width="||(LMARGIN+WIDTH*8+5),
				"height="||(HEIGHT*8+5)) |
             stop("cannot open window")
	   }

   colorbinds := [ XBind(w,"fg="||colors[1]),
		  XBind(w,"fg="||colors[2]),
		  XBind(w,"fg="||colors[3]) ]
   every i := 1 to 3 do {
      XDrawArc( 4+i*10, HEIGHT+68, 7, 22)
      XFillArc(colorbinds[i], 5+i*10, HEIGHT+70, 5, 20)
      }
   DrawRectangle( 5, HEIGHT+55, 45, 60)
   DrawRectangle( 25, HEIGHT+50, 5, 5)
   DrawCurve(27, HEIGHT+50,
	      27, HEIGHT+47,
	      15, HEIGHT+39,
	      40, HEIGHT+20,
	      25, HEIGHT+5)

   Fg( "black")
   every i := 0 to HEIGHT-1 do
      every j := 0 to WIDTH-1 do
         DrawRectangle( j*8+LMARGIN+5, i*8, 8, 8)

   DrawLine( 0, HEIGHT, WIDTH, HEIGHT, WIDTH, 0)

  repeat {
     case e := Event(w) of {
	"q"|"\e": return
	"s"|"S": {
	   if /s | (e=="S") then s := getfilename()
	   write("saving image ", s, " with width ", image(WIDTH),
		 " height ", image(HEIGHT))
	   WriteImage( s, 0, 0, WIDTH, HEIGHT)
	   }
	&lpress | &ldrag | &mpress | &mdrag | &rpress | &rdrag : {

	   x := (&x - LMARGIN - 5) / 8
	   y := &y / 8

	   if (y < 0) | (y > HEIGHT-1) | (x > WIDTH) then next
	   if (x < 0) then {
	      if &x < 21 then getacolor(1, "left")
	      else if &x < 31 then getacolor(2, "middle")
	      else getacolor(3, "right")
	      until Event(w) === (&mrelease | &lrelease | &rrelease)
	      }
	   else dot(x, y, (-e-1)%3)
	   }
	}
     }
end

procedure getacolor(n, s)
   local wtmp, theColor
   wtmp := WOpen("label=" || image(s||" button: "), "lines=1") |
      stop("can't open temp window")
   writes(wtmp,"[",colors[n],"] ")
   theColor := read(wtmp) | stop("read fails")
   close(wtmp)
   wtmp := colorbinds[n] | stop("colorbinds[n] fails")
   Fg(wtmp, theColor) | write("XFG(", theColor, ") fails")
   XFillArc(wtmp, 5+n*10, HEIGHT+70, 5, 20)
   colors[n] := theColor
end

procedure dot(x, y, color)
   if (x|y) < 0 then fail
   FillRectangle(colorbinds[color+1], x*8+LMARGIN+5, y*8, 8, 8)
   DrawPoint(colorbinds[color+1], x, y)
   DrawRectangle( x*8+LMARGIN+5, y*8, 8, 8)
end

procedure getfilename()
   local s, pos, wprompt, rv
   pos := "pos="
   every s := QueryPointer() do pos||:= (s-10)||","
   wprompt := WOpen("label=Enter a filename to save the pixmap",
		   "font=12x24", "lines=1", pos[1:-1]) | stop("can't xprompt")
   rv := read(wprompt)
   close(wprompt)
   if not find(XBM, rv) then rv ||:= XBM
   return rv
end
