/*********************************************************************
*	ProgressBar
*	SOURCE FILE
*	Autor:	Michal Jirouš
*	Datum: 3.7.2008
*	Soubor: progressbar.cpp
*	Popis: Indikator prubehu operace. Operuje s hodnotou (0-1), ktera udava podil
*			dokonceni. Hodnota vypisuje v procentech.
**********************************************************************/

#include "gfg.h"

Tabs::Tabs( float w, float h)
{
	baseInit( w, h );
	setPadding(1);
	m_iPanelIndex = 0;
	m_fCurrentXpos = 0;
	m_ColorBackGround = GFG_COLOR_TEXTBOX_START_LINE_MOUSEOVER;
	m_iObjectType = GFG_TABS;
}

bool Tabs::isFocusable()
{
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
		if( (*iter)->m_pComponent && (*iter)->m_pComponent->isFocusable() )
			return true;
	return false;

}

void Tabs::setPadding( float padding )
{
	m_fPaddingBottom = padding;
	m_fPaddingLeft = padding;
	m_fPaddingTop = GFG_TABS_HEIGHT + padding;
	m_fPaddingRight = padding;
	updateScissorBox();
}


//pridani noveho panelu, vraci ID
int Tabs::addPanel(std::string caption)
{
	m_Panels.push_front( new SinglePanel() );

	SwitchedButton *tmp = m_Panels.front()->m_Button;
	tmp = new SwitchedButton( GFG_TABS_MIN_WIDTH, GFG_TABS_HEIGHT );
	tmp->init();
	tmp->setPosition( m_fGlobalXpos + m_fCurrentXpos, m_fGlobalYpos + m_fHeight - GFG_TABS_HEIGHT );
	
	tmp->setCaption( caption, "REGULAR" );
	tmp->setTextureIdle( "GFG_TABBED_BUTTON" );
	tmp->setTexturePushed( "GFG_TABBED_BUTTON" );
	float width = GFG_TABS_MIN_WIDTH;
	if( !tmp->getCaption().empty() )
	{
		width = tmp->getCaption().m_pLineList->front().width * GFG_TABS_PANEL_CAPTION_WIDTH_MULTIPLICATOR;
		tmp->setWidth( width );
	}
	m_fCurrentXpos += width;
	m_Panels.front()->m_iIndex = m_iPanelIndex++;
	m_Panels.front()->m_Button = tmp;
	if( m_Panels.size() == 1 )	//tlacitko prvniho panelu musi byt stisknute,
		//protoze prvni panel je vzdy aktivni
	{
		//m_Panels.back()->m_Button->inputController( GFG_GOT_FOCUS, 0, 0, 0, 0 );
		m_Panels.back()->m_Button->setPushed( true );
	}
	else
	{
		m_Panels.front()->m_Button->setPushed( false );
		//m_Panels.front()->m_Button->inputController( GFG_LOST_FOCUS, 0, 0, 0, 0 );
	}
	return m_Panels.front()->m_iIndex;
}

//vsechny zpravy je treba predat i aktivnimu panelu
void Tabs::setAlphaMultiplier( float multiplier )
{
	m_fAlphaMultiplier = multiplier;
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		if( (*iter)->m_pComponent )
			(*iter)->m_pComponent->setAlphaMultiplier( multiplier );
	}
}

void Tabs::run()
{
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		if( (*iter)->m_pComponent )
			(*iter)->m_pComponent->run();
	}
}

//tato funkce je zde unikatni kvuli hornimu panelu zalozek
//void Tabs::updateScissorBox()
//{
//	float x_offset = m_fGlobalXpos + getFromRange( m_fPaddingLeft, 0, m_fWidth ) - m_ScissorBox.x;
//	m_ScissorBox.x += x_offset;
//	float y_offset = m_fGlobalYpos + getFromRange( m_fPaddingBottom, 0, m_fHeight ) - m_ScissorBox.y;
//	m_ScissorBox.y += y_offset;
//	float w_offset = getFromRange( m_fWidth - m_fPaddingLeft  - m_fPaddingRight,0,m_fWidth ) - m_ScissorBox.w;
//	m_ScissorBox.w += w_offset;
//	float h_offset =  getFromRange( m_fHeight - m_fPaddingBottom  - (m_fPaddingTop + GFG_TABS_HEIGHT) ,0,m_fHeight ) - m_ScissorBox.h;
//	m_ScissorBox.h += h_offset;
//	if( !compareFloats( x_offset, 0 ) || !compareFloats( y_offset, 0 ) )
//		onScissorBoxTranslate( x_offset, y_offset );
//	if( w_offset > 0 || h_offset > 0 || w_offset < 0 || h_offset < 0  )
//		onScissorBoxResize( w_offset, h_offset );
//}

//prirazeni komponenty panelu dle ID
void Tabs::setComponent(int panelID, CBaseComponent *component)
{
	if( panelID < 0 || panelID >= m_iPanelIndex || component == NULL )
		return;

	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		if( (*iter)->m_iIndex == panelID )	//musim e vseznamu panelu najit ten se zadanym ID
		{
			if( (*iter)->m_pComponent )
				delete (*iter)->m_pComponent;
			
			(*iter)->m_pComponent = component;
			(*iter)->m_pComponent->setPosition( m_ScissorBox.x, m_ScissorBox.y );
			(*iter)->m_pComponent->setSize( m_ScissorBox.w, m_ScissorBox.h );
			(*iter)->m_pComponent->setParent( this );
			//(*iter)->m_pComponent->inputController( GFG_GOT_FOCUS, 0, 0, 0, 0 );
		}
	}
}
bool Tabs::lostFocusForChilds()
{ 
	if( parent )
		return parent->lostFocusForChilds();
	return true;	
}


//pri vykreslovani nejdrive vykreslim sebe a pak teprve aktivni panel
void Tabs::draw( ScissorBox &scissorBox )
{
	if( !m_bVisible )
		return;

	glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_SCISSOR_BIT );
	glEnable(GL_BLEND);
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	
	ScissorBox intersected = m_ScissorBox.intersection( scissorBox );
	glScissor( (GLint)intersected.x, (GLint)intersected.y, (GLint)intersected.w, (GLint)(intersected.h+GFG_TABS_HEIGHT) );
	intersected.h += GFG_TABS_HEIGHT;
	if( m_Panels.empty() )
		return glPopAttrib();;

	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
		(*iter)->m_Button->draw( intersected );
	glScissor( (GLint)intersected.x, (GLint)intersected.y, (GLint)intersected.w, (GLint)intersected.h );
	
	
	
	
	glBegin( GL_LINE_STRIP );
		setColor( GFG_COLOR_SKIN_END_LINE );
		glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight*0.5f );
		setColor( m_ColorBackGround );
		glVertex2f( m_fGlobalXpos, m_fGlobalYpos + m_fHeight - GFG_TABS_HEIGHT  );
		glVertex2f( m_fGlobalXpos + m_fWidth, m_fGlobalYpos + m_fHeight - GFG_TABS_HEIGHT );
	glEnd();

	intersected.h -= GFG_TABS_HEIGHT ;
	
	if( !m_Panels.back()->m_pComponent )
		return glPopAttrib();

	glScissor( (GLint)intersected.x, (GLint)intersected.y, (GLint)intersected.w, (GLint)intersected.h );
	m_Panels.back()->m_pComponent->draw( intersected );


	
	glPopAttrib();

}

//ovladani teto komponentu
bool Tabs::thisController( int type, float x, float y, int param1, int param2 )
{
	if( type & GFG_MOUSE )
	{
		bool bTopPanel = x > m_fGlobalXpos && x < m_fGlobalXpos + m_fWidth && y < m_fGlobalYpos + m_fHeight && y > m_fGlobalYpos + m_fHeight - GFG_TABS_HEIGHT;

		if( type == GFG_MOUSE_OVER  )
		{
			for( list<SinglePanel*>::reverse_iterator iter = m_Panels.rbegin(); iter != m_Panels.rend(); iter++ )
			{
				if( (*iter)->m_Button->inputController( type, x, y, param1, param2 ) )
					param1 = 0;
			}
			return (param1 == 0);
		}
		else if( type == GFG_MOUSE_BUTTON && param2 == GFG_DOWN )
		{
			//pri kliknuti tlacitka mysi musim otestovat, zda se nekloklo 
			//na nejaky prepinac, protoze pak musim aktivovat prislusny panel
			for( list<SinglePanel*>::reverse_iterator iter = m_Panels.rbegin(); iter != m_Panels.rend(); iter++ )
			{
				if( (*iter) != m_Panels.back() && (*iter)->m_Button->inputController( type, x, y, param1, param2 ) )
				{
					m_Panels.back()->m_Button->inputController( GFG_LOST_FOCUS, 0, 0, 0, 0 );
					SinglePanel *tmp = (*iter);
					m_Panels.remove( tmp );
					
					tmp->m_Button->setPushed( true );
					m_Panels.back()->m_Button->setPushed( false );
					m_Panels.push_back( tmp );
					m_Panels.back()->m_Button->inputController( GFG_GOT_FOCUS, 0, 0, 0, 0 );
					return true;
				}

			}
		}
	}

	return false;
}

//zakladni ovladani
bool Tabs::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_Panels.empty() || !m_Panels.back()->m_pComponent)
			return false;
		return m_Panels.back()->m_pComponent->inputController( type, x, y, param1, param2 );
	}

	if( !m_bVisible || !m_bEnabled || m_bTemporaryDisabled || m_Panels.empty() )
		return false;

	bool bValue = thisController( type, x, y, param1, param2 );

	//ovladani aktivniho panelu
	bValue |= m_Panels.back()->m_pComponent && m_Panels.back()->m_pComponent->inputController( type, x, y, param1, param2 );
	return bValue;
}


Tabs::~Tabs()
{
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		delete (*iter);
	}
}

//komponenty v panelech maji vzdy stejnou velikost jak orezavaci box teto komponenty
void Tabs::onScissorBoxResize(float w_offset, float h_offset)
{
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		if( (*iter)->m_pComponent )
			(*iter)->m_pComponent->setSizeOffset( w_offset, h_offset);
		(*iter)->m_Button->setPositionOffset( 0, h_offset);
	}

}

//musim posunout vsechny komponenty
void Tabs::onScissorBoxTranslate(float offsetX, float offsetY)
{
	for( list<SinglePanel*>::iterator iter = m_Panels.begin(); iter != m_Panels.end(); iter++ )
	{
		if( (*iter)->m_pComponent )
			(*iter)->m_pComponent->setPositionOffset( offsetX, offsetY);
		(*iter)->m_Button->setPositionOffset( offsetX, offsetY);
	}
}


void Tabs::setTemporaryDisabled( bool disabled )
{
	m_bTemporaryDisabled = disabled;	
	if( !m_bEnabled )
		return;

	if( !m_Panels.empty() && m_Panels.back()->m_pComponent )
		m_Panels.back()->m_pComponent->setTemporaryDisabled( disabled );
}

void Tabs::setEnabled( bool enabled )
{
	if( m_bTemporaryDisabled )
	{
		m_bEnabled = enabled;
		return;
	}

	m_bEnabled = enabled;
	if( !m_Panels.empty() && m_Panels.back()->m_pComponent )
		m_Panels.back()->m_pComponent->setTemporaryDisabled( !enabled );
}

