/*********************************************************************
*	CBasePanel
*	SOURCE FILE
*	Autor:	Michal Jirouš
*	Datum: 3.7.2008
*	Soubor: basepanel.cpp
*	Popis: Jedna polozka seznamu (ListBox). Umoznuje ovladat jednu komponentu,
*			o kterou se musi postarat ve smyslu predavani zprav a zmen velikosti.
*			
**********************************************************************/


#include "gfg.h"
#include "mathematic.h"
CBasePanel::CBasePanel()
{
	m_pComponent = NULL;
	
}

CBasePanel::CBasePanel( float w, float h )
{	
	m_pComponent = NULL;
	baseInit( w, h );
}

CBasePanel::~CBasePanel()
{
	delete m_pComponent;
}

//implementace jednoduche animace pri ztrate/zisku aktivity
void CBasePanel::run()
{
	if( m_pComponent  )
	{
		m_pComponent->run();
		float alpha = m_pComponent->getAlphaMultiplier();
		if( m_bFocused )
		{

			if( alpha < m_fAlphaMultiplier )
				m_pComponent->setAlphaMultiplier( getFromRange( alpha + GFG_CBASEPANEL_ALPHA_STEP, 0.0f, 1.0f ) );
		}	
		else
		{
			if( alpha > GFG_CBASEPANEL_MIN_ALPHA )
				m_pComponent->setAlphaMultiplier( getFromRange( alpha - GFG_CBASEPANEL_ALPHA_STEP, 0.0f, 1.0f ) );
		}
	}
}

//prirazeni komponenty
void CBasePanel::setComponent( CBaseComponent *component )
{
	if( component )
	{
		component->setPosition( m_fGlobalXpos, m_fGlobalYpos );
		component->setWidth( m_fWidth );
		component->setHeight( m_fHeight );
		component->setParent( this );
		component->setPadding( GFG_STANDARD_PADDING );
		m_pComponent = component;
		m_pComponent->setAlphaMultiplier( GFG_CBASEPANEL_MIN_ALPHA );
	}
}

//zpravy se preposilaji komponente
void CBasePanel::setEnabled( bool value )
{
	m_bEnabled = value;
	if( m_pComponent )
		m_pComponent->setEnabled( value );
}

//zpravy se preposilaji komponente
void CBasePanel::setTemporaryDisabled( bool disabled )
{
	m_bTemporaryDisabled = disabled;
	if( m_pComponent )
		m_pComponent->setTemporaryDisabled( disabled );
}

//nastaveni alfa multiplikatoru
void CBasePanel::setAlphaMultiplier( float multiplier )
{
	m_fAlphaMultiplier = multiplier;
	if( m_pComponent )
	{
		if( m_bFocused )
		{	//dle aktivity panelu
			m_pComponent->setAlphaMultiplier( multiplier );
		}
		else
		{
			m_pComponent->setAlphaMultiplier( min(multiplier, GFG_CBASEPANEL_MIN_ALPHA) );
		}
	}
	

}



void CBasePanel::onScissorBoxResize( float w_offset, float h_offset )
{
	if( m_pComponent  )
		m_pComponent->setSizeOffset( w_offset, h_offset );
}

void CBasePanel::onScissorBoxTranslate( float offsetX, float offsetY )
{
	if( m_pComponent  )
		m_pComponent->setPositionOffset( offsetX, offsetY );
}

//panel se sam vykresluje podle toho zda je aktivni a zda
//na nej ukazuje kurzor mysi
void CBasePanel::draw( ScissorBox &scissorBox )
{
	glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_SCISSOR_BIT);
	glEnable( GL_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	float x = m_fAlphaMultiplier;
	float thisAlpha = x;
	if( m_pComponent )
		thisAlpha = m_pComponent->getAlphaMultiplier();

	

	if( m_bFocused )
	{
		m_fAlphaMultiplier = GFG_CBASEPANEL_MIN_ALPHA;
		glBegin( GL_POLYGON );
			setColor( GFG_COLOR_PANEL_SELECTED );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos );
			m_fAlphaMultiplier = thisAlpha;
			setColor( GFG_COLOR_PANEL_SELECTED );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos + m_fHeight/2.0f  );
			m_fAlphaMultiplier = GFG_CBASEPANEL_MIN_ALPHA;
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos + m_fHeight  );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight );
			m_fAlphaMultiplier = thisAlpha;
			setColor( GFG_COLOR_PANEL_SELECTED );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight/2.0f );
		glEnd();
	}
	else if( m_bMouseOver )
	{
		glBegin( GL_QUADS );
			setColor( GFG_COLOR_PANEL_MOUSEOVER );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos + m_fHeight );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight );
		glEnd();
	}
	else
	{
		glBegin( GL_QUADS );
			setColor( GFG_COLOR_PANEL_SELECTED );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos );
			glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos + m_fHeight );
			glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight );
		glEnd();
	}

	ScissorBox intersected = m_ScissorBox.intersection( scissorBox );
	glScissor( (GLsizei)intersected.x, (GLsizei)intersected.y, (GLsizei)intersected.w, (GLsizei)intersected.h );

	//nakonec se vykresli vlastnena komponenta
	if( m_pComponent  )
		m_pComponent->draw( intersected );

	m_fAlphaMultiplier = x;
	glPopAttrib();
}

//jednoduche ovladani
bool CBasePanel::inputController( int type, float x, float y, int param1, int param2 )
{
	if( type == GFG_LOST_FOCUS || type == GFG_GOT_FOCUS  )
	{
		if( type == GFG_LOST_FOCUS )
			m_bFocused = false;
		else
			m_bFocused = true;
		if( m_pComponent )
			m_pComponent->inputController( type,  x,  y,  param1,  param2 );
	}

	if( !m_bVisible || !m_bEnabled || m_bTemporaryDisabled )
		return false;

	bool bValue = false;
	
	if( type == GFG_MOUSE_BUTTON && param2 == GFG_DOWN )
	{
		bValue |= checkMouseArea( x, y );
	}
	else if( type == GFG_MOUSE_OVER )
	{
		if( m_bMouseOver = (checkMouseArea( x, y ) && param1) )
		{
			bValue |= m_bMouseOver;
		}
	}

	//a preda se komponente..GFG_MOUSE_OVER se predava pouze, pokud je pavel aktivni
	if( type != GFG_MOUSE_OVER || type == GFG_MOUSE_OVER && m_bFocused )
		bValue |= m_pComponent && m_pComponent->inputController( type, x, y, param1, param2 );
	
	return bValue;
}

