# A rough Ruby translation of the `basicwin' program from:
#	Xlib Programming Manual, O'Reilly, 1988
#	on pages 77-82 (of third print)
# However I translated it from Stephen McCamant's Perl translation.

$progname = ENV["RESOURCE_NAME"] || $0.sub(%r{^.*/}, '')

require "X11/Display"
$d = X11::Display.new

$s = $d.screens[0]
$dp = $s.depths.find {|dp| dp.depth > 1 }

$ddim = $s.size_in_pixels
$wdim = X11::Size[$ddim.x/2,$ddim.y/3]

$w = X11::Window.new($d)
$w.create_window(
	$dp.depth, $s.root,
	X11::Rectangle[X11::Point[0,0], $wdim],
	4, :InputOutput, :CopyFromParent,
	X11::WindowAttributes.new(
		:background_pixel => $s.white_pixel,
		:bit_gravity => :Static,
		:event_mask =>
			X11::EventMask.lookup(
				:Exposure, :KeyPress,
				:ButtonPress, :StructureNotify)))

props = [
	["WM_ICON_NAME","STRING","basicwin"],
	["WM_NAME","STRING","Basic Window Program"],
	["WM_NORMAL_HINTS","WM_SIZE_HINTS",[4|8|16,320,200].pack "Ix16IIx44"],
	["WM_HINTS","WM_HINTS",[1|2,1,1].pack "IIIx24"],
	["WM_CLASS","STRING", [$progname,"Basicwin"].join "\0"],
]

$d.atoms(*props.map {|name,kind| [name,kind] }.flatten)

props.each {|name,kind,value|
	$w.change_property(:Replace, $d.atom(name), $d.atom(kind), 8, value)
}

($font = X11::Font.new $d).open("9x15")
$font_info = $font.query


$gc = X11::Graphics.new $d

$gc.create $w, X11::GraphicsInfo.new(
	:font => $font,
	:foreground => $s.black_pixel,
	:line_width => 6,
	:line_style => :OnOffDash,
	:cap_style => :Round,
	:join_style => :Round)

$gc.set_dashes 0,[12,24]
$gd = X11::GraphicsOnDrawable[$w,$gc]
$w.map

def text_width(text)
	$font.query_text_extents(text).overall_width
end

def place_text
	x = $wdim.x / 4
	fh = $font_info.font_ascent + $font_info.font_descent
	y1 = 0
	y2 = $wdim.y/2 - fh - $font_info.font_descent
	y3 = $wdim.y
	[
		[:c,y1+1*fh,"Hi! I'm a window, who are you?"],
		[:c,y3-2*fh,"To terminate program, press any key"],
		[:c,y3-1*fh,"or button while in this window"],
		[ x,y2+0*fh,"Screen Dimensions:"],
		[ x,y2+1*fh," Height - #{$s.size_in_pixels.x} pixels"],
		[ x,y2+2*fh," Width  - #{$s.size_in_pixels.y} pixels"],
		[ x,y2+3*fh," Depth  - #{$s.root_depth      } plane(s)"],
	].each {|x,y,text|
		x = ($wdim.x-text_width(text))/2 if x==:c
		$gd.draw_strings(X11::Point[x,y],[X11::TextItem8[text,0]])
	}
end

def place_graphics
	dim = X11::Size[ $wdim.x*3/4, $wdim.y/2 ]
	pos = ($wdim - dim) / 2
	pos = X11::Point[0,0] + pos # typecast
	$gd.draw_rectangles([X11::Rectangle[pos,dim]])
end

def too_small
	$gd.draw_strings(
		X11::Point[2, $font_info.font_ascent],
		[X11::TextItem8["Too Small",0]])
end

def handle_event e
	case e
	when X11::ExposeEvent
		return unless e.count == 0
		$is_drawn = false

	when X11::ConfigureNotifyEvent
		$wdim = e.rectangle.size
		$is_too_small = $wdim.x < 320 || $wdim.y < 200
		$w.clear_area(true,X11::Rectangle[X11::Point[0,0],$wdim])
		$is_drawn = false

	when X11::ButtonPressEvent, X11::KeyPressEvent
		exit
	else
		puts "Unknown Event Type"
	end
end

while true
	while e = $d.next_event; p e; handle_event e; end
	if not $is_drawn then
		if $is_too_small then
			too_small
		else
			place_text
			place_graphics
		end
		$is_drawn = true
	end
	$d.flush
	$d.xreceive if IO.select [$d.sock],[],[],0
end
