////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 RWS Inc, All Rights Reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of version 2 of the GNU General Public License as published by
// the Free Software Foundation
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//////////////////////////////////////////////////////////////////////////////
//
// PUSHBTN.CPP
// 
// History:
//		02/05/97 JMI	Started.
//
//		02/05/97	JMI	Forgot to make sure we were actually clicked in before
//							processing a release within cursor event area.
//
//		02/05/97	JMI	Forgot to remove a debug TRACE.
//
//		03/19/97	JMI	Converted to using the RHot::m_iecUser (was using
//							RHot::m_epcUser) so HotCall and CursorEvent now take
//							RInputEvent ptrs.
//
//		04/16/97	JMI	In previous update, forgot to add case RSP_MB0_DOUBLECLICK
//							in both places need for this implentation of CursorEvent().
//
//////////////////////////////////////////////////////////////////////////////
//
// This a GUI item that is based on the basic RGuiItem. 
// This overrides HotCall() to get information about where a click in its CHot
// occurred.
// This overrides Compose() to add text.
//
// Enhancements/Uses:
// To change the look of a button when pressed, you may want to override the
// Compose() or DrawBorder() in a derived class.
// To change the background of a button, see RGuiItem.
// To get a callback on a click/release pair in the button, set m_bcUser.
//
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// Headers.
//////////////////////////////////////////////////////////////////////////////
#include "Blue.h"

#ifdef PATHS_IN_INCLUDES
	#include "ORANGE/GUI/PushBtn.h"
#else
	#include "PushBtn.h"
#endif // PATHS_IN_INCLUDES

//////////////////////////////////////////////////////////////////////////////
// Module specific macros.
//////////////////////////////////////////////////////////////////////////////

// Sets val to def if val is -1.
#define DEF(val, def)	((val == -1) ? def : val)

//////////////////////////////////////////////////////////////////////////////
// Module specific typedefs.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// Module specific (static) variables.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// Construction/Destruction.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
// Default constructor.
//
//////////////////////////////////////////////////////////////////////////////
RPushBtn::RPushBtn()
	{
	// Override RGuiItem's default justification.
	m_justification	= RGuiItem::Centered;

	m_type				= PushBtn;	// Indicates type of GUI item.

	// Initialize RPushBtn members.
	m_state	= Off;		// The button's current state (On or Off (see enums)).
	}

//////////////////////////////////////////////////////////////////////////////
//
// Destructor.
//
//////////////////////////////////////////////////////////////////////////////
RPushBtn::~RPushBtn()
	{
	}

////////////////////////////////////////////////////////////////////////
// Methods.
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
//
// Compose item.
//
////////////////////////////////////////////////////////////////////////
void RPushBtn::Compose(			// Returns nothing.
	)	// Dest image, uses m_im if NULL.
	{


	if (m_sPressed != FALSE || m_state == On)
		{
		// Invert border.
		m_sInvertedBorder	= TRUE;
		}
	else
		{
		m_sInvertedBorder	= FALSE;
		}

	// Call base (draws border and background).
	RGuiItem::Compose();

	// Draw pushbtn stuff.
	int16_t	sX, sY, sW, sH;
	// Get client relative to border so we know where to
	// put the text.
	GetClient(&sX, &sY, &sW, &sH);

	// Draw text.
	DrawText(sX, sY, sW, sH);
	}


//////////////////////////////////////////////////////////////////////////////
//
// Draw border.
// (virtual	(Overridden here)).
//
//////////////////////////////////////////////////////////////////////////////
void RPushBtn::DrawBorder(			// Returns nothing.
	int16_t sInvert	/*= FALSE*/)	// Inverts border if TRUE.
	{
	int16_t	sVertShadowPos;
	int16_t	sHorzShadowPos;
	int16_t	sVertHighlightPos;
	int16_t sHorzHighlightPos;
	int16_t sVertEdgePos;
	int16_t sHorzEdgePos;
	int16_t	sShadowThickness		= m_sBorderThickness;
	int16_t	sEdgeThickness			= m_sBorderThickness;
	int16_t	sHighlightThickness	= m_sBorderThickness;


	int16_t sW	= 0;
	int16_t	sH	= 0;

	m_sInvertedBorder	= sInvert;

	if (sInvert == FALSE)
		{
		sVertShadowPos			= sW - m_sBorderThickness;
		sHorzShadowPos			= sH - m_sBorderThickness;
		sVertHighlightPos		= 0;
		sHorzHighlightPos		= 0;
		sVertEdgePos			= sW - m_sBorderThickness * 2;
		sHorzEdgePos			= sH - m_sBorderThickness * 2;
		}
	else
		{
		// Left top becomes thicker when pressed.
		sShadowThickness		= (m_sPressed == FALSE) ? m_sBorderThickness 
																	: (m_sBorderThickness * 2);

		sEdgeThickness			= sShadowThickness;
		sHighlightThickness	= m_sBorderThickness;//sShadowThickness;

		sVertShadowPos			= 0;
		sHorzShadowPos			= 0;
		sVertHighlightPos		= sW - sHighlightThickness;
		sHorzHighlightPos		= sH - sHighlightThickness;
		sVertEdgePos			= sShadowThickness;
		sHorzEdgePos			= sShadowThickness;
		}

	// One pixel for each edge of border gets overwritten.
	/*rspRect(m_u32BorderHighlightColor, pim, 0, sHorzHighlightPos, sW, sHighlightThickness);
	rspRect(m_u32BorderHighlightColor, pim, sVertHighlightPos, 0, sHighlightThickness, sH);

	rspRect(m_u32BorderShadowColor, pim, 0, sHorzShadowPos, sW, sShadowThickness);
	rspRect(m_u32BorderShadowColor, pim, sVertShadowPos, 0, sShadowThickness, sH);

	rspRect(m_u32BorderEdgeColor, pim, sShadowThickness, sHorzEdgePos, sW - sShadowThickness - sEdgeThickness, sEdgeThickness);
	rspRect(m_u32BorderEdgeColor, pim, sVertEdgePos, sShadowThickness, sEdgeThickness, sH - sShadowThickness - sEdgeThickness);*/
	}

//////////////////////////////////////////////////////////////////////////////
// Querries.
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
// Gets the thickness of the top/left border (including border edge effect).
// (virtual	(Overridden here)).
//
//////////////////////////////////////////////////////////////////////////////
int16_t RPushBtn::GetTopLeftBorderThickness(void)	// Returns border thickness 
																// including edge effect.
	{
	if (m_sBorderThickness == 0)
		return 0;
	else
		return (m_sBorderThickness
		+ ((m_sInvertedBorder == FALSE) ? 0 : m_sBorderThickness) )
		* ((m_sPressed == FALSE) ? 1 : 2);
	}

//////////////////////////////////////////////////////////////////////////////
//
// Gets the thickness of the bottom/right border (including border edge effect).
// (virtual	(Overridden here)).
//
//////////////////////////////////////////////////////////////////////////////
int16_t RPushBtn::GetBottomRightBorderThickness(void)	// Returns border thickness 
																		// including edge effect.
	{
	if (m_sBorderThickness == 0)
		return 0;
	else
		return (m_sBorderThickness 
		+ ((m_sInvertedBorder == FALSE) ? m_sBorderThickness : 0) )
;//		* ((m_sPressed == FALSE) ? 1 : 2);
	}

//////////////////////////////////////////////////////////////////////////////
// EOF
//////////////////////////////////////////////////////////////////////////////
