#include <QtCore/QCoreApplication>
#include<VSMD12XControl.h>
#include "QTextCodec"
#include "SensorMannager.h"
#include"SensorOptoSky.h"
#include"SensorQExPRO.h"
#include <iostream>
#include <fstream>
#include <QTextStream>
#include <QSettings>

QTextStream cout1(stdout, QIODevice::WriteOnly);
void logout(QString str){
    cout1<<str<<" <br>"<<flush;
    cout1<<endl;
   // std::fflush(stdout);
}
vector<int> FindFeng(vector<int > point1ist, vector<float> valuelist);
vector<int> DengJianJu(int position, int distanc, int times = 10);
vector <float> PingHua(vector <float> value, int step = 2);
int main(int argc, char* argv[])
{

    if (argc!=4)
    {
        logout("Some Thing error Please check the input");
        logout( "The Correct Should Be application sensor numberofposition");
        logout( "apllication Sensor positionneed shutter_time");
        logout("Senor: OSIFAlpha  QEPRO");
        logout("Senor: OSIFBeta  QE65");
        logout("Senor: ISIF   ATP6500");
        logout("Senor: IS1    ATP1010");
        logout("Senor: IS2    ATP5020");

        return 0;
    }
   // cali;
    int bandsnumber=1024;
    QString SensorTypestr(argv[1]);
    QString PositionNumberstr(argv[2]);
    int shuttertime=QString(argv[3]).toInt();
    int PositionNumber=PositionNumberstr.toInt();
	QCoreApplication aaaaa(argc, argv);

    QString m_qstrDeviceConfigFilePath;

#ifdef WIN32
    m_qstrDeviceConfigFilePath = ("D:\\03MyGit\\linux\\movingliner\\DeviceSettings.ini");
#else
    m_qstrDeviceConfigFilePath = ("/home/data/Setting/DeviceSettings.ini");
#endif
    QSettings *m_qsDeviceConfig;
    m_qsDeviceConfig = new QSettings(m_qstrDeviceConfigFilePath, QSettings::IniFormat);
    int numberofsensor=m_qsDeviceConfig->value("DEVICE INFO/TotalSpectrometer").toInt();


    logout("Welcom to use the Auto Locate Application");
	string hdrPath = "/home/data/test.csv";
	std::ofstream outfile(hdrPath.c_str());
    string hdrPath1 = "/home/data/result.csv";
    std::ofstream outfile1(hdrPath1.c_str());

    logout("Sensor is "+SensorTypestr);
    SensorBase* aa= nullptr;
    if (SensorTypestr=="OSIFAlpha")
    {
      aa = new SensorQExPRO(QE65PRO_QE);

    } else if (SensorTypestr=="OSIFBeta")
    {
        aa = new SensorQExPRO(QE65PRO_QE);

    }
    if(aa== nullptr)
    {
        QString portname="";
        for (int i = 0; i < numberofsensor; ++i) {
            QString key="FS"+QString::number(i+1)+"/Model";
            qDebug()<<key;
            if (m_qsDeviceConfig->value(key).toString()==SensorTypestr)
            {
                QString portstr=m_qsDeviceConfig->value("FS"+QString::number(i+1)+"/Port").toString();
                QStringList strlist=portstr.split('/');
                portname=strlist.at(strlist.length()-1);
            }
        }
       // qDebug()<<portname;

        if (portname=="")
        {
            logout("<b style=\"color:red\">Can not find the sensor"+SensorTypestr+"<\/b>");
            return 1;
        }
        logout("Sensor Port is "+portname);
        aa=new SensorOptoSky(ATP6500,portname);
    }



	//SensorBase* aa = new SensorOptoSky(ATP6500,"ttyUSB0");

	aa->initSensor();
    STRSensorInfo info= aa->SensorInfo;
    int bandsshow=info.BandNum/2;
    logout("Sensor Bands to Show is "+QString::number(bandsshow));
	STROnePlot oneplot;


    CVSMD12XControl Motercontrol;
    //Motercontrol.ILMES_InitializeComm("COM16");
    if ( m_qsDeviceConfig->value("LINEAR SHUTTER/Port").toString()!="")
    {
        logout("Find the motor port:"+m_qsDeviceConfig->value("LINEAR SHUTTER/Port").toString());
        Motercontrol.ILMES_InitializeComm( m_qsDeviceConfig->value("LINEAR SHUTTER/Port").toString());
    } else
    {
        return 0;
    }

    logout("The max Postion is "+QString::number(550000/4*PositionNumber));
    ControllerParams cpTest;
    bool res = Motercontrol.ILMES_InitializeParams(cpTest);




    aa->Settingshuttertime(shuttertime);
    aa->GetOnePlot(oneplot);




    logout("GO TO ZERO");
	Motercontrol.StartBackZero();
	Motercontrol.SetRunSpeed(10000);
    logout("GO TO ZERO OK");
    logout("Start Moving to "+QString::number(550000/4*PositionNumber));
	Motercontrol.MoveTo_NoSyn(550000/4*PositionNumber);
	aa->GetOnePlot(oneplot);
	MSInfo temp;
	Motercontrol.GetStatus(temp);
	vector<int > point1ist;
	vector<float> valuelist;
	int i = 0;
	Motercontrol.GetStatus(temp);
	//outfile <<i<<"," << oneplot.Plot[1024] << "," << temp.iPosition << std::endl;

	point1ist.push_back(temp.iPosition);
	valuelist.push_back(oneplot.Plot[bandsshow]);
	while (temp.fVelocity!=0)
	{
		aa->GetOnePlot(oneplot);
		//qDebug() << oneplot.BandNum;
		//std::cout << temp.iPosition << std::endl;

		Motercontrol.GetStatus(temp);
		i++;
		outfile << i << "," << oneplot.Plot[bandsshow] << "," << temp.iPosition << std::endl;
		point1ist.push_back(temp.iPosition);
		valuelist.push_back(oneplot.Plot[bandsshow]);

	}
    logout("FINISH Moving");
	vector<float> valuepinghua1 = PingHua(valuelist, 3);
	vector<int>loction1=FindFeng(point1ist, valuepinghua1);

	int lenth = loction1.size();
    if (lenth!=PositionNumber)
    {
        logout("<b style=\"color:red\">can not find all position please change the shutter time and try agin<\/b>");
    }
    cout1<<"First find "<<lenth<<" point "<<"<br>"<<flush;

    logout("GO TO ZERO");
    Motercontrol.StartBackZero();
    logout("GO TO ZERO OK");
    logout("Start Moving");
	for (size_t i = 0; i < lenth; i++)
	{
		vector<int> location1point = DengJianJu(loction1[i], 5000, 25);
		vector<float> valuepoint;
		int lennow = location1point.size();
        cout1<<"Detail find "<<i<<" point begin"<<"<br>"<<flush;
		for (size_t ii = 0; ii < lennow; ii++)
		{

			Motercontrol.MoveTo(location1point[ii]);
			aa->GetOnePlot(oneplot);
			valuepoint.push_back(oneplot.Plot[bandsshow]);
			//outfile << ii << "," << oneplot.Plot[1024] << "," << location1point[ii] << std::endl;

		}
		vector<float> valuepinghua = PingHua(valuepoint,3);
		vector<int>loction2 = FindFeng(location1point, valuepinghua);

		if (loction2.size() == 1)
		{   cout1<<"find "<<i<<"point value is <b color=\'green\'>"<<loction2[0]<<"<\/b><br>"<<flush;
			outfile1 <<i+1<<"," << loction2[0]<< std::endl;
		}

		int cc = 10;
		cc++;

	}
    logout("FINISH Moving");

	;










	std::cout<<"totle:" << i;
	outfile.close();
    outfile.close();
    if (!res)
    {
        return 0;

    }

    return 0;
	return aaaaa.exec();

}


vector<int> FindFeng(vector<int > point1ist, vector<float> valuelist)
{
	vector<int> ret;
	int lenth = point1ist.size();
	if (lenth<10)
	{
		ret.push_back(0);
		return ret;
	}
	for (size_t i = 5; i < lenth-5; i++)
	{
		if (valuelist[i] > 5000&&valuelist[i]>valuelist[i-1]&& valuelist[i] > valuelist[i - 4]&& valuelist[i] >valuelist[i + 1]&& valuelist[i] > valuelist[i + 4]
				&& valuelist[i-1] > 5000 && valuelist[i-4]&& valuelist[i +1] > 5000 && valuelist[i + 4])
		{
			if (ret.size()!=0)
			{
				if (point1ist[i]-ret[ret.size()-1]<5000)
				{
					continue;
				}

			}
			ret.push_back(point1ist[i]);


		}

	}
	return ret;



}
vector<int> DengJianJu(int position, int distanc, int times )
{
	int begin = position - distanc;
	vector<int> ret;
	int eachstep = distanc / times;
	for (size_t i = 0; i < 2*times; i++)
	{
		ret.push_back(begin + i * eachstep);
	}
	return ret;

}
vector <float> PingHua(vector <float> value,int step)
{
	vector <float> ret;
	if (value.size()<2*step)
	{
		return value;
	}
	int len = value.size();
	for (size_t i = 0; i < step; i++)
	{
		ret.push_back(value[i]);
	}
	for (size_t i = step; i <len-step; i++)
	{
		float sumi = 0;
		for (size_t ii = 0; ii < 2*step+1; ii++)
		{
			sumi += value[i - step + ii];
		}
		ret.push_back(sumi / (2 * step + 1));
	}
	for (size_t i = len  - step; i < len; i++)
	{
		ret.push_back(value[i]);
	}

	return ret;
}