#ifndef TITAN_PCBCAM_COMMON_H
#define TITAN_PCBCAM_COMMON_H
#include "../titanpcbcamglobal.h"
#include <Qt>
#include <QString>
#include <QRegularExpression>

class TITAN_PCBCAM_EXPORT PcbCam : public QObject
{
    Q_OBJECT
public:
    enum LayerContext {
        BoardContext = 0x01,
        MiscContext = 0x02,
        AllContext = BoardContext|MiscContext,
    };
    Q_ENUM(LayerContext)
    Q_DECLARE_FLAGS(LayerContexts, LayerContext)
    Q_FLAGS(LayerContexts)

    enum FeatureType {
        LineFeature = 0x0001,
        PadFeature = 0x0002,
        ArcFeature = 0x0004,
        TextFeature = 0x0008,
        BarcodeFeature = 0x0010,
        SurfaceFeature = 0x0200,
        PathFeature = 0x0400, // profile and package
        ComponentFeature = 0x0800, // component
        AllFeatures = LineFeature|PadFeature|ArcFeature|TextFeature|BarcodeFeature|SurfaceFeature|PathFeature|ComponentFeature,
    };

    Q_ENUM(FeatureType)
    Q_DECLARE_FLAGS(FeatureTypes, FeatureType)
    Q_FLAGS(FeatureTypes)

    enum Polarity {
        Positive = 0x01,
        Negative = 0x02,
        BothPolarity = Positive|Negative,
    };
    Q_ENUM(Polarity)
    Q_DECLARE_FLAGS(Polarities, Polarity)
    Q_FLAGS(Polarities)

    enum ProfileRegion {
        InProfile = 0x01,
        OutProfile = 0x02,
        AllProfile = InProfile|OutProfile,
    };
    Q_ENUM(ProfileRegion)
    Q_DECLARE_FLAGS(ProfileRegions, ProfileRegion)
    Q_FLAGS(Polarities)

    enum Orient {
        Orient_N_0 = 0,
        Orient_N_90 = 1,
        Orient_N_180 = 2,
        Orient_N_270 = 3,
        Orient_Y_0 = 4,
        Orient_Y_90 = 5,
        Orient_Y_180 = 6,
        Orient_Y_270 = 7
    };

    enum SymbolType {
        Sym_R,
        Sym_S,
        Sym_Rect,
        Sym_RectR,
        Sym_RectC,
        Sym_Oval,
        Sym_Di,
        Sym_Oct,
        Sym_DonutR,
        Sym_DonutS,
        Sym_HexL,
        Sym_HexS,
        Sym_Bfr,
        Sym_Bfs,
        Sym_Tri,
        Sym_OvalH,
        Sym_Thr,
        Sym_Ths,
        Sym_SThs,
        Sym_STho,
        Sym_SrThs,
        Sym_RcThs,
        Sym_RcTho,
        Sym_El,
        Sym_Moire,
        Sym_Hole,
        Sym_User = 1000,
    };

    enum BarcodeTextPos {
        BarcodeTextPos_Top,
        BarcodeTextPos_Bot,
    };

    enum FeatureSelectionOperation {
        NoFeatureSelection,
        ReplaceFeatureSelection,
        AppendFeatureSelection,
        RemoveFeatureSelection,
    };

    enum FeatureSelectionMode {
        ContainsFeatureShape,
        IntersectsFeatureShape,
    };

    enum UnitsType {
        Units_Unknow,
        Units_Inch,
        Units_Mm
    };

    enum ZerosOmit
    {
        ZerosOmit_Unknow,
        ZerosOmit_None,
        ZerosOmit_Leading,
        ZerosOmit_Training,
        ZerosOmit_Decimal,
    };

    enum CoordNotation
    {
        CoordUnknow,
        CoordAbsoulte,
        CoordIncremental,
    };

    enum LogicOperator {
        Logic_And,
        Logic_Or,
    };

    enum SnapMode {
        SnapOff = 0x0000,
        SnapCenter = 0x0001,
        SnapSkeleton = 0x0002,
        SnapEdge = 0x0004,
        SnapIntersect = 0x0008,
        SnapMidPoint = 0x0010,
        SnapProfile = 0x0020,
        SnapBetween = 0x0040,
        AllSnapMode = SnapCenter|SnapSkeleton|SnapEdge|SnapIntersect|SnapMidPoint|SnapProfile|SnapBetween,
    };
    Q_ENUM(SnapMode)
    Q_DECLARE_FLAGS(SnapModes, SnapMode)
    Q_FLAGS(SnapModes)

    enum DisplayOption {
        DisplayFill = 0x0001,
        DisplayOutline = 0x0002,
        DisplaySketeon = 0x0004,
        DisplayNegative = 0x0008,
        DisplayMultiLayer = 0x0010,
        DisplayStepRepeat = 0x0020,
        DisplayTextValue = 0x0040,
        DisplayProfile = 0x0080,
        DisplayDatumn = 0x0100,
        DisplayFullCursor = 0x0200,
    };
    Q_ENUM(DisplayOption)
    Q_DECLARE_FLAGS(DisplayOptions, DisplayOption)
    Q_FLAGS(DisplayOptions)

    enum MessageType {
        Message_Error,
        Message_Warn,
        Message_Info,
        Message_Ok,
    };

    struct FeatureSelectionFilter {
        FeatureTypes type {FeatureType::AllFeatures};
        Polarities polarity {Polarity::BothPolarity};
        ProfileRegions profile {ProfileRegion::AllProfile};
        QStringList includeSymbols;
        QStringList excludeSymbols;
        QStringList includeAttributes;
        QStringList excludeAttributes;
        LogicOperator includeAttributesLogic {LogicOperator::Logic_And};
        LogicOperator excludeAttributesLogic {LogicOperator::Logic_And};
        bool isEmpty() const {
            return ((type == FeatureType::AllFeatures)
                    && (polarity == Polarity::BothPolarity)
                    && (profile == ProfileRegion::AllProfile)
                    && (includeSymbols.isEmpty())
                    && (excludeSymbols.isEmpty())
                    && (includeAttributes.isEmpty())
                    && (excludeAttributes.isEmpty()));
        }
    };

    struct AttrCompareInfo {
        ushort type {0}; //比较类型(0:是否有此属性; 1:属性值是否相等; 2:数值是否在范围)
        QString name;
        QString strValue;
        double minValue = static_cast<double>(INTMAX_MIN);
        double maxValue = static_cast<double>(INTMAX_MAX);
        AttrCompareInfo() {}
        AttrCompareInfo(const QString &iAttrStr) {
            auto idx = iAttrStr.indexOf("=");
            if (idx != -1) {
                this->type = 1;
                this->name = iAttrStr.left(idx).trimmed();
                this->strValue = iAttrStr.mid(idx+1).trimmed();
                auto vidx = this->strValue.indexOf('~');
                if (vidx != -1) {
                    this->type = 2;
                    auto minstr = this->strValue.left(vidx).trimmed();
                    auto maxstr = this->strValue.mid(vidx+1).trimmed();
                    if (!minstr.isEmpty()) {
                        this->minValue = minstr.toDouble();
                    }
                    if (!maxstr.isEmpty()) {
                        this->maxValue = maxstr.toDouble();
                    }
                }
            }
            else {
                this->name = iAttrStr.trimmed();
            }
        }
    };
};


#endif //TITAN_PCBCAM_COMMON_H

