//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
// software: you can redistribute it and/or modify it under the terms of 
// the GNU General Public License as published by the Free Software Foundation, 
// either version 3 of the License, or (at your option) any later version.

// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
// in the hope that it will be useful, but with permitted additional restrictions 
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
// distributed with this program. You should have received a copy of the 
// GNU General Public License along with permitted additional restrictions 
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection

/* $Header: /CounterStrike/GADGET.CPP 1     3/03/97 10:24a Joe_bostic $ */
/***********************************************************************************************
 ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
 ***********************************************************************************************
 *                                                                                             *
 *                 Project Name : Command & Conquer                                            *
 *                                                                                             *
 *                    File Name : GADGET.CPP                                                   *
 *                                                                                             *
 *                   Programmer : Maria del Mar McCready Legg                                  *
 *                                Joe L. Bostic                                                *
 *                                                                                             *
 *                   Start Date : 01/03/95                                                     *
 *                                                                                             *
 *                  Last Update : August 1, 1996 [JLB]                                         *
 *                                                                                             *
 *---------------------------------------------------------------------------------------------*
 * Functions:                                                                                  *
 *   GadgetClass::Action -- Base action for gadget.                                            *
 *   GadgetClass::Clear_Focus -- Clears the focus if this gadget has it.                       *
 *   GadgetClass::Delete_List -- Deletes all gadget objects in list.                           *
 *   GadgetClass::Disable -- Disables the gadget from input processing.                        *
 *   GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn.                        *
 *   GadgetClass::Draw_Me -- Gadget redraw action (flag control).                              *
 *   GadgetClass::Enable -- Enables the gadget.                                                *
 *   GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified.  *
 *   GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn.                           *
 *   GadgetClass::GadgetClass -- Constructor for gadget object.                                *
 *   GadgetClass::GadgetClass -- Default constructor for a gadget class object.                *
 *   GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain.               *
 *   GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget.                        *
 *   GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus.         *
 *   GadgetClass::Remove -- Removes the specified gadget from the list.                        *
 *   GadgetClass::Set_Focus -- Sets focus to this gadget.                                      *
 *   GadgetClass::Sticky_Process -- Handles the sticky flag processing.                        *
 *   GadgetClass::~GadgetClass -- Destructor for gadget object.                                *
 *   GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing         *
 *   GadgetClass::GadgetClass -- Constructor for the gadget object.                            *
 *   GadgetClass::Set_Position -- Set the coordinate position of this gadget.                  *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include "function.h"


/*
**	This records the current gadget the the gadget system is "stuck on". Such a
**	gadget will be processed to the exclusion of all others until the mouse button
**	is no longer pressed.
*/
GadgetClass * GadgetClass::StuckOn = 0;

/*
**	This is a copy of a pointer to the last list used by the gadget input system.
**	If a change of list is detected, then all gadgets are forced to be redrawn.
*/
GadgetClass * GadgetClass::LastList = 0;


/*
**	This points to the gadget that is intercepting all keyboard events.
*/
GadgetClass * GadgetClass::Focused = 0;


/*
** This points to the current color scheme for drawing all gadgets.
*/
static RemapControlType _GreyScheme = {15};
RemapControlType * GadgetClass::ColorScheme = &_GreyScheme;


/***********************************************************************************************
 * GadgetClass::GadgetClass -- Constructor for gadget object.                                  *
 *                                                                                             *
 *    This is the normal constructor for gadget objects. A gadget object is only concerned     *
 *    with the region on the screen to considered "its own" as well as the flags that tell     *
 *    what mouse action should be recognized when the mouse is over this screen area.          *
 *                                                                                             *
 * INPUT:   x,y   -- Coordinates (in pixels) of the upper left hand corner of the region that  *
 *                   will be "owned" by this gadget.                                           *
 *                                                                                             *
 *          w,h   -- Width and height (in pixels) of this gadget's region.                     *
 *                                                                                             *
 *          flags -- The flags (mouse conditions) that will cause this gadget's action         *
 *                   function to be called.                                                    *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/03/1995 MML : Created.                                                                 *
 *=============================================================================================*/
GadgetClass::GadgetClass(int x, int y, int w, int h, unsigned flags, int sticky) :
	X(x), Y(y), Width(w), Height(h), IsToRepaint(false), IsSticky(sticky), IsDisabled(false), Flags(flags)
{
	if (IsSticky) {
		Flags |= LEFTPRESS|LEFTRELEASE;
	}
}


/***********************************************************************************************
 * GadgetClass::GadgetClass -- Constructor for the gadget object.                              *
 *                                                                                             *
 *    This is the copy constructor for the gadget object. It will try to duplicate the         *
 *    righthand gadget.                                                                        *
 *                                                                                             *
 * INPUT:   gadget   -- Reference to the initilization gadget.                                 *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   08/01/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
GadgetClass::GadgetClass(GadgetClass const & gadget) :
	X(gadget.X),
	Y(gadget.Y),
	Width(gadget.Width),
	Height(gadget.Height),
	IsToRepaint(gadget.IsToRepaint),
	IsSticky(gadget.IsSticky),
	IsDisabled(gadget.IsDisabled),
	Flags(gadget.Flags)
{
}


/***********************************************************************************************
 * GadgetClass::~GadgetClass -- Destructor for gadget object.                                  *
 *                                                                                             *
 *    This is the destructor for the gadget object. It will clear the focus from this gadget   *
 *    if this gadget currently has the focus.                                                  *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   07/08/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
GadgetClass::~GadgetClass(void)
{
	if (Has_Focus()) {
		Clear_Focus();
	}

	if (this == StuckOn) {
		StuckOn = NULL;
	}

	if (this == LastList) {
		LastList = NULL;
	}

	if (this == Focused) {
		Focused = NULL;
	}
}


/***************************************************************************
 * GADGETCLASS::CLICKEDON -- If a mouse click is detected within gadget's  *
 *      area and the appropriate flag is set, then call Action().          *
 *                                                                         *
 * INPUT:      int key, int mousex, int mousey                             *
 *                                                                         *
 * OUTPUT:     true or false                                               *
 *                                                                         *
 * WARNINGS:   none.                                                       *
 *                                                                         *
 * HISTORY:    01/03/1995 MML : Created.                                   *
 *=========================================================================*/
int GadgetClass::Clicked_On(KeyNumType & key, unsigned flags, int mousex, int mousey)
{
	/*
	**	Set flags to match only those events that occur AND are being looked for. If
	**	the result is NULL, then we know that this button should be ignored.
	*/
	flags &= Flags;

	/*
	**	If keyboard input should be processed by this "gadget" and keyboard input is
	**	detected, then always call the action function. It is up to the action function
	**	in this case to either ignore the keyboard input or not.
	**
	**	For mouse actions, check to see if the mouse is in the region of the button
	**	before calling the associated action function. This is the typical action for
	**	buttons.
	*/
	if (this == StuckOn ||
		(flags & KEYBOARD) ||
		(flags && (mousex - X) < Width  && (mousey - Y) < Height)) {

		return(Action(flags, key));
	}
	return(false);
}


/***********************************************************************************************
 * GadgetClass::Enable -- Enables the gadget.                                                  *
 *                                                                                             *
 *    This function enables the gadget. An enabled gadget will be processed for input          *
 *    purposes.                                                                                *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Enable(void)
{
	IsDisabled = false;
	IsToRepaint = true;
	Clear_Focus();
}


/***********************************************************************************************
 * GadgetClass::Disable -- Disables the gadget from input processing.                          *
 *                                                                                             *
 *    This routine will disable the gadget. A disabled gadget might be rendered, but is        *
 *    ignored for input processing.                                                            *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Disable(void)
{
	IsDisabled = true;
	IsToRepaint = true;
	Clear_Focus();
}


/***********************************************************************************************
 * GadgetClass::Remove -- Removes the specified gadget from the list.                          *
 *                                                                                             *
 *    Use this routine if an individual gadget needs to be removed from the list of gadgets.   *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  bool; Was the specified gadget found and removed? A false indicates that the       *
 *                gadget wasn't in the list.                                                   *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
GadgetClass * GadgetClass::Remove(void)
{
	Clear_Focus();
	return(GadgetClass *)LinkClass::Remove();
}


/***********************************************************************************************
 * GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain.                 *
 *                                                                                             *
 *    This returns with the next gadget's pointer. It is identical to the base Get_Next()      *
 *    function, but returns a pointer to a GadgetClass object.                                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the next gadget in the list.                             *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
GadgetClass * GadgetClass::Get_Next(void) const
{
	return(GadgetClass*)LinkClass::Get_Next();
}


/***********************************************************************************************
 * GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget.                          *
 *                                                                                             *
 *    This routine will return the previous gadget in the list. It is identical to the base    *
 *    function Get_Prev, but returns a pointer to a GadgetClass object.                        *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the previous gadget in the list.                         *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
GadgetClass * GadgetClass::Get_Prev(void) const
{
	return(GadgetClass*)LinkClass::Get_Prev();
}


/***********************************************************************************************
 * GadgetClass::Delete_List -- Deletes all gadget objects in list.                             *
 *                                                                                             *
 *    This function will delete all gadgets in the list. It is the counterpart to the          *
 *    Create_One_Of functions.                                                                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   Any references to these gadget become invalidated by this routine.              *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Delete_List(void)
{
	GadgetClass * g = this;

	/*
	**	Move to head of the list.
	*/
	while (g->Get_Prev()) {
		g = g->Get_Prev();
	}

	/*
	**	First delete all the gadgets following the first one. The reason the first one
	**	is kept around is that sometimes deleting one gadget will result in related gadgets
	**	in the same list also being deleted. The first gadget will always contain the
	**	correct gadget pointer.
	*/
	while (g) {
		g->Clear_Focus();

		GadgetClass * temp = g;
		g = g->Get_Next();
		delete temp;
	}
}


/***********************************************************************************************
 * GadgetClass::Action -- Base action for gadget.                                              *
 *                                                                                             *
 *    This handles the base level action that a gadget performs when a qualifying input event  *
 *    is detected. This sets the redraw flag and returns true (to stop further processing).    *
 *    If no qualifying input event was detected, but this routine was called anyway, then      *
 *    don't perform any action. The call to this routine, in that case, must have been forced  *
 *    for some other reason.                                                                   *
 *                                                                                             *
 * INPUT:   flag  -- The input event bits that qualify for this gadget. A NULL indicates that  *
 *                   no qualifying event occurred.                                             *
 *                                                                                             *
 * OUTPUT:  bool; Should further gadget list processing be aborted?                            *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/15/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
int GadgetClass::Action(unsigned flags, KeyNumType &)
{
	/*
	**	If any of the event flags are active, then this indicates that something probably
	**	has changed the gadget. Flag the gadget to be redrawn. Also, make sure that
	**	any sticky flags are cleared up.
	*/
	if (flags) {
		IsToRepaint = true;
		Sticky_Process(flags);
		return(true);
	}
	return(false);
}


/***********************************************************************************************
 * GadgetClass::Draw_Me -- Gadget redraw action (flag control).                                *
 *                                                                                             *
 *    At this level, there is no actual rendering taking place with the call to Draw_Me, but   *
 *    the IsToRepaint flag must be cleared. Derived objects will call this routine and if it   *
 *    returns true, they will perform their custom rendering.                                  *
 *                                                                                             *
 * INPUT:   forced   -- Is this redraw forced by outside circumstances?                        *
 *                                                                                             *
 * OUTPUT:  bool; Should the gadget imagery be redrawn?                                        *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/14/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
int GadgetClass::Draw_Me(int forced)
{
	if (forced || IsToRepaint) {
		IsToRepaint = false;
		return(true);
	}
	return(false);
}


/***********************************************************************************************
 * GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn.                          *
 *                                                                                             *
 *    Use this function to cause all gadget in the list to be redrawn regardless of the state  *
 *    of the IsToRepaint flag.                                                                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/03/1995 MML : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Draw_All(bool forced)
{
	GadgetClass * gadget = this;

	while (gadget != NULL) {
		gadget->Draw_Me(forced);
		gadget = gadget->Get_Next();
	}
}


/***************************************************************************
 * GADGETCLASS::PROCESSLIST -- Check list for a mouse click within a gadget*
 *                                                                         *
 * INPUT:      none.                                                       *
 *                                                                         *
 * OUTPUT:     key pressed.                                                *
 *                                                                         *
 * WARNINGS:   none.                                                       *
 *                                                                         *
 * HISTORY:    01/03/1995 MML : Created.                                   *
 *=========================================================================*/
KeyNumType GadgetClass::Input(void)
{
	int mousex, mousey;
	KeyNumType key;
	unsigned flags;
	int forced = false;

	/*
	**	Record this list so that a forced redraw only occurs the FIRST time the
	**	gadget list is passed to this routine.
	*/
	if (LastList != this) {
		LastList = this;
		forced = true;
		StuckOn = NULL;
		Focused = NULL;
	}

	/*
	**	Fetch any pending keyboard input.
	*/
	key = Keyboard->Check();
	if (key != 0) {
		key = Keyboard->Get();
	}

#ifdef WIN32
#ifdef CHEAT_KEYS
	if (key == KN_K && !Debug_Map && (Debug_Flag || Debug_Playtest)) {
		/*
		** time to create a screen shot using the PCX code (if it works)
		*/
		if (!Debug_MotionCapture) {
			GraphicBufferClass temp_page(	SeenBuff.Get_Width(),
													SeenBuff.Get_Height(),
													NULL,
													SeenBuff.Get_Width() * SeenBuff.Get_Height());
			CDFileClass file;
			char filename[30];

//			Hide_Mouse();
			SeenBuff.Blit(temp_page);
//			Show_Mouse();
			for (int lp = 0; lp < 99; lp ++) {
				sprintf(filename, "scrsht%02d.pcx", lp);
				file.Set_Name(filename);
				if (!file.Is_Available()) break;
			}

			file.Cache(200000);
			Write_PCX_File(file, temp_page, & GamePalette);
			Sound_Effect(VOC_BEEP);
		}
	}
#endif
#endif

	/*
	**	For mouse button clicks, the mouse position is actually held in the MouseQ...
	**	globals rather than their normal Mouse... globals. This is because we need to
	**	know the position of the mouse at the exact instant when the click occurred
	**	rather the the mouse position at the time we get around to this function.
	*/
	if (((key&0xFF) == KN_LMOUSE) || ((key&0xFF) == KN_RMOUSE)) {
	   mousex = Keyboard->MouseQX;
	   mousey = Keyboard->MouseQY;
	} else {
	   mousex = Get_Mouse_X();
	   mousey = Get_Mouse_Y();
	}

	/*
	**	Set the mouse button state flags. These will be passed to the individual
	**	buttons so that they can determine what action to perform (if any).
	*/
	flags = 0;
	if (key) {
		if (key == KN_LMOUSE) {
			flags |= LEFTPRESS;
		}
		if (key == KN_RMOUSE) {
			flags |= RIGHTPRESS;
		}
		if (key == (KN_LMOUSE | KN_RLSE_BIT)) {
			flags |= LEFTRELEASE;
		}
		if (key == (KN_RMOUSE | KN_RLSE_BIT)) {
			flags |= RIGHTRELEASE;
		}
	}

	/*
	**	If the mouse wasn't responsible for this key code, then it must be from
	**	the keyboard. Flag this fact.
	*/
	if (key && !flags) {
		flags |= KEYBOARD;
	}

	/*
	**	Mouse button up or down action is ignored if there is a keyboard event. This
	**	allows keyboard events to fall through normally even if the mouse is over a
	**	gadget that is flagged for LEFTUP or RIGHTUP.
	*/
	if (!key) {

		/*
		**	Check for the mouse being held down. We can't use the normal input system
		**	for this, so we must examine the actual current state of the mouse
		**	buttons. As a side note, if we determine that the mouse button isn't being
		**	held down, then we automatically know that it must be up -- set the flag
		**	accordingly.
		*/
		if (Keyboard->Down(KN_LMOUSE)) {
			flags |= LEFTHELD;
		} else {
			flags |= LEFTUP;
		}
		if (Keyboard->Down(KN_RMOUSE)) {
			flags |= RIGHTHELD;
		} else {
			flags |= RIGHTUP;
		}
	}

	/*
	**	If "sticky" processing is active, then only process the stuck gadget.
	*/
	if (StuckOn) {
		StuckOn->Draw_Me(false);
		GadgetClass * oldstuck = StuckOn;
		StuckOn->Clicked_On(key, flags, mousex, mousey);
		if (StuckOn) {
			StuckOn->Draw_Me(false);
		} else {
			oldstuck->Draw_Me(false);
		}
	} else {

		/*
		**	If there is a gadget that has the keyboard focus, then route all keyboard
		**	events to it.
		*/
		if (Focused && (flags & KEYBOARD)) {
			Focused->Draw_Me(false);
			Focused->Clicked_On(key, flags, mousex, mousey);
			if (Focused) {
				Focused->Draw_Me(false);
			}
		} else {

			/*
			**	Sweep through all the buttons in the chain and pass the current button state
			**	and keyboard input data to them. These routines will detect whether they should
			**	perform some action and return a flag to this effect. They also have the option
			**	of changing the key value so that an appropriate return value is use for this
			**	processing routine.
			*/
			GadgetClass * next_button = this;
			while (next_button != NULL) {

				/*
				**	Maybe redraw the button if it needs to or is being forced to redraw.
				*/
				next_button->Draw_Me(forced);

				if (!next_button->IsDisabled) {

					/*
					**	Process this button. If the button was recognized and action was
					**	performed, then bail from further processing (speed reasons?).
					*/
					if (next_button->Clicked_On(key, flags, mousex, mousey)) {

						/*
						**	Some buttons will require repainting when they perform some action.
						**	Do so at this time.
						*/
						next_button->Draw_Me(false);
						break;
					}
				}

				next_button = next_button->Get_Next();
			}
		}
	}
	return(key);
}


/***********************************************************************************************
 * GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified.    *
 *                                                                                             *
 *    This examines the gadget list looking for on that has the same ID as specified. If that  *
 *    gadget was found, then a pointer to it is returned. Since only ControlClass gadgets      *
 *    or ones derived from it can have an ID value, we know that the returned pointer is at    *
 *    least of the ControlClass type.                                                          *
 *                                                                                             *
 * INPUT:   id -- The ID number to scan for. Zero is not a legal ID number and if passed in,   *
 *                a NULL will always be returned.                                              *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the ControlClass gadget that has the matching ID number. *
 *          If no matching gadget was found, then NULL is returned.                            *
 *                                                                                             *
 * WARNINGS:   If there happens to be more than one gadget with a matching ID, this routine    *
 *             will return a pointer to the first one only.                                    *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/16/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
ControlClass * GadgetClass::Extract_Gadget(unsigned id)
{
	GadgetClass * g = this;

	if (id != 0) {
		while (g != NULL) {
			if (g->Get_ID() == id) {
				return((ControlClass *)g);
			}
			g = g->Get_Next();
		}
	}
	return(0);
}


/***********************************************************************************************
 * GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn.                             *
 *                                                                                             *
 *    Use this routine to flag the gadget to be redrawn. A gadget so flagged will have its     *
 *    Draw_Me function called at the next available opportunity. Usually, this is the next     *
 *    time the Input() function is called.                                                     *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/16/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Flag_To_Redraw(void)
{
	IsToRepaint = true;
}


/***********************************************************************************************
 * GadgetClass::Sticky_Process -- Handles the sticky flag processing.                          *
 *                                                                                             *
 *    This function examines the event flags and handles any "sticky" processing required.     *
 *    Sticky processing is when the button is flagged with the "IsSticky" bit and it will      *
 *    be processed to the exclusion of all other gadgets while the mouse button is held        *
 *    down.                                                                                    *
 *                                                                                             *
 * INPUT:   flags -- The event flags that triggered the call to this routine.                  *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/16/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Sticky_Process(unsigned flags)
{
	if (IsSticky && (flags & LEFTPRESS)) {
		StuckOn = this;
	}
	if (StuckOn == this && (flags & LEFTRELEASE)) {
		StuckOn = 0;
	}
}


/***********************************************************************************************
 * GadgetClass::Set_Focus -- Sets focus to this gadget.                                        *
 *                                                                                             *
 *    This will set the focus to this gadget regardless of any current focus setting. If there *
 *    is another gadget that has focus, it will have its focus cleared before this gadget will *
 *    get the focus. A focused gadget is one that has all keyboard input routed to it.         *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/25/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Set_Focus(void)
{
	if (Focused) {
		Focused->Flag_To_Redraw();
		Focused->Clear_Focus();
	}
	Flags |= KEYBOARD;
	Focused = this;
}


/***********************************************************************************************
 * GadgetClass::Clear_Focus -- Clears the focus if this gadget has it.                         *
 *                                                                                             *
 *    Use this function to clear the focus for the gadget. If the gadget doesn't currently     *
 *    have focus, then this routine will do nothing. For added functionality, overload this    *
 *    virtual function so that gadget specific actions may be take when focus is lost.         *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/25/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Clear_Focus(void)
{
	if (Focused == this) {
		Flags &= ~KEYBOARD;
		Focused = 0;
	}
}


/***********************************************************************************************
 * GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus.           *
 *                                                                                             *
 *    If this object has the keyboard focus, then this routine will return true. When the      *
 *    gadget has keyboard focus, all keyboard events get routed to the gadget.                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  bool; Does this gadget have the keyboard focus?                                    *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/21/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
bool GadgetClass::Has_Focus(void)
{
	return(this == Focused);
}


/***********************************************************************************************
 * GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing           *
 *                                                                                             *
 * This function is mostly for supporting HidPage drawing.  If it returns true, it means       *
 * the application needs to re-blit the HidPage forward, after calling the list's Input().     *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  true = an item needs redrawing, false = no items need redrawing                    *
 *                                                                                             *
 * WARNINGS:   It is assumed 'this' is the head of the list.                                   *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   01/03/1995 MML : Created.                                                                 *
 *=============================================================================================*/
int GadgetClass::Is_List_To_Redraw(void)
{
	GadgetClass * gadget = this;

	while (gadget != NULL) {
		if (gadget->IsToRepaint) {
			return (true);
		}
		gadget = gadget->Get_Next();
	}
	return (false);
}


/***********************************************************************************************
 * GadgetClass::Set_Position -- Set the coordinate position of this gadget.                    *
 *                                                                                             *
 *    This routine helps with moving a gadget's location. It will set the gadgets upper        *
 *    left corner to the pixel location specified.                                             *
 *                                                                                             *
 * INPUT:   x,y   -- The X and Y position to put the gadget's upper left corner to.            *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   08/01/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
void GadgetClass::Set_Position(int x, int y)
{
	X = x;
	Y = y;
}