//    Copyright (C) 2020-2021 Jakub Melka
//
//    This file is part of PDF4QT.
//
//    PDF4QT is free software: you can redistribute it and/or modify
//    it under the terms of the GNU Lesser General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    with the written consent of the copyright owner, any later version.
//
//    PDF4QT is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public License
//    along with PDF4QT.  If not, see .
#ifndef DIMENSIONTOOL_H
#define DIMENSIONTOOL_H
#include "pdfwidgettool.h"
#include 
#include 
struct DimensionUnit;
using DimensionUnits = std::vector;
struct DimensionUnit
{
    explicit inline DimensionUnit() = default;
    explicit inline DimensionUnit(pdf::PDFReal scale, QString symbol) :
        scale(scale),
        symbol(qMove(symbol))
    {
    }
    pdf::PDFReal scale = 1.0;
    QString symbol;
    static DimensionUnits getLengthUnits();
    static DimensionUnits getAreaUnits();
    static DimensionUnits getAngleUnits();
};
class Dimension
{
public:
    enum Type
    {
        Linear,
        Perimeter,
        Area,
        Angular
    };
    inline explicit Dimension() = default;
    inline explicit Dimension(Type type, pdf::PDFInteger pageIndex, pdf::PDFReal measuredValue, std::vector polygon) :
        m_type(type),
        m_pageIndex(pageIndex),
        m_measuredValue(measuredValue),
        m_polygon(qMove(polygon))
    {
    }
    Type getType() const { return m_type; }
    pdf::PDFInteger getPageIndex() const { return m_pageIndex; }
    pdf::PDFReal getMeasuredValue() const { return m_measuredValue; }
    const std::vector& getPolygon() const { return m_polygon; }
    /// Returns true, if definition fo given type is complete
    static bool isComplete(Type type, const std::vector& polygon);
private:
    Type m_type = Linear;
    pdf::PDFInteger m_pageIndex = -1;
    pdf::PDFReal m_measuredValue = 0.0;
    std::vector m_polygon;
};
class DimensionTool : public pdf::PDFWidgetTool
{
    Q_OBJECT
private:
    using BaseClass = pdf::PDFWidgetTool;
public:
    enum Style
    {
        LinearHorizontal,
        LinearVertical,
        Linear,
        Perimeter,
        RectanglePerimeter,
        Area,
        RectangleArea,
        Angle,
        LastStyle
    };
    explicit DimensionTool(Style style, pdf::PDFDrawWidgetProxy* proxy, QAction* action, QObject* parent);
    void drawPage(QPainter* painter,
                  pdf::PDFInteger pageIndex,
                  const pdf::PDFPrecompiledPage* compiledPage,
                  pdf::PDFTextLayoutGetter& layoutGetter,
                  const QTransform& pagePointToDevicePointMatrix,
                  QList& errors) const override;
signals:
    void dimensionCreated(Dimension dimension);
private:
    void onPointPicked(pdf::PDFInteger pageIndex, QPointF pagePoint);
    void onRectanglePicked(pdf::PDFInteger pageIndex, QRectF pageRectangle);
    QPointF adjustPagePoint(QPointF pagePoint) const;
    Dimension::Type getDimensionType() const;
    pdf::PDFReal getMeasuredValue(pdf::PDFInteger pageIndex, const std::vector& pickedPoints) const;
    Style m_style;
    int m_previewPointPixelSize;
    pdf::PDFPickTool* m_pickTool;
};
#endif // DIMENSIONTOOL_H