#include "CivInpDbHelper.h"
#include "CivTableFields.h"
#include "CivConnection.h"
#include "CivPgDbConnection.h"


CivInpDbHelper::CivInpDbHelper(const std::string& uri)
	:CivInpHelperAbs(uri)
{

}

CivInpDbHelper::~CivInpDbHelper()
{
}

bool CivInpDbHelper::getNode(CivNode& node)
{
	JunctionTable nodeTableFields;

	std::vector<std::string> fields = 
	{ 
		nodeTableFields.sn,
		nodeTableFields.elev,
		nodeTableFields.baseDemand,
		nodeTableFields.demandPattern
	};
	std::vector<std::map<std::string,std::string>> resultVector;
	mDbConn->query(PIPENODE, fields, resultVector);

	// ±à¼­°ü×°½á¹û
	size_t total = resultVector.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> map = resultVector[i];
		CivNode::NodeTable nodeTable;

		nodeTable.ID = map.find(nodeTableFields.sn)->second;
		nodeTable.Elev = map.find(nodeTableFields.elev)->second;
		nodeTable.Demand = map.find(nodeTableFields.baseDemand)->second;
		nodeTable.PatternId = map.find(nodeTableFields.demandPattern)->second;

		node.addItem(nodeTable);
	}
	return true;
}

bool CivInpDbHelper::getPipe(CivPipe& pipes)
{
    PipeTable pipeTable;

	std::vector<std::string> fields = { 
		pipeTable.snNo, 
		pipeTable.startPoint,
		pipeTable.endPoint, 
		pipeTable.length, 
		pipeTable.diameter, 
		pipeTable.friction, 
		pipeTable.localLoss,
		pipeTable.status
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PIPELINE, fields, resultVector);

	size_t total = resultVector.size();
    for (int i = 0; i < total; i++)
    {
        CivPipe::PipesTable pipe;

		std::map<std::string, std::string> map = resultVector[i];

		pipe.ID = map.find(pipeTable.snNo)->second;
		pipe.Node1 = map.find(pipeTable.startPoint)->second;
		pipe.Node2 = map.find(pipeTable.endPoint)->second;
		pipe.Length = map.find(pipeTable.length)->second;
		pipe.Diameter = map.find(pipeTable.diameter)->second;
		pipe.Roughness = map.find(pipeTable.friction)->second;
		pipe.MinorLoss = map.find(pipeTable.localLoss)->second;
		pipe.Status = map.find(pipeTable.status)->second;

		pipes.addItem(pipe);
    }
	return true;
}

bool CivInpDbHelper::getTank(CivTank& tanks)
{
	TankTable tankTable;

	std::vector<std::string> fields = {
		tankTable.sn,
		tankTable.elev,
		tankTable.initLevel,
		tankTable.minLevel,
		tankTable.maxLevel,
		tankTable.diametor,
		tankTable.minVolume,
		tankTable.volumeCurve
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(TANK, fields, resultVector);

	size_t total = resultVector.size();
	for (int i = 0; i < total; i++)
	{
		CivTank::TankTable tank;
		std::map<std::string, std::string>map = resultVector[i];

		tank.ID = map.find(tankTable.sn)->second;
		tank.Elev = map.find(tankTable.elev)->second;
		tank.InitLevel = map.find(tankTable.initLevel)->second;
		tank.MinLevel = map.find(tankTable.minLevel)->second;
		tank.MaxLevel = map.find(tankTable.maxLevel)->second;
		tank.Diameter = map.find(tankTable.diametor)->second;
		tank.MinVol = map.find(tankTable.minVolume)->second;
		tank.VolCurve = map.find(tankTable.volumeCurve)->second;
		
		tanks.addItem(tank);
	}
	return true;
}

bool CivInpDbHelper::getValve(CivValve& valves)
{
	ValveTable vaveTable;
	std::vector<std::string> fields = { 
		vaveTable.sn, 
		vaveTable.startPoint,
		vaveTable.endPoint,
		vaveTable.length,
		vaveTable.type,
		vaveTable.setting,
		vaveTable.lossCoeff
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(VALVE, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivValve::ValveTable vave;
		std::map<std::string, std::string> map = resultVector[i];

		vave.ID = map.find(vaveTable.sn)->second;
		vave.Node1 = map.find(vaveTable.startPoint)->second;
		vave.Node2 = map.find(vaveTable.endPoint)->second;
		vave.Diameter = map.find(vaveTable.length)->second;
		vave.Type = map.find(vaveTable.type)->second;
		vave.Setting = map.find(vaveTable.setting)->second;
		vave.MinorLoss = map.find(vaveTable.lossCoeff)->second;

		valves.addItem(vave);
	}
	return true;
}

bool CivInpDbHelper::getPumps(CivPumps& pumps)
{
	PumpTable pmTable;
	std::vector<std::string> fields = {
		pmTable.sn,
		pmTable.startPoint,
		pmTable.endPoint,
		pmTable.headCurve,
		pmTable.power
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PUMP, fields, resultVector);
	
	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivPumps::PumpTable pump;
		std::map<std::string, std::string> map = resultVector[i];

		pump.ID = map.find(pmTable.sn)->second;
		pump.Node1 = map.find(pmTable.startPoint)->second;
		pump.Node2 = map.find(pmTable.endPoint)->second;
		std::string param;
		
		std::string curve = map.find(pmTable.headCurve)->second;
		if (curve != "")
			param.append("head " + curve);

		std::string power = map.find(pmTable.power)->second;
		if (power != "")
			param.append(" power " + power);
	
		pump.Parameters = param;
		pumps.addItem(pump);
	}
	return true;
}

bool CivInpDbHelper::getReservoirs(CivReservoirs& reservoirs)
{
	ResourcesTable restemTable;

	std::vector<std::string> fields = {
		restemTable.sn,
		restemTable.totalHead,
		restemTable.headPattern
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(RESIVOIR, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivReservoirs::ReservoirsTable resTable;
		std::map<std::string, std::string> map = resultVector[i];

		resTable.ID = map.find(restemTable.sn)->second;
		resTable.Head = map.find(restemTable.totalHead)->second;
		resTable.Pattern = map.find(restemTable.headPattern)->second;

		reservoirs.addItem(resTable);
	}
	return true;
}

bool CivInpDbHelper::getCoordinates(CivCoordinates& coord)
{
	JunctionTable nodeTable;

	std::vector<std::string> fields = {
		nodeTable.sn,
		nodeTable.xCoord,
		nodeTable.yCoord
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PIPENODE, fields, resultVector);
	mDbConn->query(TANK, fields, resultVector);
	mDbConn->query(RESIVOIR, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivCoordinates::CoordTable coordTable;
		std::map<std::string, std::string> map = resultVector[i];

		coordTable.ID = map.find(fields[0])->second;
		coordTable.XCoord = map.find(fields[1])->second;
		coordTable.YCoord = map.find(fields[2])->second;

		coord.addItem(coordTable);
	}

	return true;
}

bool CivInpDbHelper::getQuality(CivQuality& quality)
{
	JunctionTable nodeTable;

	std::vector<std::string> fields =
	{ 
		nodeTable.sn,
		nodeTable.initQuality 
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PIPENODE, fields, resultVector);


	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivQuality::QualityTable quliTable;

		std::map<std::string, std::string> map = resultVector[i];
		quliTable.ID = map.find(fields[0])->second;
		quliTable.InitQuality = map.find(fields[1])->second;;

		quality.addItem(quliTable);
	}

	return true;
}

