#pragma once
#include <string>
#include <sstream>
#include <vector>
#include "CivTypes.h"

#define CivItem std::vector<std::string>
#define Civitems std::vector<CivItem>


// 模拟选项
struct Options {
	// 流量被表达的单位
	enum class  UNITS
	{
		LPS,//——升 / 秒
		LPM,//——升 / 分
		MLD,//——百万升 / 日
		CMH,//——立方米 / 小时
		CMG,//——立方米 / 日
		CFS,//——立方英尺 / 秒
		GPM,//——加仑 / 分
		MGD,//——百万加仑 / 日
		IMGD,//——英制MGD
		AFD,//——英亩 - 英尺 / 日
	};

	// 水头损失公式
	enum class  HEADLOSS {
		HW,   // Hazen - Williams（H - W）
		DW,  //Darcy - Weisbach(D - W)
		CM //Chezy - Manning(C - M)
	};

	// 水质分析的类型
	enum class  QUALITY
	{
		NONE, //NONE（无）
		CHEMICAL, //CHEMICAL（化学药剂）
		AGE, // AGE（水龄）
		TRACE // TRACE（跟踪）
	};

	UNITS units;
	HEADLOSS headLoss;
	QUALITY quality;
	Str VISCOSITY = "0.1"; // 模拟流体的运动粘度
	Str  DIFFUSIVITY = "1.0"; // 是化合物的分析扩散系数
	Str SpecificGravity = "1.0"; // 被模拟流体密度与4摄氏度水的密度之比（无量纲）。
	Str TRIALS = "40"; // ，求解管网水力特性使用的最大试算次数
	Str ACCURACY = "0.001"; //指定了确定何时达到水力结果的收敛准则
	Str  UNBALANCED = "STOP"; //“STOP”将在该点终止整个分析。“CONTINUE”将在公布警告消息的情况
	Str Pattern = "1";
	Str DEMANDMULTIPLIER = "1.0"; // 用于调整所有连接节点的基本需水量数值，以及所有需水量的类型。
	Str EMITTEREXPONENT = "0.5"; // 指定了当计算扩散器的流量时，节点压力上升的幂指数
	Str TOLERANCE = "0.01"; //水质水平精度
	Str MAP;
};


/**
   inp文件对象模型
*/
class CivInp
{
public:
	// 时间单位
	enum TimeUnit { SECONDS, MINUTES, HOURS, DAYS };

	CivInp(TimeUnit timetype);
	/**
	*@brief 保存inp文件
	*@fileName: 文件名
	*/
	bool writeToFile(const char* fileName);
	
	/**
	*@brief 根据组件类型添加
	*@items: 数据
	*@type: 枚举类型
	*/
	void writeComponet(const Civitems& items, SectType type);

	/**
	*@brief 写入IO流
	*/
	void writeTextStream();

	/**
	*@brief 定义时间模式
	*@pId: 模式id
	*@pValue: 模式值
	*/
	void setPattern(StrQuote pId, std::vector<Str> pValue);

	/**
	*@brief 定义不同的模拟选项。
	*@options: 必选项
	*@others: 选填字段
	*/
	void setOption(Options options,const std::map<std::string,std::string>& others = std::map<std::string, std::string>());

	/**
	*@brief 设置模拟的历时
	*@duration： 总时间
	*/
	void setDuration(int duration);

	/**
	*@brief 设置时间间隔
	*@type：需要设置的时间步长计算模型：PATTERN，REPORT，QUALITY 
	*@step :间隔时长
	*/
	void setTimestep(Str type, int step);

	void setTimeStart(Str type, int step);

	void setTimeOthers(Str type, Str val);
	/**
	*@brief 设置时间单位
	*/
	void setTimeUnit(TimeUnit timeUnit) { mTimeUnit = timeUnit; }
private:
	Str getTimeUnit(TimeUnit timetype);
	void writeTitles();
	void writeJunctions(Civitems items);
	void writePipes(Civitems items);
	void writeTanks(Civitems items);
	void writeReservoirs(Civitems items);
	void writePumps(Civitems items);
	void writeValves(Civitems items);
	void writeTags(Civitems items);
	void writeCoordinates(Civitems items);
	void writeLabels(Civitems items);
	void writeVertices(Civitems items);
	void writeSources(Civitems items);
	void writeBackdrop(Civitems items);
	void writeEnd();
	void writeString(const std::string& s);
	void writeStatus(Civitems items);
	void writeCurves(Civitems items);
	void writeTimes(Civitems items);

	void writeControls(Civitems items);
	void writeReactions(Civitems items);
	void writeMixing(Civitems items);
	void writeRules(Civitems items);
	void writeEnergy(Civitems items);
	void writeEmitters(Civitems items);
	void writeQuality(Civitems items);
	void writeItems(const Civitems& items);
	void writeOptions(const Civitems& items);
	void writePatterns(Civitems items);
	void writeDemand(Civitems items);
private:
	std::ostringstream mTextStream;

	TimeUnit mTimeUnit; // 计算时间单位

	Civitems mJunctionsItems;  // 节点
	Civitems mPipesItems; // 管线
	Civitems mReservoirsItems; // 水源
	Civitems mTanksItems;// 水池
	Civitems mPumpsItems; // 水泵
	Civitems mValvesItems; // 阀门
	Civitems mTagsItems;  // 
	Civitems mStatusItems; // 定义模拟开始时被选管段的初始状态
	Civitems mPatternsItems; // 定义时间模式
	Civitems mCurvesItems; // 曲线
	Civitems mControlsItems; // 控制参数
	Civitems mRulesItems; // 定义基于规则控制，根据状况的组合来修改管段。
	Civitems mEnergyItems; // 定义计算水泵提升能量和成本的参数
	Civitems mEmittersItems; // 将模拟节点定义为扩散器（喷嘴或者孔口）。
	Civitems mQualityItems; // 定义节点的初始水质。
	Civitems mDemandsItems; //定义连接节点的多模式需水，是对[JUNCTIONS]的补充。
	Civitems mSourceItems; //定义水质源头的位置。
	Civitems mReactionItems; //定义对应于管网中与化学成分反应的参数。
	Civitems mMixingItems; // 确定控制蓄水池混合的模型。

	Civitems mReportItems; //描述模拟生成的输出报表内容。
	Civitems mOptionsItems; // 定义不同的模拟选项。
	Civitems mCoordinatesItems; // 
	Civitems mVerticesItems; //将内部顶点赋值给管网管段。
	Civitems mLabelsItems; // 给地图标签赋以坐标值。
	Civitems mBackdropItems; // 标识管网地图的背景图像及其尺寸。
	Civitems mTImesItems;//定义模拟中的各种事件时间步长参数。
};
