// ---------------------------------------------------------------------------
// 
//   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 -------------------------------------

#pragma once

#include <string>
#include <map>

#include "../3rdparty/tinyxml/tinyxml.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

/** @brief A nice way of storing Lua values so we can worry a little
 * less about type issues in our C++/Lua interactions. */
class LuaValue {
	public:
	
		/** @brief Constructor (number).
		 *  @param n The number to create the value from.
		 */
		LuaValue(double n);
		
		/** @brief Constructor (string).
		 *  @param str The string to initialize to.
		 */
		LuaValue(const std::string &str);
		
		/** @brief Constructor (xml).
		 *  @param xml Pointer to a TiXmlElement for an attribute tag.
		 */
		LuaValue(TiXmlElement *xml);
		
		/** @brief Constructor (boolean).
		 *  @param b The initial value.
		 */
		LuaValue(bool b);
		
		/** @brief Default constructor.
		 * Initializes it to a nil value.
		 */
		LuaValue(void);
		
		/** @brief Constructor that pulls a value from the stack.
		 *  @param L The lua_State to grab from.
		 *  @param index The stack position.
		 */
		LuaValue(lua_State *L, int index);
	
		/** @brief Convert this value to a string.
		 *  @return A string representation of this value.
		 */
		std::string toString(void);
		
		/** @brief Convert this value to a number.
		 *  @return A number value.
		 */
		double toNumber(void);
		
		/** @brief Convert this value to a boolean.
		 *  The only values that result in false are a boolean false,
		 *  numerical 0, or strings of "FALSE", "false", "0", or "".
		 *  @return false for a specific set of values, true for others.
		 */
		bool toBool(void);
		
		/** @brief Get the type of the actual value here.
		 *  @return One of LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, or
		 *  LUA_TSTRING.
		 */
		int getType(void);
		
		/** @brief Get the type as a string.
		 *  @return The Lua type as a string.
		 */
		std::string getTypeString(lua_State *L);
		
		/** @brief Push this value onto a Lua stack.
		 *  @param L The lua_State.
		 */
		void push(lua_State *L);
		
	private:
	
		int type; // Type, as a Lua constant (LUA_TSTRING, etc)
		
		// These are all where the actual value gets stored.
		double numberValue;
		std::string stringValue;
		bool boolValue;
};


