/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MVQFEATUREFRONTITEM_H
#define MVQFEATUREFRONTITEM_H

#include "MvQFeatureCurveItem.h"

//-----------------------------------------------------------
// The points of a Curve object
//-----------------------------------------------------------
class MvQFeatureMetCurveItem : public MvQFeatureCurveItem
{
public:
    MvQFeatureMetCurveItem(MvQFeatureType* feature, MvQPlotView* view) :
           MvQFeatureCurveItem(feature, view, false) {}

    double halo() const override;
    void flipSymbolDirection() override;

    const std::string& frontSubType() const override {return front_type_;}
    void setFrontSubType(const std::string&)  override;

    bool canBeCreatedOutOfView() const override { return false;}
    bool canBePastedOutOfView() const override { return true;}

protected:
    MvQFeatureMetCurveItem(const MvQFeatureMetCurveItem&);
    void buildShape() override;
    bool getRequestParameters() override;
    virtual bool getSimpleRequestParameters();

    virtual void paint_normal(QPainter*);
    virtual void paint_fronto(QPainter*);
    void init_line_segment();
    bool compute_next_line_segment(QPointF&, QPointF&, float, float);
    virtual void makeSymbol(const QPointF&, const QPointF&, QVector<QPointF>&) {}
    void makeTriangle(const QPointF&, const QPointF&, float, bool, QVector<QPointF>&);    
    QSizeF makeSemiCircle(float, float, float, QVector<QPointF>&);
    QSizeF makeCircle(float, float, float, QVector<QPointF>&);
    void makeHalfCircle(const QPointF&, const QPointF&, bool has_offset, QVector<QPointF>&);
    QSizeF makeCross(float, QVector<QPointF>&);
    void paintSeparator(QPainter*, QPen&, QBrush&, const QPointF&, const QPointF&);
    void paintSeparatorPolygon(QPainter*, QBrush&, const QPointF&, const QPointF&);
    void paintSeparatorPolygon2(QPainter*, QBrush&, const QPointF&, const QPointF&);
    void paintSeparatorLine(QPainter*, QPen&, const QPointF&, const QPointF&);
    void paintLineSegment(QPainter*, int, int, const QPointF&, const QPointF&);
    void rotateSymbol(const QPointF&, const QPointF&, bool, QVector<QPointF>&);
    void translateSymbol(const QPointF&, const QPointF&, QVector<QPointF>&);
    void translateSymbol(const QPointF&, QVector<QPointF>&);
    void translateSymbol(const QPointF&, const QPointF&, QVector<QPointF>&,QVector<QPointF>&);
    void linearInterpolation(int, float, QPointF&);

    std::string front_type_;
    bool type_normal_ {true};

    bool symbolFacesLeft_{true};
    float symbolGap_; //pixels
    QVector<QPointF> symbolSep_;  // symbol separator

    int ind_{0};     // curve index
    int startIndex_{-1}; // line segment starting index
    int endIndex_{-1};   // line segment ending index
};


//-----------------------------------------------------------------
// The Cold Front class
//-----------------------------------------------------------------
class MvQFeatureColdFrontItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureColdFrontItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureColdFrontItem(const MvQFeatureColdFrontItem&);
    void updateSymbols() override;
    void makeSymbol(const QPointF&, const QPointF&,
                    QVector<QPointF>&) override;
};

//-----------------------------------------------------------------
// The Warm Front class
//-----------------------------------------------------------------
class MvQFeatureWarmFrontItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureWarmFrontItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureWarmFrontItem(const MvQFeatureWarmFrontItem&);
    void updateSymbols() override;
    void makeSymbol(const QPointF&, const QPointF&,
                    QVector<QPointF>&) override;
};

//-----------------------------------------------------------------
// The Occluded Front class
//-----------------------------------------------------------------
class MvQFeatureOccludedItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureOccludedItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
    void paint_normal(QPainter*) override;
    void paint_fronto(QPainter*) override;

protected:
     MvQFeatureOccludedItem(const MvQFeatureOccludedItem&);
     void updateSymbols() override;
//    void makeSymbol(const QPointF&, const QPointF&,
//                    QVector<QPointF>&) override;
};

//-----------------------------------------------------------------
// The Quasi Stationary Front class
//-----------------------------------------------------------------
class MvQFeatureQuasiStationaryItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureQuasiStationaryItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
    void paint_normal(QPainter*) override;
    void paint_fronto(QPainter*) override;

protected:
    MvQFeatureQuasiStationaryItem(const MvQFeatureQuasiStationaryItem&);
    bool getRequestParameters() override;
    void updateSymbols() override;

    std::vector <bool> symbTag_;
    QVector<QPointF> symbSc_;         // symbol semi-circle
    QVector<QPointF> symbTr_;         // symbol triangle

    QPen linePenTr_;
    QBrush symbolBrushTr_;
    QPen linePenSc_;
    QBrush symbolBrushSc_;
};

//-----------------------------------------------------------------
// The Ridge Front class
//-----------------------------------------------------------------
class MvQFeatureRidgeItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureRidgeItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureRidgeItem(const MvQFeatureRidgeItem&);
    bool getRequestParameters() override;
    void updateSymbols() override;
};


//-----------------------------------------------------------------
// The Intertropical Discontinuity class
//-----------------------------------------------------------------
class MvQFeatureIttDiscontinuityItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureIttDiscontinuityItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureIttDiscontinuityItem(const MvQFeatureIttDiscontinuityItem&);
    bool getRequestParameters() override;

    QPen linePenC1_;
    QPen linePenC2_;
};


//-----------------------------------------------------------------
// The Convergence Line Front class
//-----------------------------------------------------------------
class MvQFeatureConvergenceLineItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureConvergenceLineItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureConvergenceLineItem(const MvQFeatureConvergenceLineItem&);
    bool getRequestParameters() override;
    void updateSymbols() override;
};


//-----------------------------------------------------------------
// The Instability and Shear Line Front parent class
//-----------------------------------------------------------------
class MvQFeatureInstabilityShearLineItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureInstabilityShearLineItem(MvQFeatureType* feature, MvQPlotView* view, bool bShear);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    MvQFeatureInstabilityShearLineItem(const MvQFeatureInstabilityShearLineItem&);
    bool getRequestParameters() override;
    void updateSymbols() override;

    bool bShear_{true};
    double diameter_;
};


//-----------------------------------------------------------------
// The Instability Line Front class
//-----------------------------------------------------------------
class MvQFeatureInstabilityLineItem : public MvQFeatureInstabilityShearLineItem
{
public:
    MvQFeatureInstabilityLineItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;

protected:
    MvQFeatureInstabilityLineItem(const MvQFeatureInstabilityLineItem&);
};


//-----------------------------------------------------------------
// The Shear Line Front class
//-----------------------------------------------------------------
class MvQFeatureShearLineItem : public MvQFeatureInstabilityShearLineItem
{
public:
    MvQFeatureShearLineItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;

protected:
    MvQFeatureShearLineItem(const MvQFeatureShearLineItem&);
};


//-----------------------------------------------------------------
// The Tropical Wave class
//-----------------------------------------------------------------
class MvQFeatureTropicalWaveItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureTropicalWaveItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;

protected:
    MvQFeatureTropicalWaveItem(const MvQFeatureTropicalWaveItem&);
    bool getRequestParameters() override
        { return getSimpleRequestParameters(); }

    void updateSymbols() override {}
};


//-----------------------------------------------------------------
// The Intertropical Convergence Zone class
//-----------------------------------------------------------------
class MvQFeatureItczItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureItczItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
    bool neighbourPoints(const QVector<QPointF>&, int&, float, float);
    bool drawInBetweenLine(QPainter*, const QVector<QPointF>&,
                           const QVector<QPointF>&,
                           const QPointF&, const QPointF&, float, int&, int&);

protected:
    MvQFeatureItczItem(const MvQFeatureItczItem&);
    bool getRequestParameters() override;
    void updateSymbols() override;
    void buildShape() override;

    int thickness_{1};
    int width_{10};
    int intensity_{1};
    int intensityGap_{10};
};


//-----------------------------------------------------------------
// The Trough class
//-----------------------------------------------------------------
class MvQFeatureTroughItem : public MvQFeatureMetCurveItem
{
public:
    MvQFeatureTroughItem(MvQFeatureType* feature, MvQPlotView* view);
    MvQFeatureItem* clone() const override;

protected:
    MvQFeatureTroughItem(const MvQFeatureTroughItem&);
    bool getRequestParameters() override
        { return getSimpleRequestParameters(); }

    void updateSymbols() override {}
};


// FAMII20210414
// These classes and respective icons have been removed from the user
// interface. Delete them later if they will not be used in the future.
#if 0
class MvQFeatureFrontolysisItem : public MvQFeatureCurveItem
{
public:
    MvQFeatureFrontolysisItem(MvQFeatureType* feature, MvQPlotView* view);
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    void updateStyle() override;
    void updateSize() override;

    std::vector <bool> symbFreq_;
    QVector<QPointF> symbSc_;         // symbol semi-circle
    QVector<QPointF> symbTr_;         // symbol triangle

    QPen linePenTr_;
    QBrush symbolBrushTr_;
    QPen linePenSc_;
    QBrush symbolBrushSc_;
bool symbNavy_{false};  // temporary
};

class MvQFeatureFrontogenesisItem : public MvQFeatureCurveItem
{
public:
    MvQFeatureFrontogenesisItem(MvQFeatureType* feature, MvQPlotView* view);
    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;

protected:
    void updateStyle() override;
    void updateSize() override;

    std::vector <bool> symbFreq_;
bool symbNavy_{false};  // temporary
};
#endif

#endif // MVQFEATUREFRONTITEM_H
