#include "CivNewInp.h"
#include <time.h>
#include<fstream>


CivNewInp::CivNewInp()
{
    mParamMap[OPTIONS] = &CivNewInp::setOptions;
    mParamMap[REACTIONS] = &CivNewInp::setReactions;
    mParamMap[TIMES] = &CivNewInp::setTimes;
    mParamMap[REPORT] = &CivNewInp::setReport;
    mParamMap[ENERGY] = &CivNewInp::setEnergy;
    setTtitle(" ");
}

CivNewInp::~CivNewInp()
{

}

bool CivNewInp::writeToFile(const std::string& fileName)
{
    // 检查是否存在值
    std::string res = mTextStream.str();
    if (res.empty())
        return false;

    std::ofstream outFile(fileName);
    if (!outFile)
    {
        mTextStream.clear();
        mTextStream.str("");
        return false;
    }
    else
    {
        outFile << res;
        outFile.close();
        mTextStream.clear();
        mTextStream.str("");
        return true;
    }
}

void CivNewInp::setTtitle(const std::string& title)
{
	writeString("[TITLES]");
	writeString("Scenario: Base");
	writeString("Date:"+currentTime() );
}

void CivNewInp::writeHead(const std::string& head)
{
    mTextStream << "[" << head << "]" << "\n";
}


std::string CivNewInp::currentTime()
{
    time_t rawtime;
    struct tm* timeinfo;
    char s[100];
    time(&rawtime);

    timeinfo = localtime(&rawtime);
    time_t tick = mktime(timeinfo);
    strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", timeinfo);

    return s;
}

void CivNewInp::setNode(const CivNode& node)
{

    auto tables = node.mTables;
    if (tables.size() <= 0)
        return;

    writeHead("JUNCTIONS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivNode::NodeTable nodeTable = *iter;

        writeStringFormat(nodeTable.ID);
        writeStringFormat(nodeTable.Elev);
        writeStringFormat(nodeTable.Demand);
        writeString(nodeTable.PatternId);
    }
    writeString("");
}

void CivNewInp::setPipes(const CivPipe& pipes)
{
    auto tables = pipes.mTables;
    if (tables.size() <= 0)
        return;

    writeHead("PIPES");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivPipe::PipesTable pipesTable = *iter;
        if (pipesTable.ID.empty() || 
            pipesTable.Node1.empty() || 
            pipesTable.Node2.empty()||
            pipesTable.Length.empty()||
            pipesTable.Diameter.empty())
            continue;
        if (pipesTable.MinorLoss.empty())
            pipesTable.MinorLoss = "0";

        if (pipesTable.Status.empty())
            pipesTable.Status = "Open";

        writeStringFormat(pipesTable.ID);   
        writeStringFormat(pipesTable.Node1);
        writeStringFormat(pipesTable.Node2);
        writeStringFormat(pipesTable.Length);
        writeStringFormat(pipesTable.Diameter);
        writeStringFormat(pipesTable.Roughness);
        writeStringFormat(pipesTable.MinorLoss);
        writeString(pipesTable.Status);
    }
    writeString("");
}

void CivNewInp::setTank(const CivTank& tank)
{
    auto tables = tank.mTables;
    if (tables.size() <= 0)
        return;

    writeHead("TANKS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivTank::TankTable table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.Elev);
        writeStringFormat(table.InitLevel);
        writeStringFormat(table.MinLevel);
        writeStringFormat(table.MaxLevel);
        writeStringFormat(table.Diameter);
        writeStringFormat(table.MinVol);
        writeString(table.VolCurve);
    }
    writeString("");
}

void CivNewInp::setValves(const CivValve& valve)
{
    auto tables = valve.mTables;
    if (tables.size() <= 0)
        return;

    writeHead("VALVES");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivValve::ValveTable table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.Node1);
        writeStringFormat(table.Node2);
        writeStringFormat(table.Diameter);
        writeStringFormat(table.Type);
        writeStringFormat(table.Setting);
        writeString(table.MinorLoss);
    }
    writeString("");
}

void CivNewInp::setPumps(const CivPumps& pumps)
{
    auto tables = pumps.mTables;
    if (tables.size() <= 0)
        return;

    writeHead("PUMPS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivPumps::PumpTable table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.Node1);
        writeStringFormat(table.Node2);
        writeString(table.Parameters);
    }
    writeString("");
}

void CivNewInp::setEmitters(const CivEmitters& mitters)
{
    auto tables = mitters.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead("EMITTERS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivEmitters::EmittersTable table = *iter;
        writeStringFormat(table.ID);
        writeString(table.coeff);
    }
    writeString("");
}

void CivNewInp::setReservoirs(const  CivReservoirs& res)
{
    auto tables = res.mTables;
    if (tables.size() <= 0)
    {
        return;
    }

    writeHead("RESERVOIRS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivReservoirs::ReservoirsTable table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.Head);
        writeString(table.Pattern);
    }
    writeString("");
}

// 系统运行
void CivNewInp::setCurves(const CivCurves& cureves)
{
    auto tables = cureves.mTables;
    if (tables.size() <= 0)
    {
        return;
    }

    writeHead("CURVES");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivCurves::Table table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.XCoord);
        writeString(table.YCoord);
    }
    writeString("");
}


void CivNewInp::setPatterns(const CivPatterns& patterns)
{
    auto tables = patterns.mTables;
    if (tables.size() <= 0)
    {
        return;
    }

    writeHead("PATTERNS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivPatterns::PatternTable table = *iter;
        writeStringFormat(table.name);
        writeString(table.val);
    }
    writeString("");
}


void CivNewInp::setStatus(const CivStatus& status)
{
    auto tables = status.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead("STATUS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivStatus::Table table = *iter;
        writeStringFormat(table.ID);
        writeString(table.Setting);
    }
    writeString("");
}

void CivNewInp::setControls(const std::string& control)
{
    writeHead("CONTROLS");
    writeString(control);
}

void CivNewInp::setRules(const std::string& ruleId, const std::string& rules)
{
    writeHead("RULES");
    writeString("RULE " + ruleId);
    writeString(rules);
}

void CivNewInp::setDemands(const CivDemands& demands)
{
    auto tables = demands.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead("DEMANDS");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivDemands::Table table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.BaseDemand);
        writeStringFormat(table.PatternId);
        writeString(table.DemandType);
    }
    writeString("");
}

// 水质
void CivNewInp::setQuality(const CivQuality& quality)
{
    auto tables = quality.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead("QUALITY");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivQuality::Table table = *iter;
        writeStringFormat(table.ID);   
        writeString(table.InitQuality);       
    }
    writeString("");
}

void CivNewInp::setSources(const CivSources& sources)
{
    auto tables = sources.mTables;
    if (tables.size() <= 0)
    {
        return;
    }

    writeHead("SOURCES");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivSources::Table table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.Type);
        writeStringFormat(table.Quality);
        writeString(table.Pattern);
    }
    writeString("");
}

void CivNewInp::setMixing(const CivMixing& mixing)
{
    auto tables = mixing.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead("MIXING");
    for (auto iter = tables.rbegin(); iter != tables.rend(); iter++)
    {
        CivMixing::Table table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.hyModel);
        writeString(table.volume);
    }
    writeString("");
}

// 选项和报表
void CivNewInp::setParamter(const CivParameter& params, const std::string& type)
{
    void (CivNewInp:: * funcPrt)(const CivParameter&);
    auto iter = mParamMap.find(type);
    if (mParamMap.end() == iter)
        return;

    funcPrt = iter->second;
    (this->*funcPrt)(params);  
}

void CivNewInp::setReactions(const CivParameter& params)
{
    auto tables = params.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead(REACTIONS);
    auto iter = tables.rbegin();  
    for (; iter != tables.rend(); iter++)
    {
        CivParameter::ParamTable table = *iter;
        writeStringFormat(table.name);
        writeString(table.val);
    }
    writeString("");  
}

void CivNewInp::setOptions(const CivParameter& params)
{
    auto tables = params.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead(OPTIONS);
    auto iter = tables.rbegin();
    for (; iter != tables.rend(); iter++)
    {
        CivParameter::ParamTable table = *iter;
        std::string strName = table.name;
        std::string strValue = table.val;
        writeStringFormat(strName);
        writeString(strValue);
    }
    writeString("");
}

void CivNewInp::setTimes(const CivParameter& params)
{
    auto tables = params.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    
    writeHead(TIMES);
    auto iter = tables.rbegin();
    for (; iter != tables.rend(); iter++)
    {
        CivParameter::ParamTable table = *iter;
        writeStringFormat(table.name);
        writeString(table.val);  
    }
    writeString("");
}

void CivNewInp::setReport(const CivParameter& params)
{
    auto tables = params.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead(REPORT);
    auto iter = tables.rbegin();
    for (; iter != tables.rend(); iter++)
    {
        CivParameter::ParamTable table = *iter;
        writeStringFormat(table.name);
        writeString(table.val);
    }
    writeString("");
}

void CivNewInp::setEnergy(const CivParameter& params)
{
    auto tables = params.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    writeHead(ENERGY);
    auto iter = tables.rbegin();
    for (; iter != tables.rend(); iter++)
    {
        CivParameter::ParamTable table = *iter;
        writeStringFormat(table.name);
        writeString(table.val);
    }
    writeString("");
}

//管网地图/标签
void CivNewInp::setCoordnates(const CivCoordinates& coords)
{
    auto tables = coords.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    auto iter = tables.rbegin();
    writeHead("COORDINATES");
    for (; iter != tables.rend(); iter++)
    {
        CivCoordinates::Table table = *iter;
        writeStringFormat(table.ID);
        writeStringFormat(table.XCoord);
        writeString(table.YCoord);
    }
    writeString("");
}

void CivNewInp::setVertices()
{

}

void CivNewInp::setLabels(const CivLabels& labels)
{
    auto tables = labels.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    auto iter = tables.rbegin();
    writeHead("LABELS");
    for (; iter != tables.rend(); iter++)
    {
        CivLabels::Table table = *iter;
       
        writeStringFormat(table.XCoord );
        writeStringFormat(table.YCoord);
        writeStringFormat(table.Label);
        writeStringFormat(table.ID);
    }
    writeString("");
}

void CivNewInp::setBackDrop()
{

}

void CivNewInp::setTags(const CivTags& tags)
{
    auto tables = tags.mTables;
    if (tables.size() <= 0)
    {
        return;
    }
    auto iter = tables.rbegin();
    writeHead("TAGS");
    for (; iter != tables.rend(); iter++)
    {
        CivTags::Table table = *iter;

        writeStringFormat(table.Key);
        writeStringFormat(table.Id);
        writeString(table.Label);
    }
    writeString("");
}

void CivNewInp::writeString(const std::string& s)
{
	mTextStream << s << "\n";
}

void CivNewInp::writeStringFormat(const std::string& s, const std::string& sep)
{
    mTextStream << s << sep;
}