#ifndef egl_Image_hpp
#define egl_Image_hpp

#include "Renderer/Surface.hpp"

#if defined(__ANDROID__)
#include <hardware/gralloc.h>
#include <system/window.h>
#endif

#include <assert.h>

namespace egl
{
// Types common between gl.h and gl2.h
// We can't include either header in EGL
typedef unsigned int GLenum;
typedef int GLint;
typedef int GLsizei;

class Texture;

class Image : public sw::Surface
{
public:
	Image(sw::Resource *resource, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, sw::Format internalFormat)
		: width(width), height(height), format(format), type(type), internalFormat(internalFormat), depth(depth)
		, sw::Surface(resource, width, height, depth, internalFormat, true, true)
	{
		shared = false;

		#if defined(__ANDROID__)
			nativeBuffer = 0;
			gralloc = 0;
		#endif
	}

	Image(sw::Resource *resource, int width, int height, int depth, sw::Format internalFormat, bool lockable, bool renderTarget)
		: width(width), height(height), format(0 /*GL_NONE*/), type(0 /*GL_NONE*/), internalFormat(internalFormat), depth(depth)
		, sw::Surface(resource, width, height, depth, internalFormat, lockable, renderTarget)
	{
		shared = false;

		#if defined(__ANDROID__)
			nativeBuffer = 0;
			gralloc = 0;
		#endif
	}

	GLsizei getWidth() const
	{
		return width;
	}

	GLsizei getHeight() const
	{
		return height;
	}

	int getDepth() const
	{
		// FIXME: add member if the depth dimension (for 3D textures or 2D testure arrays)
		// and multi sample depth are ever simultaneously required.
		return depth;
	}

	GLenum getFormat() const
	{
		return format;
	}

	GLenum getType() const
	{
		return type;
	}

	sw::Format getInternalFormat() const
	{
		return internalFormat;
	}

	bool isShared() const
    {
        return shared;
    }

    void markShared()
    {
        shared = true;
    }

	void *lock(unsigned int left, unsigned int top, sw::Lock lock)
	{
		#if defined(__ANDROID__)
			if(nativeBuffer)   // Lock the buffer from ANativeWindowBuffer
			{
				return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
			}
		#endif

		return lockExternal(left, top, 0, lock, sw::PUBLIC);
	}

	unsigned int getPitch() const
	{
		return getExternalPitchB();
	}

	void unlock()
	{
		#if defined(__ANDROID__)
			if(nativeBuffer)   // Unlock the buffer from ANativeWindowBuffer
			{
				return unlockNativeBuffer();
			}
		#endif

		unlockExternal();
	}

	virtual void addRef() = 0;
	virtual void release() = 0;
	virtual void unbind(const Texture *parent) = 0;   // Break parent ownership and release

	void destroyShared()   // Release a shared image
	{
		#if defined(__ANDROID__)
			if(nativeBuffer)
			{
				nativeBuffer->common.decRef(&nativeBuffer->common);
			}
		#endif

		assert(shared);
		shared = false;
		release();
	}

	virtual void loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint unpackAlignment, const void *input) = 0;
	virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels) = 0;

	#if defined(__ANDROID__)
	void setNativeBuffer(ANativeWindowBuffer* buffer)
	{
		nativeBuffer = buffer;
		nativeBuffer->common.incRef(&nativeBuffer->common);
	}

	virtual void *lockInternal(int x, int y, int z, sw::Lock lock, sw::Accessor client)
	{
		if(nativeBuffer)   // Lock the buffer from ANativeWindowBuffer
		{
			return lockNativeBuffer(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
		}
		return sw::Surface::lockInternal(x, y, z, lock, client);
	}

	virtual void unlockInternal()
	{
		if(nativeBuffer)   // Unlock the buffer from ANativeWindowBuffer
		{
			return unlockNativeBuffer();
		}
		return sw::Surface::unlockInternal();
	}
	#endif

protected:
	virtual ~Image()
	{
	}

	const GLsizei width;
	const GLsizei height;
	const GLenum format;
	const GLenum type;
	const sw::Format internalFormat;
	const int depth;

	bool shared;   // Used as an EGLImage

	#if defined(__ANDROID__)
	ANativeWindowBuffer *nativeBuffer;
	gralloc_module_t const *gralloc;

	void initGralloc()
	{
		hw_module_t const *module;
		hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
		gralloc = reinterpret_cast<gralloc_module_t const*>(module);
	}

	void* lockNativeBuffer(int usage)
	{
		if(!gralloc)
		{
			initGralloc();
		}

		void *buffer = 0;
		gralloc->lock(gralloc, nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
		return buffer;
	}

	void unlockNativeBuffer()
	{
		if(!gralloc)
		{
			initGralloc();
		}

		gralloc->unlock(gralloc, nativeBuffer->handle);
	}
	#endif
};
}

#endif   // egl_Image_hpp
