////////////////////////////////////////////////////////////////////////////////
// GLWindowContainer.h
// Copyright Bjoern Ganster
// Developed since 2006
////////////////////////////////////////////////////////////////////////////////

#include "GLWindowContainer.h"
#include "MechVM.h"

#define FILE_NUMBER FILE_NO_GLWINDOWCONTAINER_CPP

////////////////////////////////////////////////////////////////////////////////
// Constructor

GLWindowContainer::GLWindowContainer(const char* className, int class_ID, GLWindow* _parent, int _left, int _top, int _width, int _height)
: GLWindow(className, class_ID, _parent, _left, _top, _width, _height),
  focused(nullptr)
{
}

////////////////////////////////////////////////////////////////////////////////
// Destructor

GLWindowContainer::~GLWindowContainer()
{
}

////////////////////////////////////////////////////////////////////////////////
// Render

void GLWindowContainer::render(int x, int y, int w, int h)
{
	SET_SCOPE;
	for (size_t i = 0; i < windows.size(); i++) {
		GLWindow* win = windows[i];
		int ww = std::min (width, w - left);
		int wh = std::min (height, h - top);
		win->render (x+left, y+top, ww, wh);
	}
	RETURN;
}

////////////////////////////////////////////////////////////////////////////////
// Events

void GLWindowContainer::keypressed(BGKey /*key*/, bool /*shiftHeld*/, bool /*ctrlHeld*/, bool /*down*/, bool /*repeat*/)
{ }

GLWindow* GLWindowContainer::buttonStateChanged(int button, bool down, int x, int y)
{
	SET_SCOPE;
	size_t i;
	GLWindow* clicked = NULL;

	// Transform click coordinates to container's local coordinate system
	x -= left;
	y -= top;

	// Find clicked window
	for (i = 0; i < windows.size(); i++) {
		SET_OP;
		GLWindow* win = windows[i];
		if (win->getLeft () < x
			&&  x < win->getLeft () + win->getWidth ()
			&&  win->getTop () < y
			&&  y < win->getTop () + win->getHeight ())
		{
			clicked = win;
		}
	}

	SET_OP;
	if (clicked != nullptr && button == 1 && down) {
		focused = clicked;
	} else {
		focused = nullptr;
	}

	GLWindow* retVal = nullptr;
	if (clicked != NULL) {
		SET_OP;
		retVal = clicked->buttonStateChanged (button, down, x, y);
	}

	RETURN retVal;
}

void GLWindowContainer::mouseMoved (int /*x*/, int /*y*/)
{
}

////////////////////////////////////////////////////////////////////////////////
// Remove children

int GLWindowContainer::remove (GLWindow* win)
{
	SET_SCOPE;
	int deleted = 0;

	vector <GLWindow*>::iterator iter = windows.begin();
	while (iter != windows.end()) 
	{
		GLWindow* other = (*iter);
		if (other == win) {
			iter = windows.erase (iter);
			deleted++;
		} else {
			iter++;
		}
	}

	RETURN deleted;
}

// Remove all child windows
void GLWindowContainer::removeAll()
{
	SET_SCOPE;
	vector <GLWindow*>::iterator iter = windows.begin();
	MechVM* mechVm = getMechVm();
	while (iter != windows.end()) {
		GLWindow* window = *iter;
		if (window != nullptr) {
			mechVm->deleteLater(window);
		}
		++iter;
	}
	windows.clear();
	RETURN;
}

// Add/remove children
void GLWindowContainer::add (GLWindow* win)
{
	windows.push_back (win);
}

void GLWindowContainer::clear ()
{
	windows.clear();
}

size_t GLWindowContainer::getWindowCount () const
{
	return windows.size();
}

GLWindow* GLWindowContainer::getSubWin (size_t i)
{
	return windows[i];
}

const GLWindow* GLWindowContainer::getSubWin (size_t i) const 
{
	return windows[i];
}
