#ifndef OpenTestSystem_OtxDiagManager_Common_ParameterData_H
#define OpenTestSystem_OtxDiagManager_Common_ParameterData_H

#include <string>
#include <vector>
#include <map>
#include "ProtoClasses.h"
#include "CommonClasses.h"
#include "ParameterValueType.h"
namespace OpenTestSystem
{
	namespace OtxDiagManager
	{
		namespace Common
		{
			enum ExceptionTypesPb : int;
			class ParameterData
			{
			public:
				ParameterData();
				virtual ~ParameterData();
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">String Value.</param>	
				void SetValue(const std::string& value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">Integer Value.</param>	
				void SetValue(int value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">Boolean Value.</param>		
				void SetValue(bool value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">Double Value.</param>	
				void SetValue(double value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">List Value.</param>	
				void SetValue(const std::vector<Parameter>& value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">Map Value.</param>	
				void SetValue(const std::map<std::string, Parameter>& value);
				/// <summary>
				/// Set parameter value.
				/// </summary>
				/// <param name="value">Bytefield Value.</param>	
				void SetBytesValue(const std::string& value);
				/// <summary>
				/// Set exception data into parameter.
				/// </summary>
				/// <param name="errorcode">Exception error code.</param>
				/// <param name="type">Exception type. E.g: UnknownException = 0; InvalidReferenceException = 1; OutOfBoundsException = 2; TypeMismatchException = 3; ...</param>
				/// <param name="message">Exception message.</param>
				void SetExceptionData(int errorcode, ExceptionTypesPb type, const std::string& message);
				/// <summary>
				/// Get parameter type.
				/// </summary>
				/// <returns>Parameter type. E.g: Unknown, String, Integer, ...</returns>
				ParameterValueType GetValueType();
				/// <summary>
				/// Get parameter value as String.
				/// </summary>
				/// <returns>Value as String</returns>
				std::string GetValueAsString();
				/// <summary>
				/// Get parameter value as Integer.
				/// </summary>
				/// <returns>Value as Integer</returns>
				int GetValueAsInt();
				/// <summary>
				/// Get parameter value as Boolean.
				/// </summary>
				/// <returns>Value as Boolean</returns>
				bool GetValueAsBool();
				/// <summary>
				/// Get parameter value as Double.
				/// </summary>
				/// <returns>Value as Double</returns>
				double GetValueAsDouble();
				/// <summary>
				/// Get parameter value as Bytefield.
				/// </summary>
				/// <returns>Value as Bytefield</returns>
				std::string GetValueAsBytes();
				/// <summary>
				/// Get parameter value as List.
				/// </summary>
				/// <returns>Value as List</returns>
				std::vector<Parameter>& GetValueAsList();
				/// <summary>
				/// Get parameter value as Map.
				/// </summary>
				/// <returns>Value as Map</returns>
				std::map<std::string, Parameter>& GetValueAsMap();
				/// <summary>
				/// Get exception data from parameter.
				/// </summary>
				/// <param name="errorcode">Exception error code.</param>
				/// <param name="type">Exception type. E.g: UnknownException = 0; InvalidReferenceException = 1; OutOfBoundsException = 2; TypeMismatchException = 3; ...</param>
				/// <param name="message">Exception message.</param>
				void GetExceptionData(int& errorcode, ExceptionTypesPb& type, std::string& message);

			protected:
				void ThrowIfNoMatch(ParameterValueType desiredType);

				std::string _string;
				int _int;
				bool _bool;
				double _double;
				std::string _bytes;
				ParameterValueType _type;
				int _exceptionErrorcode;
				ExceptionTypesPb _exceptionType;
				std::string _exceptionMessage;
				std::vector<Parameter> _list;
				std::map<std::string, Parameter> _map;
			};
		}
	}
}
#endif // OpenTestSystem_OtxDiagManager_Common_ParameterData_H
