/******************************************************************************
*	File		-	Image.h
*	Author		-	Joey Pollack
*	Date		-	2019/07/17 (y/m/d)
*	Mod Date	-	2019/07/18 (y/m/d)
*	Description	-	Manage image data that can be rendered with OpenGL.
*					Use the Graphics class to create instances of Image.
******************************************************************************/

#include "image.h"
#include <cstring>
#include <utils/logger.h>

namespace lunarium
{
	
	Image::Image()
		: Asset(AssetType::ASSET_TYPE_IMAGE), mRawData(nullptr), mRawDataSize(0), mWidth(0), mHeight(0), mGLTextureID((unsigned)-1)
	{
	}

	Image::Image(unsigned char* data, int width, int height, ImageFormat format)
		: Asset(AssetType::ASSET_TYPE_IMAGE), mRawData(data), mRawDataSize(width * height), mWidth(width), mHeight(height), mGLTextureID((unsigned)-1)
	{
		mFormat = format;
		if (mFormat == ImageFormat::RGB)
		{
			mRawDataSize *= 3;
		}
		else if (mFormat == ImageFormat::RGBA)
		{
			mRawDataSize *= 4;
		}

	}

	Image::~Image()
	{
		delete[] mRawData;
		mRawData = nullptr;
	}

	
	Image::Image(const Image& rhs)
		: mRawData(nullptr), mRawDataSize(0), mWidth(0), mHeight(0)
	{
		*this = rhs;
	}

	const Image& Image::operator=(const Image& rhs)
	{
		if (this == &rhs)
		{
			return *this;
		}

		FreeRawData();
		mGLTextureID = rhs.mGLTextureID;
		mFormat = rhs.mFormat;
		mWidth = rhs.mWidth;
		mHeight = rhs.mHeight;
		mRawDataSize = rhs.mRawDataSize;

		mRawData = new unsigned char[mRawDataSize];
		memcpy(mRawData, rhs.mRawData, mRawDataSize);

		return *this;
	}

	
	void Image::SetData(unsigned char* data)
	{
		mRawData = data;
	}

	unsigned int  Image::GetGLTextureID() const
	{
		return mGLTextureID;
	}
	
	unsigned long long Image::GetGLTextureID64() const
	{
		return (unsigned long long) mGLTextureID;
	}
	
	int Image::GetWidth() const
	{
		return mWidth;
	}

	int Image::GetHeight() const
	{
		return mHeight;
	}

	ImageFormat Image::GetFormat() const
	{
		return mFormat;
	}

	const unsigned char* Image::GetData() const
	{
		return mRawData;
	}

	
	void Image::SetWidth(int width)
	{
		mWidth = width;
	}

	void Image::SetHeight(int height)
	{
		mHeight = height;
	}

	void Image::SetFormat(ImageFormat format)
	{
		mFormat = format;
	}

	void Image::SetGLTextureID(unsigned int id)
	{
		Logger::Debug(LogCategory::GRAPHICS, "GLTexture ID set for Image");
		mGLTextureID = id;
	}

	void Image::FreeRawData()
	{
		delete[] mRawData;
		mRawData = nullptr;

		mRawDataSize = 0;
	}
}
