/*  $Id: menu_silver.cpp,v 1.5 2004/02/20 20:58:31 harry Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library 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
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
**
*/

#include "API/display.h"
#include "API/gui.h"
#include "API/core.h"  // ?

#include "API/GUIStyleSilver/menu_silver.h"
#include "API/GUI/menu.h"
#include "API/GUI/menu_node.h"

CL_Menu_Silver::CL_Menu_Silver(
	CL_Menu *menu,
	CL_StyleManager_Silver *style)
:
	CL_ComponentStyle(menu),
	menu(menu),
	style(style),
	repositioned(true)
{
	slots.connect(menu->sig_set_options(), this, &CL_Menu_Silver::on_set_options);
	slots.connect(menu->sig_paint(), this, &CL_Menu_Silver::on_paint);
	slots.connect(menu->sig_reposition(), this, &CL_Menu_Silver::on_reposition);

	if( menu->get_parent_node() == 0 )
	{
		slots.connect(menu->get_parent()->sig_resize(), this, &CL_Menu_Silver::on_parent_resize);
		repositioned = false;
	}
}

CL_Menu_Silver::~CL_Menu_Silver()
{
}

void CL_Menu_Silver::on_set_options(const CL_DomElement &options)
{
	// ?
}

void CL_Menu_Silver::on_paint()
{
	// reposition
	if( !repositioned )
	{
		menu->reposition();
		repositioned = true;
	}

	CL_Rect area( 0, 0, menu->get_width(), menu->get_height() );
	
	if( !menu->is_vertical() )
	{
		CL_Display::fill_rect(
			area,
			CL_Gradient(
				CL_Color::silver,CL_Color::silver,
				CL_Color::white, CL_Color::white )
		);

		CL_Display::fill_rect(
			CL_Rect( area.left, area.bottom-3, area.right, area.bottom ),
			CL_Gradient(
				CL_Color::white, CL_Color::white,
				CL_Color::silver, CL_Color::silver)
		);

		CL_Display::draw_rect( area, CL_Color(128,128,128,128) );

	}
	else
	{
		// full cover gradient
		CL_Display::fill_rect(
			area,	
			CL_Gradient(
				CL_Color::white, CL_Color::white,
				CL_Color::silver,CL_Color::silver ));

		// left side gradient 
		CL_Display::fill_rect(
			CL_Rect(area.left, area.top, area.left+3, area.bottom),	
			CL_Gradient(
				CL_Color::silver,CL_Color::silver,
				CL_Color::white, CL_Color::white ));
	
		// icon area gradient
		CL_Display::fill_rect(
			CL_Rect(area.left+3, area.top, area.left+3+17, area.bottom),	
			CL_Gradient(
				CL_Color::white, CL_Color::lightgray,
				CL_Color::white, CL_Color::lightgray ));


		CL_Display::draw_rect( area, CL_Color(0,0,0,128) );
	}
		
}

void CL_Menu_Silver::on_reposition(int pos_x, int pos_y)
{
	menu->raise(); // make menu be on top of other components.

	int items_width = menu->get_items_width() + 4;
	if( items_width < 90 )
		items_width = 90;

	int items_height = menu->get_items_height();
	if( items_height < 20 )
		items_height = 20;

	CL_Rect menu_rect(
		pos_x, pos_y,
		pos_x + items_width + 3,
		pos_y + items_height );
	
	if( menu->is_auto_resize() )
	{
		menu->set_position( menu_rect );
	}
	
	std::list<CL_MenuNode*> &children = menu->get_node_list();

	if( !children.empty() )
	{
		int X=2, Y=1;
		
		// calculate a new position for each menu node, and 
		// update the positions of all submenus.
		std::list<CL_MenuNode*>::iterator it;
		for( it = children.begin(); it != children.end(); ++it )
		{
			CL_Component *item = (*it)->get_data();
			const CL_Rect &ipos = item->get_position();

			(*it)->set_position(
				CL_Rect(
					X, Y,
					menu->is_vertical() ? X + items_width : X + item->get_width(),
					Y + ipos.top + item->get_height() + 4 ));

			if( menu->is_vertical() )
			{
				// don't resize elements not placed originally at (0,0) or (1,0)
				if( ipos.top == 0 && ipos.left == 0 )
					item->set_position(1,0);
			}
			else
				item->set_position(0,0);
			
			(*it)->reposition_submenus();
			
			if( menu->is_vertical() )
				Y += ipos.top + item->get_height() + 4;
			else
				X += ipos.left + item->get_width() + 4;
		}
	}	

	if( menu->is_auto_resize() )
	{
		CL_Rect child_rect = menu->get_children_rect();

		if( menu->is_vertical() )
			menu->set_width(child_rect.right);
		else
			menu->set_width(menu->get_parent()->get_width());

		menu->set_height(child_rect.bottom+2);
	}

}

void CL_Menu_Silver::on_parent_resize(int old_size_x, int old_size_y)
{
	if( menu->is_vertical() || !menu->is_auto_resize() )
		return;
	
	menu->set_width( menu->get_parent()->get_width() );
}
