#include "FEKOFarFieldFileClass.h"

FEKOBase::FEKOFarFieldFileClass::FEKOFarFieldFileClass()
{

}

FEKOBase::FEKOFarFieldFileClass::~FEKOFarFieldFileClass()
{

}

void FEKOBase::FEKOFarFieldFileClass::parseFarFieldFile(const QString& fileName)
{
    QFile file(fileName);
    // 加载文本文件中的所有数据到一个 QString 中
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		qDebug() << "Failed to open file for reading";
		return;
	}
	QTextStream in(&file);
	QString line;
	bool dataSectionStarted = false;
	
	
	QList<QString> dataBlockStrList;
	dataBlockStrList.clear();
	while (!in.atEnd()) {
		line = in.readLine().trimmed();
		if (line.startsWith(u8"##")) {
			if (line.indexOf(u8"File Type:") != -1) {
				this->FileType = line.split(":")[1].trimmed();
			}
			else if (line.indexOf(u8"File Format:") != -1) {
				this->FileFormat = line.split(":")[1].trimmed();
			}
			else if (line.indexOf(u8"Source:") != -1) {
				this->Sourcestr = line.split(":")[1].trimmed();
			}
			else if (line.indexOf(u8"Date:") != -1) {
				this->Datestr = line.split(":")[1].trimmed();
			}
			else {
				continue;
			}
		}
		else if (line.startsWith("**")) {
			dataBlockStrList.clear();
			continue;
		}
		else {
			if (line.length() < 5) {
				if (dataBlockStrList.length() > 0) {
					FEKOFARFIELDFEKODATABLOCK temp_dataBlock;
					temp_dataBlock.paraseFEKOFarFieldDataBlockFromList(dataBlockStrList);
					this->dataBlockList.push_back(temp_dataBlock);
				}
				else {

				}
				dataBlockStrList.clear();
			}
			else {
				dataBlockStrList.append(line);
			}
		}
	}
	
	if (dataBlockStrList.length() > 0) {
		FEKOFARFIELDFEKODATABLOCK temp_dataBlock;
		temp_dataBlock.paraseFEKOFarFieldDataBlockFromList(dataBlockStrList);
		this->dataBlockList.push_back(temp_dataBlock);
	}

    file.close();
}

void FEKOBase::FEKOFarFieldFileClass::outputToFile(const QString& fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "Failed to open file for writing";
        return;
    }

    QTextStream out(&file);
 
    file.close();

}

FEKOBase::FEKOFARFIELDRESULTTYPE FEKOBase::FEKOFARFIELDRESULTTYPEString2Enum(QString str)
{
    if (str.toUpper() == "GAIN") { return FEKOBase::GAIN; }
    else if (str.toUpper() == "DIRECTIVITY") { return FEKOBase::DIRECTIVITY; }
    else if (str.toUpper() == "RCS") { return FEKOBase::RCS; }
    else if (str.toUpper() == "FARFIELDVALUES") { return FEKOBase::FARFIELDVALUES; }
    else {
        return FEKOBase::FEKOFARFIELDRESULTTYPEUNKOWN;
    }
    return FEKOBase::FEKOFARFIELDRESULTTYPE();
}

QString FEKOBase::QString2FEKOFARFIELDRESULTTYPE(FEKOBase::FEKOFARFIELDRESULTTYPE mode)
{
    switch (mode) {
    case FEKOBase::GAIN:
        return "GAIN";
    case FEKOBase::DIRECTIVITY:
        return "DIRECTIVITY";
    case FEKOBase::RCS:
        return "RCS";
    case FEKOBase::FARFIELDVALUES:
        return "FARFIELDVALUES";
    default:
        return "FEKOFARFIELDRESULTTYPEUNKOWN";

    }
}

FEKOBase::FEKOFARFIELDFEKODATABLOCK::FEKOFARFIELDFEKODATABLOCK()
{
    this->dataList.clear();
    this->thetaSamples = 0;
    this->phiSamples = 0;
    this->USamples = 0;
    this->VSamples = 0;
    this->configurationName.clear();
    this->requestName.clear();
    this->frequency = 0;
    this->Origin = { 0,0,0 };
    this->headerLines = 0;
    this->coordinateSystem = FEKOBase::UNKONWFEKOCOORDINATESYSTEM;
    this->resultType = FEKOBase::FEKOFARFIELDRESULTTYPEUNKOWN;
}

FEKOBase::FEKOFARFIELDFEKODATABLOCK::~FEKOFARFIELDFEKODATABLOCK()
{

}

int FEKOBase::FEKOFARFIELDFEKODATABLOCK::paraseFEKOFarFieldDataBlock(const QString& blockstr)
{
    // 按行进行解析
    QList<QString> lines= blockstr.split("\n");
	return this->paraseFEKOFarFieldDataBlockFromList(lines);
	return	1;

}

int FEKOBase::FEKOFARFIELDFEKODATABLOCK::paraseFEKOFarFieldDataBlockFromList(QList<QString>& lines)
{
	bool in_readHeaderState = false;
	size_t headerlineCount = 0;
	std::vector<QString> headerLines;// 解析行列时保证结果


	for (size_t i = 0; i < lines.size(); i++) {
		if (lines[i].startsWith("#")) { // 参数项是以# 开头作为配置项
			// 针对不同参数项提取参数
			QString configName = normalizationHeaderString(lines[i]); // 获取参数的归一化名称
			if (configName == u8"") { // 未知参数项
				// 进入字段解析状态
				if (in_readHeaderState) {  // 解析字段
					QList<QString> temp_headerLines=lines[i].split(FEKOFARFIELDSPLITCHAT);
					for (size_t ii = 0; ii < temp_headerLines.size();ii++) {
						if (temp_headerLines[ii].length() > 2) {
							QString temp_header_str= this->normalizationHeaderString(temp_headerLines[ii]);
							headerLines.push_back(temp_header_str);
						}
						else {
							continue;
						}
					}
					headerlineCount++;
					if (headerlineCount >= this->headerLines) {
						in_readHeaderState = false;
					}
				}
				else {
					continue;
				}
			}
			else if (configName == u8"ConfigurationName") {
				this->configurationName = lines[i].split(":")[1].trimmed();
			}
			else if (configName == u8"RequestName") {
				this->requestName = lines[i].split(":")[1].trimmed();
			}
			else if (configName == u8"Frequency") {
				this->frequency = lines[i].split(":")[1].trimmed().toDouble();
			}
			else if (configName == u8"CoordinateSystem") {
				this->coordinateSystem = FEKOBase::FEKOCoordinateSystemString2Enum(lines[i].split(":")[1].trimmed());
			}
			else if (configName == u8"ThetaSamplePointsNumber") {
				this->thetaSamples = lines[i].split(":")[1].trimmed().toInt();
			}
			else if (configName == u8"PhiSamplePointsNumber") {
				this->phiSamples = lines[i].split(":")[1].trimmed().toInt();
			}
			else if (configName == u8"USamplePointNumber") {
				this->USamples = lines[i].split(":")[1].trimmed().toInt();
			}
			else if (configName == u8"VSamplePointNumber") {
				this->VSamples = lines[i].split(":")[1].trimmed().toInt();
			}
			else if (configName == u8"ORIGIN") {
				QStringList originstrlist = lines[i].replace("(", "").replace(")", "").split(":")[1].trimmed().split(",");
				this->Origin = { originstrlist[0].trimmed().toDouble(),originstrlist[1].trimmed().toDouble(),originstrlist[2].trimmed().toDouble() };
			}
			else if (configName == u8"ResultType") {
				this->resultType = FEKOBase::FEKOFARFIELDRESULTTYPEString2Enum(lines[i].split(":")[1].trimmed());
			}
			else if (configName == u8"HeaderLines") {
				this->headerLines = lines[i].split(":")[1].trimmed().toInt();
				in_readHeaderState = true;
				 
			}
			else {
				continue;
			}
		}
		else if (lines[i].size() > 10) { // 解析数据块
			QList<QString> dataline = lines[i].split(FEKOFARFIELDSPLITCHAT);
			FEKOBase::FEKOFarFieldFEKOFarFieldData temp_data;
			long field_idx =-1;
			for (size_t ii = 0; ii < dataline.count(); ii++) {
				if (dataline[ii] == u8"") { continue; }
				else { field_idx = field_idx + 1; }
				if (headerLines[field_idx] == "theta") { temp_data.theta = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "phi") { temp_data.phi = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(etheta)") { temp_data.re_Etheta = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(etheta)") { temp_data.im_Etheta = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(ephi)") { temp_data.re_Ephi = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(ephi)") { temp_data.im_Ephi = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "gain(theta)") { temp_data.gain_Theta = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "gain(phi)") { temp_data.gain_Phi = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "gain(total)") { temp_data.gain_Total = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "radius") { temp_data.radius = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "x") { temp_data.X = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "y") { temp_data.Y = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "z") { temp_data.Z = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(ex)") { temp_data.re_Ex = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(ey)") { temp_data.re_Ey = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(ez)") { temp_data.re_Ez = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(ex)") { temp_data.im_Ex = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(ey)") { temp_data.im_Ey = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(ez)") { temp_data.im_Ez = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "re(er)") { temp_data.re_Er = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "im(er)") { temp_data.im_Er = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "u") { temp_data.U = dataline[ii].toDouble(); }
				else if (headerLines[field_idx] == "v") { temp_data.V = dataline[ii].toDouble(); }
				else {
					continue;
				}
			}
			this->dataList.push_back(temp_data);
		}
		else {
			continue;
		}

	}
	return 0;
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::normalizationHeaderString(QString headerstr)
{
	headerstr = headerstr.replace("'", "").replace(u8"\"",u8"");
    if(headerstr.indexOf("#Configuration Name") != -1)
	{
		return u8"ConfigurationName";
	}
	else if (headerstr.indexOf("#Request Name") != -1)
	{
		return  u8"RequestName";
	}
	else if (headerstr.indexOf("#Frequency") != -1)
	{
		return u8"Frequency";
	}
	else if (headerstr.indexOf("#Coordinate System:") != -1)
	{
		return u8"CoordinateSystem";
	}
	else if (headerstr.indexOf("#No. of Theta Samples:") != -1)
	{
		return u8"ThetaSamplePointsNumber";
	}
	else if (headerstr.indexOf("#No. of Phi Samples:") != -1)
	{
		return u8"PhiSamplePointsNumber";
	}
	else if (headerstr.indexOf("#No. of U Samples:") != -1)
	{
		return u8"USamplePointNumber";
	}
	else if (headerstr.indexOf("#No. of V Samples:") != -1)
	{
		return u8"VSamplePointNumber";
	}
	else if (headerstr.indexOf("#No. of X Samples:") != -1)
	{
		return u8"XSamplePointNumber";
	}
	else if (headerstr.indexOf("#No. of Y Samples:") != -1)
	{
		return u8"YSamplePointNumber";
	}
	else if (headerstr.indexOf("#No. of Z Samples:") != -1)
	{
		return u8"ZSamplePointNumber";
	}
	else if (headerstr.indexOf("#Origin:") != -1)
	{
		return u8"ORIGIN";
	}
	else if (headerstr.indexOf("#Result Type:") != -1)
	{
		return u8"ResultType";
	}
	else if (headerstr.indexOf("#No. of Header Lines:") != -1)
	{
		return u8"HeaderLines";
	} 
    else if (headerstr.toLower().trimmed()==u8"theta"|| headerstr.toLower().trimmed() == u8"theta'") {
		return u8"theta";
    }
    else if (headerstr.toLower().trimmed() == u8"phi"|| headerstr.toLower().trimmed() == u8"phi'") {
		return u8"phi";
    }
    else if (headerstr.toLower().trimmed() == u8"re(etheta)"|| headerstr.toLower().trimmed() == u8"re(etheta')") {
		return u8"re(etheta)";
	}
    else if (headerstr.toLower().trimmed() == u8"im(etheta)"|| headerstr.toLower().trimmed() == u8"im(etheta')") {
		return u8"im(etheta)";
	}
    else if (headerstr.toLower().trimmed() == u8"re(ephi)"|| headerstr.toLower().trimmed() == u8"re(ephi')") {
		return u8"re(ephi)";
	}
    else if (headerstr.toLower().trimmed() == u8"im(ephi)"|| headerstr.toLower().trimmed() == u8"im(ephi')") {
		return u8"im(ephi)";
	}
	else if (headerstr.toLower().trimmed() == u8"re(er)"|| headerstr.toLower().trimmed() == u8"re(er')") {
		return u8"re(ephi)";
	}
	else if (headerstr.toLower().trimmed() == u8"im(er)"|| headerstr.toLower().trimmed() == u8"im(er')") {
		return u8"im(ephi)";
	}
    else if (headerstr.toLower().trimmed() == u8"gain(theta)"|| headerstr.toLower().trimmed() == u8"gain(theta')") {
		return u8"gain(theta)";
	}
    else if (headerstr.toLower().trimmed() == u8"gain(phi)"|| headerstr.toLower().trimmed() == u8"gain(phi')") {
		return u8"gain(phi)";
	}
	else if (headerstr.toLower().trimmed() == u8"gain(total)"|| headerstr.toLower().trimmed() == u8"gain(total')") {
		return u8"gain(total)";	
	}
	else if (headerstr.toLower().trimmed() == u8"radius"|| headerstr.toLower().trimmed() == u8"radius'") {
		return u8"radius";
	}
	else if (headerstr.toLower().trimmed() == u8"x" || headerstr.toLower().trimmed() == "x'") {
		return u8"x";
	}
	else if (headerstr.toLower().trimmed() == u8"y" || headerstr.toLower().trimmed() == "y'") {
		return u8"y";
	}
	else if (headerstr.toLower().trimmed() == u8"z" || headerstr.toLower().trimmed() == "z'") {
		return u8"z";
	}
	else if (headerstr.toLower().trimmed() == "re(ex)" || headerstr.toLower().trimmed() == "re(ex')") {
		return u8"re(ex)";
	}
	else if (headerstr.toLower().trimmed() == "re(ey)" || headerstr.toLower().trimmed() == "re(ey')") {
		return u8"re(ey)";
	}
	else if (headerstr.toLower().trimmed() == "re(ez)" || headerstr.toLower().trimmed() == "re(ez')") {
		return u8"re(ez)";
	}
	else if (headerstr.toLower().trimmed() == "im(ex)" || headerstr.toLower().trimmed() == "im(ex')") {
		return u8"im(ex)";
	}
	else if (headerstr.toLower().trimmed() == "im(ey)" || headerstr.toLower().trimmed() == "im(ey')") {
		return u8"im(ey)";
	}
	else if (headerstr.toLower().trimmed() == "im(ez)" || headerstr.toLower().trimmed() == "im(ez')") {
		return u8"im(ez)";
	}
	else if (headerstr.toLower().trimmed() == "re(er)" || headerstr.toLower().trimmed() == "re(er')") {
		return u8"re(er)";
	}
	else if (headerstr.toLower().trimmed() == "im(er)" || headerstr.toLower().trimmed() == "im(er')") {
		return u8"im(er)";
	}
	else if (headerstr.toLower().trimmed() == "u" || headerstr.toLower().trimmed() == "u'") {
		return u8"u";
		}
	else if (headerstr.toLower().trimmed() == "v" || headerstr.toLower().trimmed() == "v'") {
			return u8"v";
			}
	else {
		return u8"";
	}

;
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::saveFEKOFarFieldDataBlock()
{

    switch (this->resultType) {
    case FEKOBase::GAIN:
        return this->saveFEKOFarFieldDataBlock_Gain();
    case FEKOBase::DIRECTIVITY:
        return this->saveFEKOFarFieldDataBlock_Directivity();
    case FEKOBase::RCS:
        return this->saveFEKOFarFieldDataBlock_RCS();
    case FEKOBase::FARFIELDVALUES:
        return this->saveFEKOFarFieldDataBlock_FarFieldValues();
    default:
        return QString();
    }
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::saveFEKOFarFieldDataBlock_Gain()
{
    return QString();
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::saveFEKOFarFieldDataBlock_Directivity()
{
    return QString();
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::saveFEKOFarFieldDataBlock_RCS()
{
    return QString();
}

QString FEKOBase::FEKOFARFIELDFEKODATABLOCK::saveFEKOFarFieldDataBlock_FarFieldValues()
{
    return QString();
}
