/**************************************************************************
 * RSCRRBTN.C - The obj_rrbuttons() routine.
 *	 This changes the specified objects into rounded-rectangle radio
 *	 buttons (by making them USERDEF objects), and supplies the drawing
 *	 routine for the buttons.
 *************************************************************************/

#include "gemfintl.h"
#include <string.h>

/*-------------------------------------------------------------------------
 * rr_draw - Draw a rounded rectangle radio button.  This routine is
 *
		called by the AES whenever a rrbutton needs to be drawn
 *			 or to have its state changed.	(Note that this routine
 *			 gets control in supervisor mode.  Some runtime libraries
 *			 will crash on stack overlow problems if you make calls
 *			 to DOS, BIOS, or XBIOS from in here.)
 *
 *			 We handle SELECTED and DISABLED states here, but other
 *			 states are handled by the AES because we pass the states we
 *			 didn't do back to the AES as the retval from this routine.
 *-----------------------------------------------------------------------*/

#ifdef GEMFAST_PROTOS
  static long GCALLBACK rr_draw(XPARMBLK *parmblk)
#else
  static long GCALLBACK rr_draw(parmblk)
	register XPARMBLK *parmblk;
#endif
{
	short	vdi_handle;
	short	xpos;
	short	ypos;
	short	dmy;
	short	len;
	short	objstate;
	VRECT	cliprect;
	VRECT	boxrect;

	if (0 == (vdi_handle = apl_vshared())) {
		return 0;	/* oh well, so sorry */
	}

	objstate = parmblk->currstate;

	rc_gtov(&parmblk->cliprect, &cliprect);
	vs_clip(vdi_handle, 1, (short *)&cliprect);

	rc_gtov(&parmblk->drawrect, &boxrect);
	rc_vadjust(&boxrect, 1, 1);

	len = (short)strlen((char *)parmblk->pub->ob_spec);

	xpos = parmblk->drawrect.g_x +
				((parmblk->drawrect.g_w - gl_wchar * len) / 2);
	ypos = parmblk->drawrect.g_y +
				((parmblk->drawrect.g_h - gl_hchar) / 2);

	if (objstate & SELECTED) {
		v_rfbox(vdi_handle, (short *)&boxrect);
		vswr_mode(vdi_handle, MD_TRANS);
		vst_color(vdi_handle, 0);
	} else {
		vsf_interior(vdi_handle, IS_HOLLOW);
		v_rfbox(vdi_handle, (short *)&boxrect);
		vsf_interior(vdi_handle, IS_SOLID);
	}

	if (objstate & DISABLED) {
		vst_effects(vdi_handle, 0x0002); /* lightened text */
	}
	vst_alignment(vdi_handle, 0, 5, &dmy, &dmy);
	v_gtext(vdi_handle, xpos, ypos, (char *)parmblk->pub->ob_spec);
	vst_alignment(vdi_handle, 0, 0, &dmy, &dmy);
	if (objstate & DISABLED) {
		vst_effects(vdi_handle, 0x0000); /* normal text */
	}

	if (objstate & SELECTED) {
		vst_color(vdi_handle, 1);
		vswr_mode(vdi_handle, MD_REPLACE);
	}

	vs_clip(vdi_handle, 0, (short *)&cliprect);

	return (objstate & ~(SELECTED|DISABLED));
}

/*-------------------------------------------------------------------------
 * rsc_rrbuttons - Transform all radio buttons into rounded radio buttons.
 *-----------------------------------------------------------------------*/

short rsc_rrbuttons(ptree)
	OBJECT			 *ptree;
{
	register OBJECT   *pobj;
	register XUSERBLK *pblk;
	register short		 obflags;
	register short		 numobj = 0;
	register short		 curobj;

	if (0 == apl_vshared()) {
		return gfErr_vdi_handle;			 /* no more handles */
	}

/*
 * count the number of button objects we'll be transforming...
 */

	for (pobj = ptree; ; ++pobj) {
		obflags = pobj->ob_flags;
		if ((pobj->ob_type & 0x00FF) == G_BUTTON && (obflags & RBUTTON)) {
			++numobj;
		}
		if (obflags & LASTOB) { 		/* stop after doing last	*/
			break;						/* object in the tree.		*/
		}
	}

/*
 * allocate a chunk of memory to hold all the XUSERBLKs we're going
 * to attach to the objects.
 */

	if (NULL == (pblk = apl_malloc((long)(numobj * sizeof(XUSERBLK))))) {
		return gfErr_no_memory;
	}

/*
 * now go through and change each radio button object into a USERDEF.
 */

	for (curobj = 0, pobj = ptree; ; ++curobj, ++pobj) {
		obflags = pobj->ob_flags;
		if ((pobj->ob_type & 0x00FF) == G_BUTTON && (obflags & RBUTTON)) {
			obj_mxuserdef(ptree, curobj, pblk++, rr_draw, NULL, 0L);
		}
		if (obflags & LASTOB) { 		/* stop after doing last	*/
			break;						/* object in the tree.		*/
		}
	}

	return 0;
}


