#ifndef CIVASSEMBLY_H
#define CIVASSEMBLY_H
#include "CivTypes.h"
#include <list>
#include "pandaDbManager.h"

#pragma warning(disable:4251)

#define Str std::string 

class CivAssembly;
class CivNode;
class CivPipe;
class CivTank;
class CivValve;
class CivPumps;
class CivEmitters;
class CivCoordinates;
class CivMixing;
class CivLabels;
class CivTags;

/**
	 管网基本组件
*/
class CivAssembly
{
};

/**
   节点类型
 */
class PANDADBMANAGER_API CivNode: public CivAssembly
{
public:
	typedef struct  Table
	{
		// ; ID   Elev  Demand  	Pattern
		Str ID;
		Str Elev;
		Str Demand;
		Str PatternId;
	}  NodeTable;

	void addItem(const NodeTable& table);
	std::list<NodeTable> mTables;
};

/**
 * 管线类型
 */
class PANDADBMANAGER_API CivPipe: public CivAssembly
{
public:
	typedef struct  Table
	{
		// ; ID  Node1   Node2   Length   Diameter  	Roughness  MinorLoss  Status
		Str ID;
		Str Node1;
		Str Node2;
		Str Length;
		Str Diameter;
		Str Roughness;
		Str MinorLoss;
		Str Status;
		Str code;
	}  PipesTable;

	void addItem(const PipesTable& table);
	std::list<PipesTable> mTables;
};


/*
水池类型
*/
class PANDADBMANAGER_API CivTank:public CivAssembly
{
public:
	typedef struct  Table
	{
		// ; ID   Elevation  InitLevel  MinLevel   MaxLevel   Diameter   MinVol   VolCurve
		Str ID;
		Str Elev;
		Str InitLevel;
		Str MinLevel;
		Str MaxLevel;
		Str Diameter;
		Str MinVol;
		Str VolCurve;
	}  TankTable;

	void addItem(const TankTable& table);
	std::list<TankTable> mTables;
};

/*
 定义包含在管网中所有控制阀门。
*/
class PANDADBMANAGER_API CivValve :public CivAssembly
{
public:
	typedef struct  Table
	{
		Str ID;
		Str Node1;
		Str Node2;
		Str Diameter;
		Str Type;
		Str Setting;
		Str MinorLoss;
	}  ValveTable;

	void addItem(const ValveTable& table);

	std::list<ValveTable> mTables;
};

/**
  水泵
*/
class PANDADBMANAGER_API CivPumps :public CivAssembly
{
public:
	typedef struct  Table
	{
		// ;ID   Node1   Node2   Parameters
		Str ID;
		Str Node1;
		Str Node2;
		Str Parameters = "HEAD 1";
	}  PumpTable;

	void addItem(const PumpTable& table);
	std::list<PumpTable> mTables;
};

/*
定义管网中包含的所有水库节点
*/
class PANDADBMANAGER_API CivReservoirs :public CivAssembly
{
public:
	typedef struct  Table
	{
		/* 
			ID标签
			水头，ft(m)
			水头模式ID（可选）
		*/
		Str ID;
		Str Head;
		Str Pattern;
	}  ReservoirsTable;

	void addItem(const ReservoirsTable& table);

	std::list<ReservoirsTable> mTables;
};

/**
   EMITTERS将模拟节点定义为扩散器（喷嘴或者孔口）。
*/
class PANDADBMANAGER_API CivEmitters :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
			连接节点ID标签
			流量系数，在1米（1 psi）压降下的流量单位
		*/
		Str ID;
		Str coeff;
	}  EmittersTable;

	void addItem(const EmittersTable& table);
	std::list<EmittersTable> mTables;
};

/**
  坐标
*/
class PANDADBMANAGER_API CivCoordinates :public CivAssembly
{
public:
	typedef struct  Table
	{
		Str ID;
		Str XCoord;
		Str YCoord;
		Str code;
	}  CoordTable;

	

	void addItem(const CoordTable& table);
	std::list<CoordTable> mTables;
};

/**
	参数控制选项
*/
class PANDADBMANAGER_API  CivMixing :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
			水池ID标签
			混合模型（MIXED, 2COMP, FIFO或LIFO）
			室的容积（小数）
		*/
		Str ID;
		Str hyModel;
		Str volume;
	}  MixingTable;

	void addItem(const MixingTable& table);
	std::list<MixingTable> mTables;
};

/**
   确定控制蓄水池混合的模型。
*/
class PANDADBMANAGER_API  CivParameter :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
			[OPTIONS]
			[TIMES]
			[REACTIONS]
			[ENERGY] 
			[REPORT]
		*/
		Str name;
		Str val;

		bool operator==(const Table& oterhtable)
		{
			return name == oterhtable.name;
		}
	} ParamTable;

	void addItem(const ParamTable& table);
	void setType(const std::string& type) { mType = type; }

	void merge(const CivParameter& otherParam)
	{
		if (mType != otherParam.mType)
			return;

		std::list<ParamTable> tables = otherParam.mTables;
		for (auto iter = tables.begin(); iter != tables.end(); iter++)
		{
			std::string name = iter->name;
			std::list<ParamTable>::iterator findIter = std::find(mTables.begin(), mTables.end(),*iter);
			if (findIter == mTables.end())
			{
				mTables.push_back({ iter->name,iter->val });
				continue;
			}
			 findIter->val =iter->val;
		}

	}

	std::string mType;
	std::list<ParamTable> mTables;
};

/**
  模式
*/
class PANDADBMANAGER_API CivPatterns :public CivAssembly
{
public:
	typedef struct  Table
	{
		Str name; // 模式名
		Str val; // 模式值
	} PatternTable;

	void addItem(const PatternTable& table);
	std::list<PatternTable> mTables;
};

/*
	定义数据曲线及其X、Y点。
*/
class PANDADBMANAGER_API CivCurves :public CivAssembly
{
public:
	typedef struct  Table
	{
		Str ID; // 模式名
		Str XCoord; // X数值
		Str YCoord; // Y数值
	} CurvesTable;

	void addItem(const CurvesTable& table);
	std::list<CurvesTable> mTables;
};

/**
	定义连接节点的多模式需水，是对[JUNCTIONS]的补充。
*/
class PANDADBMANAGER_API CivDemands :public CivAssembly
{
public:
	typedef struct  Table
	{
		/* 
			连接节点ID标签；
		    基本需水量（流量单位）；
			需水量模式ID（可选）；
			分号之后的需水量类型名称（可选）
		*/
		Str ID; 
		Str BaseDemand; 
		Str PatternId; 
		Str DemandType;
	} DemandsTable;

	void addItem(const DemandsTable& table);
	std::list<DemandsTable> mTables;
};

// 定义水质源头的位置。
class PANDADBMANAGER_API  CivSources :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
		节点ID标签
        源头类型（CONCEN, MASS, FLOWPACED或SETPOINT）
        基准源头强度
        时间模式ID（可选）;Node  Type  Quality  Pattern
		*/
		Str ID;
		Str Type;
		Str Quality;
		Str Pattern;
	} CurvesTable;

	void addItem(const CurvesTable& table);
	std::list<CurvesTable> mTables;
};

// 定义模拟开始时被选管段的初始状态。
class PANDADBMANAGER_API CivStatus :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
		   管段ID标签
           状态或者设置 ID    Status/Setting
		*/
		Str ID;
		Str Setting;
	} StatusTable;

	void addItem(const StatusTable& table);
	std::list<StatusTable> mTables;
};

// 定义节点的初始水质。
class PANDADBMANAGER_API CivQuality :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
		    节点ID标签
            初始水质
		*/
		Str ID;
		Str InitQuality;
	} QualityTable;

	void addItem(const QualityTable& table);
	std::list<QualityTable> mTables;
};

// 给地图标签赋以坐标值。
class  PANDADBMANAGER_API CivLabels :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
		  X坐标
		  Y坐标
		  双引号中的标签文本
		  锚定节点的ID标签（可选）
		*/
		Str XCoord;
		Str YCoord;
		Str Label;
		Str ID;
	} LabelTable;

	void addItem(const LabelTable& table);

	std::list<LabelTable> mTables;
};

// 将类型标签与特定节点和管段相连。
class PANDADBMANAGER_API CivTags :public CivAssembly
{
public:
	typedef struct  Table
	{
		/*
		   关键词为NODE或者LINK
		   节点或者管段ID标签
		   标签的文本（无空格）
		*/
		Str Key;
		Str Id;
		Str Label;
	} TagsTable;

	void addItem(const TagsTable& table);
	std::list<TagsTable> mTables;
};

#endif // !CIVASSEMBLY_H

