/*
 * domains.hpp
 *
 *  Created on: May 19, 2017
 *      Author: vadims
 */

#pragma once


#include <iostream>
#include <string>
#include <map>
#include "InputValue.hpp"
#include "Material.hpp"
#include "topology/domainGroup.h"

typedef nlohmann::json json;


class Domains : public DomainGroup
{
public:

	struct domainType  // struct for available domain types
	{
		std::string key;
		std::vector<std::string> properties;
		std::vector<std::string> materialProps;
		domainType(std::string key_) : key(key_) {};
	};

	Domains(std::string, json, std::string);
	~Domains() { };

	Domains(const Domains& that);

	bool operator==(const Domains& rhs) const;
	static std::vector<domainType> existingDomainTypes;


	// get parameters
	int getId();
	std::string getName();
	std::string getTypeKey();
	std::string getSolverKey();
	int getMaterialId();
	std::map<std::string, InputValue> getProperties();
	std::map<std::string, InputValue> getInitialConditions();
	std::string getGroupKey();
	std::string getGeometryGroupKey();

	// returns value as string ( value or comma separated table)
	std::string getPropertyValue(std::string);

	void addProperty(std::string, InputValue);

	void addInitialCondition(std::string, InputValue);

	void setGroupKey(std::string);
	void setProperties(std::map<std::string, InputValue> props);
	bool isPointDomain();
	bool isNLDomain();
	bool isEnabled();

	// static method for adding existing domain types
	static void addDomainTypes(json inp);


	//TODO change from making copy to using pointers!
	void setMaterial(Material);
private:

	std::string typeKey;
	std::string solverKey;
	int materialId;
	Material material;
    std::map<std::string, InputValue> properties;
    std::map<std::string, InputValue> initialConditions;
    std::string groupKey, geometryGroupKey;
	bool pointDomain;
	bool enabled;
};
typedef std::shared_ptr<Domains> Domains_;

