#ifndef JSONTYPE_H
#define JSONTYPE_H

#include <string>
#include <list>
#include <map>
#include <vector>

using std::string;
using std::list;
using std::vector;
using std::map;

class JsonType;

typedef list<JsonType> JsonList;
typedef vector<JsonType> JsonVector;
typedef map<JsonType, JsonType> JsonMap;

class JsonType {
public:
	JsonType() : m_type(JsonType::VoidType) {}

	JsonType(int num) : m_type(JsonType::NumberType), num_vale(num) {}

	JsonType(double fvalue) : m_type(JsonType::FloatType), float_value(fvalue) {}

	JsonType(bool bl) : m_type(JsonType::BooleanType), bl_value(bl) {}

	JsonType(const char *str) : m_type(JsonType::StringType), str_value(str) {}

	JsonType(const char *str, int len) : m_type(JsonType::StringType), str_value(str, len) {}

	JsonType(const string &str) : m_type(JsonType::StringType), str_value(str) {}

	JsonType(const JsonList &list) : m_type(JsonType::ListType), json_list(list) {}

	JsonType(const JsonVector &vec) : m_type(JsonType::VectorType), json_vec(vec) {}

	JsonType(const JsonMap &map) : m_type(JsonType::MapType), json_map(map) {}

	virtual ~JsonType() {}

	bool operator<(const JsonType &val) const {
		if (this->type() < val.type()) {
			return true;
		}
		else if (this->type() == val.type()) {
			switch (this->type()) {
			case JsonType::VoidType:
				return false;
				break;
			case JsonType::NumberType:
				return this->toNumber() < val.toNumber();
				break;
			case JsonType::FloatType:
				return this->toFloat() < val.toFloat();
				break;
			case JsonType::BooleanType:
				return this->toBoolean() < val.toBoolean();
				break;
			case JsonType::StringType:
				return this->toString() < val.toString();
				break;
			case JsonType::ListType:
				return this->toList() < val.toList();
				break;
			case JsonType::VectorType:
				return this->toVector() < val.toVector();
				break;
			case JsonType::MapType:
				return this->toMap() < val.toMap();
				break;
			default:
				break;
			}
		}
		return false;
	}

public:
	enum Type {
		VoidType, NumberType, FloatType, BooleanType, StringType, ListType, VectorType, MapType
	};

private:
	Type m_type;

	int		 num_vale;
	double   float_value;
	bool     bl_value;
	string   str_value;
	JsonList json_list;
	JsonVector json_vec;
	JsonMap  json_map;

public:
	Type type() const {
		return m_type;
	}

	int toNumber() const {
		return num_vale;
	}

	double toFloat() const {
		return float_value;
	}

	bool toBoolean() const {
		return bl_value;
	}

	string toString() const {
		return str_value;
	}

	JsonList toList() const {
		return json_list;
	}

	JsonMap toMap() const {
		return json_map;
	}

	JsonVector toVector() const {
		return json_vec;
	}
};


#endif // JSONTYPE_H
