// Window.bcpl -- a BCPL package to select areas on the display
//		screen.
//		A window is defined by an "origin" (upper left corner) and
//		a "corner" (lower right corner).  See Menu package


get "MenuDefs.d"


external		// incoming OS statics and procedures
	[
	lvCursorLink
	MoveBlock
	Zero
	]





let SelectWindow(box) = valof SMCWindow(box,4)		// left key


and MoveWindow(box) = valof SMCWindow(box,1)	// middle key


and ChangeWindow(box) = valof SMCWindow(box,2)	// right key





and SMCWindow(box,key;numargs na) = valof
	[
	// returns false if nothing happens
	// returns true if box is selected or moved or changed

	// default case
	if box eq 0 then resultis false
	if na ls 2 then resultis false

	// check consistency of dcb
	let dcb=box>>BOX.dcb
	if dcb eq 0 then dcb=@#420
	if dcb eq 0 then resultis false
	if (16*(dcb>>DCB.width) ls 606) % (dcb>>DCB.height ls 404) then resultis false
	box>>BOX.dcb=dcb

	// define and check out the incoming box dimensions
	let width=box>>BOX.xcorner-box>>BOX.xorigin+1
	let height=box>>BOX.ycorner-box>>BOX.yorigin+1
	if (width le 1)%(height le 1)%(width gr 606)%(height gr 808) resultis false

	// define variables
	let newkey=(not @#177030) & #377
	if (newkey & key) eq 0 then resultis false
	let x1,y1,x2,y2,x3,y3=nil,nil,nil,nil,nil,nil
	let Xo,Xc,Yo,Yc=nil,nil,nil,nil

	// setup initial conditions
	switchon key into
		[
		case 4:
			x1=@#424 ; y1=@#425
			if x1 ls 0 then x1=0 ; if y1 ls 0 then y1=0
			if x1 gr 605 then x1=605 ; if y1 gr 807 then y1=807
			x2=x1 ; y2=y1
			box>>BOX.xorigin=x1 ; box>>BOX.yorigin=y1
			box>>BOX.xcorner=x2 ; box>>BOX.ycorner=y2
			endcase
		case 2:
		case 1:
			x1=box>>BOX.xorigin ; y1=box>>BOX.yorigin
			x2=box>>BOX.xcorner ; y2=box>>BOX.ycorner
			@#424=x2 ; @#425=y2
			endcase
		]

	// major loop looking for window
	@lvCursorLink=false
	[
	// check if still holding key
	newkey=(not @#177030) & #377
	if (key & newkey) eq 0 then		// let go of key
		[
		@lvCursorLink=true
		resultis (x1 ne x2) & (y1 ne y2)
		]

	// get new position
	x3=@#424 ; y3=@#425
	if x3 ls 0 then x3=0 ; if y3 ls 0 then y3=0
	if x3 gr 605 then x3=605 ; if y3 gr 807 then y3=807
	@#424=x3 ; @#425=y3
	@#426=x3 ; @#427=y3
	if (x3 eq x2) & (y3 eq y2) then loop

	// rubout old box
	test x2 gr x1 ifso [ Xo=x1 ; Xc=x2 ] ifnot [ Xo=x2 ; Xc=x1 ]
	test y2 gr y1 ifso [ Yo=y1 ; Yc=y2 ] ifnot [ Yo=y2 ; Yc=y1 ]
	box>>BOX.xorigin=Xo
	box>>BOX.yorigin=Yo
	box>>BOX.xcorner=Xc
	box>>BOX.ycorner=Yc
	OutlineBox(box)

	// check sides of display
	if key eq 1 then
		[
		x1=x3-width+1 ; y1=y3-height+1
		if x1 ls 0 then [ x3=x3-x1 ; @#424=x3 ; @#426=x3 ; x1=0 ]
		if y1 ls 0 then [ y3=y3-y1 ; @#425=y3 ; @#427=y3 ; y1=0 ]
		]

	// put in new box
	test x3 gr x1 ifso [ Xo=x1 ; Xc=x3 ] ifnot [ Xo=x3 ; Xc=x1 ]
	test y3 gr y1 ifso [ Yo=y1 ; Yc=y3 ] ifnot [ Yo=y3 ; Yc=y1 ]
	box>>BOX.xorigin=Xo
	box>>BOX.yorigin=Yo
	box>>BOX.xcorner=Xc
	box>>BOX.ycorner=Yc
	OutlineBox(box)

	// now loop back to beginning
	x2=x3 ; y2=y3

	] repeat

	]