/*-------------------------------------------------------------------------
 * 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 test activity.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidTestActivity.hpp"
#include "tcuAndroidUtil.hpp"

#include <android/window.h>

#include <string>
#include <stdlib.h>

using std::string;

namespace tcu
{
namespace Android
{

// TestThread

TestThread::TestThread (NativeActivity& activity, const std::string& cmdLineString, const CommandLine& cmdLine)
	: RenderThread	(activity)
	, m_cmdLine		(cmdLine)
	, m_platform	(activity)
	, m_archive		(activity.getNativeActivity()->assetManager)
	, m_log			(m_cmdLine.getLogFileName(), cmdLineString, m_cmdLine.getLogFlags())
	, m_app			(m_platform, m_archive, m_log, m_cmdLine)
	, m_finished	(false)
{
}

TestThread::~TestThread (void)
{
	// \note m_testApp is managed by thread.
}

void TestThread::run (void)
{
	RenderThread::run();
}

void TestThread::onWindowCreated (ANativeWindow* window)
{
	m_platform.getWindowRegistry().addWindow(window);
}

void TestThread::onWindowDestroyed (ANativeWindow* window)
{
	m_platform.getWindowRegistry().destroyWindow(window);
}

void TestThread::onWindowResized (ANativeWindow* window)
{
	DE_UNREF(window);
	print("Warning: Native window was resized, results may be undefined");
}

bool TestThread::render (void)
{
	if (!m_finished)
		m_finished = !m_app.iterate();
	return !m_finished;
}

// TestActivity

TestActivity::TestActivity (ANativeActivity* activity)
	: RenderActivity	(activity)
	, m_cmdLine			(getIntentStringExtra(activity, "cmdLine"))
	, m_testThread		(*this, getIntentStringExtra(activity, "cmdLine"), m_cmdLine)
	, m_started			(false)
{
	// Set initial orientation.
	setRequestedOrientation(getNativeActivity(), mapScreenRotation(m_cmdLine.getScreenRotation()));

	// Set up window flags.
	ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON	|
											 AWINDOW_FLAG_TURN_SCREEN_ON	|
											 AWINDOW_FLAG_FULLSCREEN		|
											 AWINDOW_FLAG_SHOW_WHEN_LOCKED, 0);
}

TestActivity::~TestActivity (void)
{
}

void TestActivity::onStart (void)
{
	if (!m_started)
	{
		setThread(&m_testThread);
		m_testThread.start();
		m_started = true;
	}

	RenderActivity::onStart();
}

void TestActivity::onDestroy (void)
{
	if (m_started)
	{
		setThread(DE_NULL);
		m_testThread.stop();
		m_started = false;
	}

	RenderActivity::onDestroy();

	// Kill this process.
	print("Done, killing process");
	exit(0);
}

void TestActivity::onConfigurationChanged (void)
{
	RenderActivity::onConfigurationChanged();

	// Update rotation.
	setRequestedOrientation(getNativeActivity(), mapScreenRotation(m_cmdLine.getScreenRotation()));
}

} // Android
} // tcu
