// ---------------------------------------------------------------------------
// 
//   Lily Engine alpha
// 
//   Copyright (c) 2010 Clifford Jolly
//     http://cliffjolly.com
//     cliff@cliffjolly.com
// 
// ---------------------------------------------------------------------------
// 
//   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 2 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, write to the Free Software
//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
//   USA
// -------------------------- END HEADER -------------------------------------

#ifndef MALFONT_H
#define MALFONT_H

#include <string>

class Image;

// TODO: Rename MalFont to either Font or BitmapFont.

/** @brief A class to render SFont formatted fonts to OpenGL. (Uses no
 * SFont code!) This code is pretty old (excepting newer modifications),
 * but usable and stable. It's basically an OpenGL clone of SFont
 * ( http://www.linux-games.com/sfont ) with fewer features and written
 * entirely from scratch. It can use SFont formatted fonts, though and
 * the creation process of those is well documented.
 * */
class MalFont {
	public:
		/** @brief Constructor */
		MalFont(void);
	
		/** @brief Destructor */
		~MalFont(void);
	
		///////////////////////////////////////////////////////////////
		// DO NOT USE THE SAME TEXTURE FOR TWO FONTS //////////////////
		///////////////////////////////////////////////////////////////

		/** @brief Loads a font.
			@param fileName Name of the font file to load.
			@note Since SFont files don't conform to normal OpenGL
			  texture sizes and such, all of that is handled
			  automatically. However, the image must still be a 32-bit
			  alpha-enabled TGA file.
		*/
		void loadFont(const std::string &fileName);
		
		// TODO: Make this respect the value for maxYSize.
		// TODO: Marked area color setting.
		
		/** @brief Draws text on the screen or a surface.
			@param x x coordinate to start (px)
			@param y y coordinate to start (px)
			@param text The text to draw.
			@param maxXsize The maximum x-distance to go before word-wrapping.
			@param maxYsize The maximum y-distance to go before stopping.
			@param scale An arbitrary scaling amount.
			@param xSizePrinted Pointer to store the length of the longest line in pixels.
			@param ySizePrinted Pointer to store the height of the text block in pixels.
			@param wordWrap Turn on wordwrapping at maxXsize.
			@param cursorPos Position to draw the cursor at, or -1 for no cursor.
			@param markStart Beginning of marked text.
			@param markEnd End of marked text.
			@param skipBindTexture If true, will skip binding the OpenGL texture before drawing.
			@param cursorColor 4-element array representing RGBA for the cursor color. NULL for none.
			@param markColor 4-element array representing RGBA for the mark color. NULL for none.
		*/
		void drawText(
			float x,
			float y,
			const char *text,
			float maxXSize = -1,
			float maxYSize = -1,
			float scale = 1,
			float *xSizePrinted = NULL,
			float *ySizePrinted = NULL,
			bool wordWrap = false,
			int cursorPos = -1,
			int markStart = -1,
			int markEnd = -1,
			bool skipBindTexture = false,
			float *cursorColor = NULL,
			float *markColor = NULL);
			
		/**	@brief
			Sets the size of the spaces between characters. This is not
			defined in the SFont bitmap itself, so it must be set here.
			@param spaceSize The number of pixels between characters.
		*/
		void setSpaceSize(int spaceSize = 8);
		
		/** @brief 
			Sets the amount of pixels to subtract from letter widths to
			squish them together.
			@param squish The amount of pixels.
		*/
		void setSquish(int squish = 0);
	
		/// Same as setSquish, but for vertical spacing.
		void setVerticalSquish(int verticalSquish = 0);
	
		/// Bind the font texture. This ensures the texture is loaded
		/// and stuff too. Returns true on success, false if it
		/// couldn't bind for whatever reason.
		bool bindFontTexture(void);
		
		/// Create a word-wrapped buffer (with '\n' inserted at the
		/// right places to effectively wrap) for rendering.
		char *makeWordWrappedBuffer(
			const char *text,
			float maxWidth,
			float scale,
			const char **cursor = NULL,
			const char **markStart = NULL,
			const char **markEnd = NULL,
			float pointerX = 0,
			float pointerY = 0,
			int *pointerIndex = NULL,
			bool dontReallyWrap = false);
		
		/// Get the original Image for this font's texture.
		Image *getOriginalImage(void);
		
        /// Get the original image height.
        int getOrigHeight(void);

	private:
		
		/// Sets up the font from the Image. This WILL modify the Image
		/// to remove the pink pixels!
		void setImage(Image *image);
		
		struct MalFontCharacter {
			int start;
			int end;
		};
		
		MalFontCharacter characters[94];
		int squish;
		int verticalSquish;
		int spaceSize;
		int tex;
		int adjustedWidth;
		int adjustedHeight;
		int origHeight;
		
};

#endif
