// ---------------------------------------------------------------------------
// 
//   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 WIDGETTEXT_H
#define WIDGETTEXT_H

#include "widget.h"

/// Simple (hah) text display. May be repurposed for text editing
/// later, too. Uses MalFont bitmap fonts. See MalFont and FontManager
/// for details on those.
///
/// Unique events:
///
///   onTextChanged
///
LUA_WRAP class WidgetText : public Widget {
	public:
		
		/// Get word wrapping.
		LUA_WRAP bool getWordWrap(void);
		
		/// Set word wrapping. Wraps at word boundaries if true.
		LUA_WRAP void setWordWrap(bool b);
		
		/// Get the current text buffer.
		LUA_WRAP const std::string &getText(void);
		
		/// Set the text buffer.
		LUA_WRAP void setText(const std::string &str);
		
		/// Get the font file name.
		LUA_WRAP const std::string &getFontName(void);
		
		/// Set the font file name.
		LUA_WRAP void setFontName(const std::string &newFont);
		
		/// Set the editable flag. (User can change this text.)
		LUA_WRAP void setEditable(bool editable);
		
		/// Get the editable flag.
		LUA_WRAP bool getEditable(void);
		
		/// Set the cursor position. (Will be clamped to the range of 0
		/// to text.size(), inclusive.)
		LUA_WRAP void setCursorPos(int newPos);
		
		/// Get the cursor position.
		LUA_WRAP int getCursorPos(void);
		
		/// Set the marked region.
		LUA_WRAP void setMark(int start, int end);
		
		/// Get marked region start.
		LUA_WRAP int getMarkStart(void);
		
		/// Get marked region end.
		LUA_WRAP int getMarkEnd(void);
		
		/// Set the text scale.
		LUA_WRAP void setScale(float scale);
		
		/// Get the text scale.
		LUA_WRAP float getScale(void);
		
		/// Set the color of the cursor.
		LUA_WRAP void setCursorColor(float r, float g, float b, float a);
		
		/// Set the color behind a marked text region.
		LUA_WRAP void setMarkColor(float r, float g, float b, float a);
		
		/// Sets this text entry to only take numbers.
		LUA_WRAP void setNumberOnly(bool numberOnly);
		
		/// Gets number-only attribute.
		LUA_WRAP bool getNumberOnly(void);
		
		// Constructors/destructors.
		WidgetText(void);
		WidgetText(TiXmlElement *xml);
		virtual ~WidgetText(void);
		
		// Inherited stuff.
		void draw(void);
		bool handleEvent(const WidgetEvent *event);

	private:
	
		void enforceNumberOnly(void);
	
		/// True of this text entry should only accept numbers.
		bool numberOnly;
	
		/// True if the next draw operation also needs to rebuild the
		/// display list.
		bool needsNewDisplayList;
	
		/// The current text buffer.
		std::string text;
		
		/// Font file name.
		std::string fontName;
		
		/// Text scaling amount.
		float scale;
		
		/// Word wrapping.
		bool wordWrap;
		
		/// Width of the widget when last drawn. If this changes by the
		/// next time it draws, it'll rebuild the display list.
		float lastDrawnWidth;
		
		/// Same as lastDrawnWidth, but may not be necessary to rebuild
		/// the display list for this.
		float lastDrawnHeight;
		
		/// My OpenGL display list.
		unsigned int displayList;
		
		/// True if you can type in this Widget.
		bool editable;
		
		// TODO: Make get/set for this...
		
		/// Location of the cursor for editing.
		int cursorPos;
		
		/// Just get the cursor to a known good value if it's not.
		void fixCursorPos(void);
		

		/// Start of text selection.
		int markStart;
		
		/// End of text selection.
		int markEnd;
		
		/// True if we're marking a selection with the mouse.
		bool marking;
		
		struct TextColor {
			float r;
			float g;
			float b;
			float a;
		};
		
		TextColor cursorColor;
		TextColor markColor;
};

#endif

