/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Android window.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidWindow.hpp"

namespace tcu
{
namespace Android
{

using std::vector;

// Window

Window::Window (ANativeWindow* window)
	: m_window	(window)
	, m_state	(STATE_AVAILABLE)
{
}

Window::~Window (void)
{
}

void Window::setBuffersGeometry (int width, int height, int32_t format)
{
	ANativeWindow_setBuffersGeometry(m_window, width, height, format);
}

IVec2 Window::getSize (void) const
{
	const int32_t	width	= ANativeWindow_getWidth(m_window);
	const int32_t	height	= ANativeWindow_getHeight(m_window);
	return IVec2(width, height);
}

bool Window::tryAcquire (void)
{
	de::ScopedLock lock(m_stateLock);

	if (m_state == STATE_AVAILABLE)
	{
		m_state = STATE_IN_USE;
		return true;
	}
	else
		return false;
}

void Window::release (void)
{
	de::ScopedLock lock(m_stateLock);

	if (m_state == STATE_IN_USE)
	{
		// Reset buffer size and format back to initial state
		ANativeWindow_setBuffersGeometry(m_window, 0, 0, 0);

		m_state = STATE_AVAILABLE;
	}
	else if (m_state == STATE_PENDING_DESTROY)
		m_state = STATE_READY_FOR_DESTROY;
	else
		DE_FATAL("Invalid window state");
}

void Window::markForDestroy (void)
{
	de::ScopedLock lock(m_stateLock);

	if (m_state == STATE_AVAILABLE)
		m_state = STATE_READY_FOR_DESTROY;
	else if (m_state == STATE_IN_USE)
		m_state = STATE_PENDING_DESTROY;
	else
		DE_FATAL("Invalid window state");
}

bool Window::isPendingDestroy (void) const
{
	de::ScopedLock lock(m_stateLock);
	return m_state == STATE_PENDING_DESTROY;
}

bool Window::tryAcquireForDestroy (bool onlyMarked)
{
	de::ScopedLock lock(m_stateLock);

	if (m_state == STATE_READY_FOR_DESTROY ||
		(!onlyMarked && m_state == STATE_AVAILABLE))
	{
		m_state = STATE_ACQUIRED_FOR_DESTROY;
		return true;
	}
	else
		return false;
}

// WindowRegistry

WindowRegistry::WindowRegistry (void)
{
}

WindowRegistry::~WindowRegistry (void)
{
	for (vector<Window*>::const_iterator winIter = m_windows.begin(); winIter != m_windows.end(); winIter++)
	{
		Window* const window = *winIter;

		if (window->tryAcquireForDestroy(false))
			delete window;
		else
		{
			print("ERROR: Window was not available for deletion, leaked tcu::Android::Window!\n");
			DE_FATAL("Window leaked");
		}
	}
}

void WindowRegistry::addWindow (ANativeWindow* window)
{
	m_windows.reserve(m_windows.size()+1);
	m_windows.push_back(new Window(window));
}

void WindowRegistry::destroyWindow (ANativeWindow* rawHandle)
{
	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
	{
		Window* const window = m_windows[ndx];

		if (window->getNativeWindow() == rawHandle)
		{
			if (window->tryAcquireForDestroy(false))
			{
				delete window;
				m_windows[ndx] = m_windows.back();
				m_windows.pop_back();
			}
			else
				window->markForDestroy();

			return;
		}
	}

	throw tcu::InternalError("Window not registered", DE_NULL, __FILE__, __LINE__);
}

Window* WindowRegistry::tryAcquireWindow (void)
{
	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
	{
		Window* const window = m_windows[ndx];

		if (window->tryAcquire())
			return window;
	}

	return DE_NULL;
}

void WindowRegistry::garbageCollect (void)
{
	for (int ndx = 0; ndx < (int)m_windows.size(); ++ndx)
	{
		Window* const window = m_windows[ndx];

		if (window->tryAcquireForDestroy(true))
		{
			delete window;
			m_windows[ndx] = m_windows.back();
			m_windows.pop_back();
			ndx -= 1;
		}
	}
}

} // Android
} // tcu
