//
//  Value.hpp
//  Meteor
//
//  Created by Cesar Parent on 05/09/2015.
//  Copyright © 2015 Cesar Parent. All rights reserved.
//

#ifndef Value_hpp
#define Value_hpp

#include "../defines.h"
#include <string>
#include <vector>
#include <map>

NS_BEGIN

/*!
 * @brief       Defines the type of data held in a <code>Value</code> object.
 */
enum class ValueTag {
    /// @brief  Used for the Null value.
    None = 0,
    /// @brief  Boolean-holding value.
    Bool,
    /// @brief  Integer-holding value.
    Integer,
    /// @brief  Real Number-holding value.
    Real,
    /// @brief  String-holding value.
    String,
    /// @brief  Array-holding value.
    Array,
    /// @brief  Dict-holding value.
    Dictionary,
};


class Value {
    
    
    typedef std::vector<Value> Array;
    typedef std::map<std::string, Value> Dict;
    
public:
    
    static const Value Null;
    
    Value(ValueTag type = ValueTag::None);
    
    Value(bool value);
    
    Value(int value);
    
    Value(double value);
    
    Value(const std::string& value);
    
    Value(const char* value);
    
    Value(const Array& value);
    
    Value(const Dict& value);
    
    Value(const Value& rhs);
    
    Value&
    operator=(const Value& rhs);
    
    ~Value();
    
    bool
    boolValue() const;
    
    int
    integerValue() const;
    
    double
    realValue() const;
    
    
    std::string&
    stringValue() const;
    
    Array&
    arrayValue() const;
    
    Dict&
    dictionaryValue() const;
    
    ValueTag
    type() const;
    
private:
    
    ValueTag        _type;
    
    union {
        bool                _boolValue;
        int                 _integerValue;
        double              _realValue;
        std::string*        _stringValue;
        Array*              _arrayValue;
        Dict*               _dictValue;
    };
};

NS_END

#endif /* Value_hpp */
