/*-------------------------------------------------------------------------
 * 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 X11Egl Display Factory.
 *//*--------------------------------------------------------------------*/

#include "tcuLnxX11EglDisplayFactory.hpp"
#include "tcuLnxX11.hpp"
#include "egluGLContextFactory.hpp"
#include "eglwLibrary.hpp"
#include "eglwFunctions.hpp"
#include "eglwEnums.hpp"
#include "deUniquePtr.hpp"

namespace tcu
{
namespace lnx
{
namespace x11
{
namespace egl
{

typedef ::Display*	EGLNativeDisplayType;
typedef ::Pixmap	EGLNativePixmapType;
typedef ::Window	EGLNativeWindowType;

DE_STATIC_ASSERT(sizeof(EGLNativeDisplayType)	<= sizeof(eglw::EGLNativeDisplayType));
DE_STATIC_ASSERT(sizeof(EGLNativePixmapType)	<= sizeof(eglw::EGLNativePixmapType));
DE_STATIC_ASSERT(sizeof(EGLNativeWindowType)	<= sizeof(eglw::EGLNativeWindowType));

extern "C"
{

typedef EGLW_APICALL	eglw::EGLDisplay	(EGLW_APIENTRY* eglX11GetDisplayFunc)			(EGLNativeDisplayType display_id);
typedef EGLW_APICALL	eglw::EGLBoolean	(EGLW_APIENTRY* eglX11CopyBuffersFunc)			(eglw::EGLDisplay dpy, eglw::EGLSurface surface, EGLNativePixmapType target);
typedef EGLW_APICALL	eglw::EGLSurface	(EGLW_APIENTRY* eglX11CreatePixmapSurfaceFunc)	(eglw::EGLDisplay dpy, eglw::EGLConfig config, EGLNativePixmapType pixmap, const eglw::EGLint* attrib_list);
typedef EGLW_APICALL	eglw::EGLSurface	(EGLW_APIENTRY* eglX11CreateWindowSurfaceFunc)	(eglw::EGLDisplay dpy, eglw::EGLConfig config, EGLNativeWindowType win, const eglw::EGLint* attrib_list);

}

using std::string;

using de::MovePtr;
using de::UniquePtr;
using glu::ContextFactory;
using eglu::GLContextFactory;
using eglu::NativeDisplay;
using eglu::NativeDisplayFactory;
using eglu::NativeWindow;
using eglu::NativeWindowFactory;
using eglu::NativePixmap;
using eglu::NativePixmapFactory;
using eglu::WindowParams;
using tcu::TextureLevel;

class Library : public eglw::DefaultLibrary
{
public:
	Library (void)
		: eglw::DefaultLibrary("libEGL.so")
	{
	}

	eglw::EGLBoolean copyBuffers (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLNativePixmapType target) const
	{
		return (m_egl.copyBuffers)(dpy, surface, reinterpret_cast<EGLNativePixmapType*>(target));
	}

	eglw::EGLSurface createPixmapSurface (eglw::EGLDisplay dpy, eglw::EGLConfig config, eglw::EGLNativePixmapType pixmap, const eglw::EGLint *attrib_list) const
	{
		return (m_egl.createPixmapSurface)(dpy, config, reinterpret_cast<EGLNativePixmapType*>(pixmap), attrib_list);
	}

	eglw::EGLSurface createWindowSurface (eglw::EGLDisplay dpy, eglw::EGLConfig config, eglw::EGLNativeWindowType win, const eglw::EGLint *attrib_list) const
	{
		return (m_egl.createWindowSurface)(dpy, config, reinterpret_cast<EGLNativeWindowType*>(win), attrib_list);
	}

	eglw::EGLDisplay getDisplay (eglw::EGLNativeDisplayType display_id) const
	{
		return ((eglX11GetDisplayFunc)m_egl.getDisplay)(reinterpret_cast<EGLNativeDisplayType>(display_id));
	}
};

class Display : public NativeDisplay
{
public:
	static const Capability CAPABILITIES		= Capability(CAPABILITY_GET_DISPLAY_LEGACY |
															 CAPABILITY_GET_DISPLAY_PLATFORM_EXT);

								Display				(MovePtr<XlibDisplay> x11Display)
									: NativeDisplay	(CAPABILITIES,
													 EGL_PLATFORM_X11_EXT,
													 "EGL_EXT_platform_x11")
									, m_display		(x11Display) {}

	void*						getPlatformNative		(void)	{ return m_display->getXDisplay(); }
	eglw::EGLNativeDisplayType	getPlatformExtension	(void)	{ return reinterpret_cast<eglw::EGLNativeDisplayType>(m_display->getXDisplay()); }
	eglw::EGLNativeDisplayType	getLegacyNative			(void)	{ return reinterpret_cast<eglw::EGLNativeDisplayType>(m_display->getXDisplay()); }

	XlibDisplay&				getX11Display			(void)			{ return *m_display;	}
	const eglw::Library&		getLibrary				(void) const	{ return m_library;		}
	const eglw::EGLAttrib*		getPlatformAttributes	(void) const	{ return DE_NULL;		}

private:
	UniquePtr<XlibDisplay>		m_display;
	Library						m_library;
};

class Window : public NativeWindow
{
public:
	static const Capability	CAPABILITIES		= Capability(CAPABILITY_CREATE_SURFACE_LEGACY |
															 CAPABILITY_CREATE_SURFACE_PLATFORM |
															 CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION |
															 CAPABILITY_GET_SURFACE_SIZE |
															 CAPABILITY_SET_SURFACE_SIZE |
															 CAPABILITY_GET_SCREEN_SIZE);

								Window				(Display&				display,
													 const WindowParams&	params,
													 Visual*				visual);

	eglw::EGLNativeWindowType	getLegacyNative			(void) { return reinterpret_cast<eglw::EGLNativeWindowType>(m_window.getXID()); }
	void*						getPlatformExtension	(void) { return &m_window.getXID();	}
	void*						getPlatformNative		(void) { return &m_window.getXID();	}

	IVec2						getSurfaceSize		(void) const;
	void						setSurfaceSize		(IVec2 size);
	IVec2						getScreenSize		(void) const { return getSurfaceSize(); }

private:
	XlibWindow					m_window;
};

Window::Window (Display& display, const WindowParams& params, Visual* visual)
	: NativeWindow	(CAPABILITIES)
	, m_window		(display.getX11Display(), params.width, params.height, visual)
{
	m_window.setVisibility((params.visibility != WindowParams::VISIBILITY_HIDDEN));
}

IVec2 Window::getSurfaceSize (void) const
{
	IVec2 ret;
	m_window.getDimensions(&ret.x(), &ret.y());
	return ret;
}

void Window::setSurfaceSize (IVec2 size)
{
	m_window.setDimensions(size.x(), size.y());
}

class WindowFactory : public NativeWindowFactory
{
public:
						WindowFactory		(void);

	NativeWindow*		createWindow		(NativeDisplay*			nativeDisplay,
											 const WindowParams&	params) const;

	NativeWindow*		createWindow		(NativeDisplay*			nativeDisplay,
											 eglw::EGLDisplay		display,
											 eglw::EGLConfig		config,
											 const eglw::EGLAttrib*	attribList,
											 const WindowParams&	params) const;
};

WindowFactory::WindowFactory (void)
	: NativeWindowFactory ("window", "X11 Window", Window::CAPABILITIES)
{
}

NativeWindow* WindowFactory::createWindow (NativeDisplay*		nativeDisplay,
										   const WindowParams&	params) const
{
	Display&	display	= *dynamic_cast<Display*>(nativeDisplay);

	return new Window(display, params, DE_NULL);
}

NativeWindow* WindowFactory::createWindow (NativeDisplay*			nativeDisplay,
										   eglw::EGLDisplay			eglDisplay,
										   eglw::EGLConfig			config,
										   const eglw::EGLAttrib*	attribList,
										   const WindowParams&		params) const
{
	DE_UNREF(attribList);

	Display&		display		= *dynamic_cast<Display*>(nativeDisplay);
	eglw::EGLint	visualID	= 0;
	::Visual*		visual		= DE_NULL;
	nativeDisplay->getLibrary().getConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &visualID);

	if (visualID != 0)
		visual = display.getX11Display().getVisual(visualID);

	return new Window(display, params, visual);
}

#if 0
class Pixmap : public NativePixmap
{
public:
	enum {
		CAPABILITIES = (CAPABILITY_CREATE_SURFACE_LEGACY |
						CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION |
						CAPABILITY_READ_PIXELS)
	};

							Pixmap				(MovePtr<x11::Pixmap> x11Pixmap)
								: NativePixmap	(CAPABILITIES)
								, m_pixmap		(x11Pixmap) {}

	void*					getPlatformNative	(void) { return &m_pixmap.getXID(); }
	void					readPixels			(TextureLevel* dst);

private:
	UniquePtr<x11::Pixmap>	m_pixmap;
};

class PixmapFactory : public NativePixmapFactory
{
public:
					PixmapFactory	(void)
						: NativePixmapFactory ("pixmap", "X11 Pixmap", Pixmap::CAPABILITIES) {}

	NativePixmap*	createPixmap	(NativeDisplay* nativeDisplay,
									 int			width,
									 int			height) const;
};

NativePixmap* PixmapFactory::createPixmap (NativeDisplay* nativeDisplay,
										   int			width,
										   int			height) const

{
	Display*				display		= dynamic_cast<Display*>(nativeDisplay);
	MovePtr<x11::Pixmap>	x11Pixmap	(new x11::Pixmap(display->getX11Display(),
														 width, height));
	return new Pixmap(x11Pixmap);
}
#endif

class DisplayFactory : public NativeDisplayFactory
{
public:
						DisplayFactory		(EventState& eventState);

	NativeDisplay*		createDisplay		(const eglw::EGLAttrib* attribList) const;

private:
	EventState&			m_eventState;
};

DisplayFactory::DisplayFactory (EventState& eventState)
	: NativeDisplayFactory	("x11", "Native X11 Display",
							 Display::CAPABILITIES,
							 EGL_PLATFORM_X11_SCREEN_EXT,
							 "EGL_EXT_platform_x11")
	, m_eventState			(eventState)
{
	m_nativeWindowRegistry.registerFactory(new WindowFactory());
	// m_nativePixmapRegistry.registerFactory(new PixmapFactory());
}

NativeDisplay* DisplayFactory::createDisplay (const eglw::EGLAttrib* attribList) const
{
	DE_UNREF(attribList);

	//! \todo [2014-03-18 lauri] Somehow make the display configurable from command line
	MovePtr<XlibDisplay>	x11Display	(new XlibDisplay(m_eventState, DE_NULL));

	return new Display(x11Display);
}

NativeDisplayFactory* createDisplayFactory (EventState& eventState)
{
	return new DisplayFactory(eventState);
}

} // egl
} // x11
} // lnx
} // tcu
