//	FreetypeFontAtlas.h - Uses freetype to generate a font atlas.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef FREETYPEFONTATLAS_H_
#define FREETYPEFONTATLAS_H_

#include "FontAtlas.h"

#include "ft2build.h"
#include FT_FREETYPE_H

#include <stdint.h>

///	Uses freetype to generate a font atlas.
class FreetypeFontAtlas : public FontAtlas
{
  public:
	///	Constructor.
	/*!
		\param fontFile The font file to load the font from.
		\param fontSize The size of the rendered font, in points.
		\param metrics The metrics object to fill with the metrics for each
		glyph in the font.
		\param instanceName The name of this font instance.
	 */
	FreetypeFontAtlas(const FilePath& fontFile,
					  float fontSize,
					  FontMetrics& metrics,
					  const std::wstring& instanceName);
	///	Destructor.
	~FreetypeFontAtlas();
	
	///	Used to load a glyph missing from the passed-in FontMetrics.
	void getMissingGlyphData(wchar_t missingCharacter,
							 FontMetrics& metrics,
							 AtlasImage **atlasImage,
							 unsigned char **imageData,
							 int& imageWidth,
							 int& imageHeight,
							 bool& needNewAtlas);

	///	Returns the dimensions of the atlas texture.
	/*!
		FontAtlases are assumed to be square.
	 */
	int getAtlasDimensions() const {return atlasSize;};

	///	The Freetype atlas Creator class.
	class Creator : public FontAtlas::Creator
	{
		///	Returns a new instance of FreetypeFontAtlas.
		FontAtlasPtr createInstance(const FilePath& fontFile,
								    float fontSize,
								    FontMetrics& metrics,
									const std::wstring& instanceName) {return FontAtlasPtr(new FreetypeFontAtlas(fontFile, fontSize, metrics, instanceName));};
	};

	///	The Freetype atlas Creator.
	static Creator creator;
  private:
	///	Helper method. Draws an FT_Bitmap structure to our image buffer.
	void drawFTBitmap(FT_Bitmap& bitmap, int x, int y);
	///	Helper method. Draws an FT_Bitmap structure to a temporary image buffer.
	void drawFTBitmap(FT_Bitmap& bitmap,
					  unsigned char *buffer,
					  int bufferPitch);

	///	Singleton class used to initialise the freetype library.
	class FreetypeSingleton
	{
	  public:
		///	Returns the sole FT_Library instance.
		static FT_Library& getLibrary();

		///	Returns the FT_Library of this singleton.
		FT_Library& getLib() {return library;};
	  private:
		///	Constructor.
		FreetypeSingleton();
		///	Destructor.
		~FreetypeSingleton();

		///	The FT_Library instance.
		FT_Library library;
	};

	///	The name of this font.
	std::wstring name;

	///	The font face.
	FT_Face fontFace;

	///	The size of the atlas in pixels (the atlas is square).
	int atlasSize;
	///	The height of a cell in the texture atlas.
	int lineHeight;
	///	The position of the last glyph in the atlas, plus its size.
	/*!
		New glyphs will be drawn at this position, unless they would
		go past the boundaries of the atlas.
	 */
	TwoFloats glyphsEnd;

	///	The atlas image data.
	unsigned char *imageData;
	///	The atlas image data size.
	int imageDataSize;

	///	The number of images within this atlas.
	int numImages;
	///	The images within this atlas.
	AtlasImage *images;

};

#endif
