#pragma once

#include <util/generic/vector.h>

namespace NRTYFactors {

    struct EFictiveFactors {
        static const int MATRIX_NET = 0;
        static const int META_MATRIX_NET = 1;
        static const int FULL_MATRIX_NET = 2;
        static const int FAST_MATRIX_NET = 3;
        static const int FILTER_MATRIX_NET = 4;
        static const int FAST_FILTER_MATRIX_NET = 5;
        static const int META_POLYNOM = 6;
        static const int FULL_POLYNOM = 7;
        static const int FAST_POLYNOM = 8;
        static const int FILTER_POLYNOM = 9;
        static const int FAST_FILTER_POLYNOM = 10;
        static const int COUNT = 11;
    };

    class TFictiveFactorsInfo {
    public:
        TFictiveFactorsInfo();
        virtual ~TFictiveFactorsInfo() = default;

        inline const ui32& GetMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::MATRIX_NET];
        }

        inline const ui32& GetMetaMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::META_MATRIX_NET];
        }

        inline const ui32& GetFullMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FULL_MATRIX_NET];
        }

        inline const ui32& GetFastMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FAST_MATRIX_NET];
        }

        inline const ui32& GetFilterMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FILTER_MATRIX_NET];;
        }

        inline const ui32& GetFastFilterMatrixNetGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FAST_FILTER_MATRIX_NET];;
        }

        inline const ui32& GetMetaPolynomGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::META_POLYNOM];
        }

        inline const ui32& GetFullPolynomGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FULL_POLYNOM];
        }

        inline const ui32& GetFastPolynomGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FAST_POLYNOM];
        }

        inline const ui32& GetFilterPolynomGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FILTER_POLYNOM];;
        }

        inline const ui32& GetFastFilterPolynomGlobalIndex() const {
            return FictiveFactorsGlobalIndex[EFictiveFactors::FAST_FILTER_POLYNOM];;
        }

        bool IsFictiveFactor(ui32 factorIndex) const;

    protected:
        TVector<ui32>& GetFictiveFactorsGlobalIndex() {
            return FictiveFactorsGlobalIndex;
        }

    private:
        TVector<ui32> FictiveFactorsGlobalIndex;
    };

}
