// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include "CGUIMessageBox.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "IGUIButton.h"
#include "IGUIFont.h"

namespace irr
{
namespace gui
{

//! constructor
CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption,
	const wchar_t* text, s32 flags,
	IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: CGUIWindow(environment, parent, id, rectangle), StaticText(0),
  OkButton(0), YesButton(0), NoButton(0), CancelButton(0)
{
	#ifdef _DEBUG
	setDebugName("CGUIMessageBox");
	#endif

	// remove focus
	Environment->setFocus(0);

	// remove buttons

	getMaximizeButton()->remove();
	getMinimizeButton()->remove();

	if (caption)
		setText(caption);

	IGUISkin* skin = Environment->getSkin();

	s32 buttonHeight = skin->getSize(EGDS_BUTTON_HEIGHT);
	s32 buttonWidth = skin->getSize(EGDS_BUTTON_WIDTH);
	s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2;
	s32 buttonDistance = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);

	// add static multiline text

	core::dimension2d<s32> dim(AbsoluteClippingRect.getWidth() - buttonWidth,
		AbsoluteClippingRect.getHeight() - (buttonHeight * 3));
	core::position2d<s32> pos((AbsoluteClippingRect.getWidth() - dim.Width) / 2,
		buttonHeight / 2 + titleHeight);

	StaticText = Environment->addStaticText(text, 
		core::rect<s32>(pos, dim), false, false, this);
	StaticText->setWordWrap(true);
	StaticText->grab();

	// adjust static text height

	s32 textHeight = StaticText->getTextHeight();
	core::rect<s32> tmp = StaticText->getRelativePosition();
	tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + textHeight;
	StaticText->setRelativePosition(tmp);
	dim.Height = textHeight;

	// adjust message box height

	tmp = getRelativePosition();
	s32 msgBoxHeight = textHeight +	(s32)(2.5f * buttonHeight) + titleHeight;

	// adjust message box position

	tmp.UpperLeftCorner.Y = (parent->getAbsolutePosition().getHeight() - msgBoxHeight) / 2;
	tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + msgBoxHeight;
	setRelativePosition(tmp);
	

	// add buttons

	s32 countButtons = 0;
	if (flags & EMBF_OK) ++countButtons;
	if (flags & EMBF_CANCEL) ++countButtons;
	if (flags & EMBF_YES) ++countButtons;
	if (flags & EMBF_NO) ++countButtons;

	core::rect<s32> btnRect;
	btnRect.UpperLeftCorner.Y = pos.Y + dim.Height + buttonHeight / 2;
	btnRect.LowerRightCorner.Y = btnRect.UpperLeftCorner.Y + buttonHeight;
	btnRect.UpperLeftCorner.X = (AbsoluteClippingRect.getWidth() - 
		((buttonWidth + buttonDistance)*countButtons)) / 2;
	btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + buttonWidth;

	// add ok button
	if (flags & EMBF_OK)
	{
		OkButton = Environment->addButton(btnRect, this);
		OkButton->setText(skin->getDefaultText(EGDT_MSG_BOX_OK));
		OkButton->grab();

		btnRect.LowerRightCorner.X += buttonWidth + buttonDistance;
		btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance;

		Environment->setFocus(OkButton);
	}

	// add yes button
	if (flags & EMBF_YES)
	{
		YesButton = Environment->addButton(btnRect, this);
		YesButton->setText(skin->getDefaultText(EGDT_MSG_BOX_YES));
		YesButton->grab();

		btnRect.LowerRightCorner.X += buttonWidth + buttonDistance;
		btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance;
	}

	// add no button
	if (flags & EMBF_NO)
	{
		NoButton = Environment->addButton(btnRect, this);
		NoButton->setText(skin->getDefaultText(EGDT_MSG_BOX_NO));
		NoButton->grab();

		btnRect.LowerRightCorner.X += buttonWidth + buttonDistance;
		btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance;
	}

	// add cancel button
	if (flags & EMBF_CANCEL)
	{
		CancelButton = Environment->addButton(btnRect, this);
		CancelButton->setText(skin->getDefaultText(EGDT_MSG_BOX_CANCEL));
		CancelButton->grab();

		btnRect.LowerRightCorner.X += buttonWidth + buttonDistance;
		btnRect.UpperLeftCorner.X += buttonWidth + buttonDistance;
	}


}


//! destructor
CGUIMessageBox::~CGUIMessageBox()
{
	if (StaticText)
		StaticText->drop();

	if (OkButton)
		OkButton->drop();

	if (CancelButton)
		CancelButton->drop();

	if (YesButton)
		YesButton->drop();

	if (NoButton)
		NoButton->drop();
}


//! called if an event happened.
bool CGUIMessageBox::OnEvent(SEvent event)
{
	SEvent outevent;
	outevent.EventType = EET_GUI_EVENT;
	outevent.GUIEvent.Caller = this;

	switch(event.EventType)
	{
	case EET_GUI_EVENT:
		if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
		{
			if (event.GUIEvent.Caller == OkButton)
			{
				outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
				Parent->OnEvent(outevent);
				remove();
				return true;
			}
			else
			if (event.GUIEvent.Caller == CancelButton || 
				event.GUIEvent.Caller == CloseButton)
			{
				outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
				Parent->OnEvent(outevent);
				remove();
				return true;
			}
			else
			if (event.GUIEvent.Caller == YesButton)
			{
				outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
				Parent->OnEvent(outevent);
				remove();
				return true;
			}
			else
			if (event.GUIEvent.Caller == NoButton)
			{
				outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
				Parent->OnEvent(outevent);
				remove();
				return true;
			}
		}
		break;
	}

	return CGUIWindow::OnEvent(event);
}


} // end namespace gui
} // end namespace irr
