/*
 * AlignObjects.fw
 *
 * USAGE: AlignObjects.fw
 *
 * Add a powerfull function to FinalWriter
 *
 * HISTORY:
 * v1.01	added "ICONIFY"
 *
 * v1.02	aligned with the new server design v1.10
 *
 * v1.03	fixed for the Release 3 of FinalWriter
 *
 * $(C): (1994, Rocco Coluccelli, Bologna)
 * $VER: AlignObjects.fw 1.03 (07.Feb.1995)
 */

OPTIONS RESULTS

PARSE ARG oleclip
PARSE VALUE GETCLIP(oleclip) WITH jobID modID box.left box.top char.w char.h olewin oleport olehost . userport . locale config .

ADDRESS VALUE userport
SetMeasure "MICROPOINTS"

ADDRESS VALUE oleport

	align. = 0
	obj_lock = 0; lock. = GetLocale(1); lock.0 = GetLocale(2)

	/*
	 *	these remember the last kind of alignement for radio buttons
	 */
	n.horz = 0; n.vert = 0

IF OPENPORT(olehost) == NULL() THEN DO
	ERROR jobID modID 1 olehost
	SETJOB jobID 'end'
	EXIT 10
	END

st = GUIGads()
DO UNTIL st = 'end'

	CALL WAITPKT(olehost)
	pkt = GETPKT(olehost)

	IF pkt == NULL() THEN ITERATE

	PARSE VALUE GETARG(pkt) WITH cmd argv
	PARSE VALUE GETARG(pkt,1) WITH n0 .

	SELECT

		/*
		 *	align.horz = (1 left  2 center  3 right)
		 *	align.vert = (1 up    2 center  3 down)
		 */
		WHEN cmd = 'ALIGN' THEN DO
			PARSE VAR argv a1 a2 .

			IF n.a1 > 0 THEN DO
				n1 = n.a1; g_str.n1 = 0
				CALL Gadgets(2,n1)
				END

			IF n.a1 ~= n0 THEN DO
				g_str.n0 = ~g_str.n0
				CALL Gadgets(2,n0)
				END

			align.a1 = g_str.n0 * a2
			n.a1 = g_str.n0 * n0
		END

		WHEN cmd = 'START' & ~(align.vert = 0 & align.horz = 0) THEN DO
			ADDRESS VALUE userport
			CALL Gadgets(3,n0)

			IF SelectAllObj() THEN DO
				obj_lock = ExistsLockedObj()
				CALL CalcNewPos()
				CALL ReselectObj()
				CALL Gadgets(1,nundo)
				END

			CALL Gadgets(1,n0)
			ADDRESS
		END

		WHEN cmd = 'UNDO' THEN DO
			ADDRESS VALUE userport

			CALL UndoAlignObj()
			CALL ReselectObj()
			CALL Gadgets(3,nundo)

			ADDRESS
		END

		WHEN cmd = 'LOCK' THEN DO

			IF obj_lock = 0 THEN DO
				ADDRESS VALUE userport
				FirstObject 'SELECTED'
				obj_lock = result
				ADDRESS
				END

			ELSE obj_lock = 0

			g_str.nlock = lock.obj_lock
			CALL Gadgets(2,nlock)
		END

		WHEN cmd = 'UNICONIFY' THEN
			CALL Gadgets(8,1,nundo)

		WHEN cmd = 'HELP' THEN
			ABOUT jobID modID 'HELP' || st

		WHEN cmd = 'QUIT' THEN st = 'end'

		OTHERWISE NOP
	END

	CALL REPLY(pkt,0)

END

CALL CLOSEPORT(olehost)
EXIT 0


ExistsLockedObj:

	DO n = 1 TO obj_n
		IF obj_lock = obj_id.n THEN RETURN obj_lock
	END

	g_str.nlock = lock.0
	CALL Gadgets(2,nlock)

RETURN 0


/*
 *	build a list of all selected objects
 */
SelectAllObj:

	FirstObject 'SELECTED'
	IF result = 0 THEN RETURN 0

	DO n = 1 UNTIL result = 0
		obj_id.n = result
		NextObject obj_id.n 'SELECTED'
	END

	obj_n = n

	/*
	 *	read data from each object
	 */
	DO n = 1 TO obj_n
		GetObjectCoords obj_id.n
		PARSE VAR result page obj_x.n obj_y.n obj_w.n obj_h.n .

		GetObjectType obj_id.n
		obj_t.n = result

		new_x.n = obj_x.n
		IF result = 7 THEN DO
			old_h.n = obj_h.n
			obj_h.n = TRUNC(obj_h.n * 0.72)
			new_y.n = obj_y.n - obj_h.n
			END

		ELSE new_y.n = obj_y.n

	END

RETURN 1


UndoAlignObj:
	DO n = 1 TO obj_n
		SetObjectCoords obj_id.n page obj_x.n obj_y.n obj_w.n obj_h.n
	END
	Redraw
RETURN


ReselectObj:
	DO n = 1 TO obj_n
		SelectObject obj_id.n 'MULTIPLE'
	END
RETURN


CalcNewPos:

	IF align.vert > 0  &  obj_lock = 0 THEN DO
		up = obj_y.1
		IF align.vert ~= 3 THEN
			DO n = 2 TO obj_n
				up = MIN(up,obj_y.n)
			END

		down = 0
		IF align.vert ~= 1 THEN
			DO n = 1 TO obj_n
				down = MAX(down,obj_y.n + obj_h.n)
			END

		midvert = (up + down) % 2
		END

	IF align.horz > 0  &  obj_lock = 0 THEN DO
		left = obj_x.1
		IF align.horz ~= 3 THEN
			DO n = 2 TO obj_n
				left = MIN(left,obj_x.n)
			END

		right = 0
		IF align.horz ~= 1 THEN
			DO n = 1 TO obj_n
				right = MAX(right,obj_x.n + obj_w.n)
			END

		midhorz = (left + right) % 2
		END

	/*
	 *	if only one object is selected...
	 */
	IF obj_n = 1 THEN DO
		GetPageSetup 'Width' 'Height' 'Top' 'Bottom' 'Left' 'Right'
		PARSE VAR result width height up bottom left right .

		midvert = (up + height - bottom) % 2
		down = height - bottom
		midhorz = (left + width - right) % 2
		right = width - right
		END

	IF obj_lock > 0 THEN DO
		GetObjectCoords obj_lock
		PARSE VAR result page left up width height .

		midvert = up + height % 2
		down = up + height
		midhorz = left + width % 2
		right = left + width
		END

	IF align.vert = 1 THEN
		DO n = 1 TO obj_n
			new_y.n = up
		END
	ELSE IF align.vert = 2 THEN
		DO n = 1 TO obj_n
			new_y.n = midvert - (obj_h.n % 2)
		END
	ELSE IF align.vert = 3 THEN
		DO n = 1 TO obj_n
			new_y.n = down - obj_h.n
		END

	IF align.horz = 1 THEN
		DO n = 1 TO obj_n
			new_x.n = left
		END
	ELSE IF align.horz = 2 THEN
		DO n = 1 TO obj_n
			new_x.n = midhorz - (obj_w.n % 2)
		END
	ELSE IF align.horz = 3 THEN
		DO n = 1 TO obj_n
			new_x.n = right - obj_w.n
		END

	/*
	 *	write data for all selected objects
	 */
	DO n = 1 TO obj_n
		IF obj_t.n = 7 THEN DO
			new_y.n = new_y.n + obj_h.n
			obj_h.n = old_h.n
		END

		SetObjectCoords obj_id.n page new_x.n new_y.n obj_w.n obj_h.n
	END
	ReDraw

RETURN


GetLocale: PROCEDURE EXPOSE locale
ARG strID

	strID = 'þ'strID'þ'; PARSE VALUE GETCLIP(locale) WITH (strID)text'Þ'

RETURN text


GUIGads:

	g_offx. = 2;	g_offx.1 = 0;			g_offx.3 = 2
	g_offy. = 2;	g_offy.1 = char.h + 1;	g_offy.3 = 3
	g_wid. = 8;				g_wid.1 = 0;			g_wid.3 = 12
	g_hei. = char.h + 4;	g_hei.1 = char.h + 1;	g_hei.3 = char.h + 6
	g_sx = char.w % 2;	g_sy = char.h % 4
	g_onoff. = 0

	box.left = box.left + g_sx; box.top = box.top + 2 * g_sy
	box.w = 24 * char.w

	n = 1; nmain = 1

	x = box.left; y = box.top
	CALL IniGad(1,1,4,,GetLocale(3))
	CALL IniGad(4,0,2,'ALIGN HORZ' 1 '%1' n,0)
	CALL IniGad(4,0,1,'ALIGN HORZ' 2 '%1' n,0)
	CALL IniGad(4,0,1,'ALIGN HORZ' 3 '%1' n,0)
	y = y + g_hei.3 + 2 * g_sy
	CALL IniGad(4,1,1,'ALIGN VERT' 1 '%1' n,0)
	y = y + g_hei.3 + g_sy
	CALL IniGad(4,1,1,'ALIGN VERT' 2 '%1' n,0)
	CALL IniGad(1,0,2,,GetLocale(4))
	y = y + g_hei.3 + g_sy
	CALL IniGad(4,1,1,'ALIGN VERT' 3 '%1' n,0)

	y = y + g_hei.3 + 2 * g_sy
	CALL IniGad(2,3,0,'HELP',GetLocale(5))
	nlock = IniGad(2,1,0,'LOCK',lock.0)
	CALL IniGad(2,0,0,'START %1' n,GetLocale(6))
	nundo = IniGad(2,0,0,'UNDO',GetLocale(7))

	box.h = y + g_hei.2 + 2 * g_sy - box.top
	WINDOW jobID modID (box.w + 2 * g_sx) (box.h + 2 * g_sy) 1 1
	CALL Gadgets(4,1,nundo - 1)

RETURN nmain


Gadgets:

	IF ARG(1) < 4 THEN
		DO i = 2 TO ARG(); n = ARG(i)
			IF ARG(1) ~= 1 THEN CALL DelGad(n,g_type.n)
			IF ARG(1) ~= 3 THEN CALL NewGad(n,g_type.n)
		END

	ELSE IF ARG(1) < 7 THEN
		DO n = ARG(2) TO ARG(3)
			IF ARG(1) ~= 4 THEN CALL DelGad(n,g_type.n)
			IF ARG(1) ~= 6 THEN CALL NewGad(n,g_type.n)
		END

	ELSE IF ARG(1) = 8 THEN
		DO n = ARG(2) TO ARG(3)
			IF g_onoff.n THEN CALL NewGad(n,g_type.n)
		END

	ELSE DO
		DO n = ARG(2) TO ARG(3)
			g_onoff.n = 0
			IF g_type.n ~= 1 THEN CALL RemoveGadget(olewin,GAD.n)
		END
		CALL SetAPen(olewin,0)
		CALL RectFill(olewin,box.left,box.top,box.left + box.w,box.top + box.h)
		CALL RefreshGadgets(olewin)
		END
RETURN


DelGad:
PARSE ARG n,t

	g_onoff.n = 0

	IF t ~= 1 THEN CALL RemoveGadget(olewin,GAD.n)

	x = g_xpos.n - g_offx.t; y = g_ypos.n - g_offy.t
	CALL SetAPen(olewin,0)
	CALL RectFill(olewin,x,y,x + g_len.n,y + g_hei.t)

RETURN


NewGad:
PARSE ARG n,t

	g_onoff.n = 1

	IF t = 2 THEN
		CALL AddGadGet(olewin,g_xpos.n,g_ypos.n,GAD.n,g_str.n,g_msg.n)

	ELSE IF t = 4 THEN
		CALL AddGadGet(olewin,g_xpos.n,g_ypos.n,GAD.n,D2C(32 + g_str.n * 183),g_msg.n)

	ELSE DO
		CALL SetAPen(olewin,1)
		CALL Move(olewin,g_xpos.n,g_ypos.n)
		CALL Text(olewin,g_str.n)
		END
RETURN


IniGad:
PARSE ARG t,na,nx,g_msg.n,g_str.n

	x = x + nx * g_sx

	g_len.n = LENGTH(g_str.n) * char.w + g_wid.t

	IF na > 0 THEN x = box.left + (na - 1) * (box.w - g_len.n) % 2 + nx * g_sx

	g_xpos.n = x + g_offx.t; g_ypos.n = y + g_offy.t; g_type.n = t

	x = x + g_len.n; n = n + 1

RETURN n - 1
