#ifndef POINTCALCULATE_H
#define POINTCALCULATE_H

#include <QPointF>

#include "filemanager.h"
#include "global.h"

namespace PointCalculate{
using namespace Global;

void setAnalysisData(const QVector<Global::ExperimentData>&);

//QPair<QPointF,QPointF> getStartAndEndPoint();
QPair<float,float> getMinAndMaxOfSampleTemp();
QPair<float,float> getMinAndMaxOfRunTime();
QPair<float,float> getMinAndMaxOfDSC();

QPair<float,float> getMinAndMaxOfAxis(const float min,const float max);

QVector<Global::ExperimentData> getDataInXRange(const float, const float);
QVector<Global::ExperimentData> getDataInXRangeByTime(const float, const float);

QVector<QPointF> getPointVtrInXRange(const float, const float);

void setRegionPointX(const float,const float);

ExperimentData getClosestDataByTemperature(const float);
ExperimentData getClosestDataByTime(const float);

QPointF getClosestPointByX(const float);
QVector<QPointF> getNearbyPointGroupByX(const float);

QPointF getClosestPointByY(const double left,const double right,const double valueY);
QPointF getPeakPoint();
QPointF getPeakPointByTime();
QPair<float, float>  getMaxMinValue();

QPair<QPointF,QPointF> getSelectedPoints();

// According to the value of plot x axis witch of temperature value.
QPair<float, float>  getTheMaximumAndMinimumValuesOfTime(
        const double min,const double max);

QPair<QPointF,QPointF> calculateStartAndEndPoint();
QPair<ExperimentData,ExperimentData> calculateStartAndEndData();

QPair<QPointF,QPointF> calculateOITStartAndEndDataByTime(const double x1,const double x2);

float calculateArea(const double x1,const double x2);
double obtainTimeValueBasedOnTemperatureValue(const double sampleTemp);

ExperimentData findOnSetDataByTemperature(const double x1,const double x2);
ExperimentData findEndSetDataByTemperature(const double x1,const double x2);

ExperimentData findOnSetDataByTime(const double x1,const double x2);
ExperimentData findEndSetDataByTime(const double x1,const double x2);

ExperimentData getOITStartData(const double x1,const double x2);
std::pair<bool, ExperimentData> calculateMedianOIT();
// text format
QString textFormatPeakPoint(const float enthalpyValue,
                            const float peakValue,
                            const float startPoint,
                            const float endPoint);
QString textFormatPeakPointWithTime(const float enthalpyValue,
                            const float peakValue,
                            const float startPoint,
                            const float endPoint);

QString textFormatNumbericalLabel(const QPointF);
QString textFormatNumbericalLabelWithTime(const QPointF);

QString textFormatStartPoint(const QPointF);
QString textFormatStartPointWithTime(const QPointF);

QString textFormatEndPoint(const QPointF);
QString textFormatEndPointWithTime(const QPointF);

QString textFormatGlassTranstion(const float t1,const float tg,const float t2);
QString textFormatGlassTranstionWithTime(const float t1,const float tg,const float t2);

// glass transition
QPair<float,float> getCurveInflectionPointTangent(const float,const float);
struct Line {
    double slope; //
    double intercept; //
};
QPointF getIntersection(const Line& line1, const Line& line2);
double calculateSlope(double x1, double y1, double x2, double y2) ;
QVector<double> findInflectionPoints(const QVector<double>& x, const QVector<double>& y) ;
QMap<double, Line>  calculateTangentLine(const QVector<double>& x, const QVector<double>& y) ;
double calculateDistance(const QPointF& p1, const QPointF& p2);

//private
void updateStartEndPoint();
QPair<QPointF,QPointF> calculateMaxDiffPointLeft();
QPair<QPointF,QPointF> calculateMaxDiffPointRight();
enum MaxDiffPointDetailType{
    Left,
    Right
};
QPair<QPointF,QPointF> calculateMaxDiffPointDetail(const MaxDiffPointDetailType type);
QPair<Global::ExperimentData,Global::ExperimentData> calculateMaxDiffDataByTime(
        const double x1,const double x2);

QPointF calculateIntersection(const QPointF p1,const QPointF p2,
                              const QPointF p3, const QPointF p4);
QVector<QPointF> getPeakPointGroup();
QVector<QPointF> getPeakPointGroupByTime(const double,const double);

std::vector<float> movingAverage(const std::vector<float>& data, int windowSize);
QVector<QPointF> movingAveragePoint(const QVector<QPointF>& data, int windowSize);


extern QVector<Global::ExperimentData> _dataVtr;
extern QPointF _peakPoint;
extern QPointF _leftSelectedPoint,_rightSelectedPoint;
}

#endif // POINTCALCULATE_H
