/*  Multimodal Image Segmentation Tool (MIST)  */
/*  Eelke Visser  */

/*  Copyright (c) 2016 University of Oxford  */

/*  CCOPYRIGHT  */

#ifndef PROFILEFILTERS_H
#define PROFILEFILTERS_H

#include "armawrap/newmat.h"
#include <boost/log/trivial.hpp>
#include "serialisation.h"

class IdentityFilter;
class DerivativeFilter;
BOOST_CLASS_EXPORT_KEY(IdentityFilter)
BOOST_CLASS_EXPORT_KEY(DerivativeFilter)

class ProfileFilter
{
public:
    virtual NEWMAT::ColumnVector Filter(const NEWMAT::ColumnVector &profile) = 0;
    virtual ~ProfileFilter() { }

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        BOOST_LOG_TRIVIAL(debug) << "(De)serialising base ProfileFilter";
    }
};

class IdentityFilter : public ProfileFilter
{
public:
    virtual NEWMAT::ColumnVector Filter(const NEWMAT::ColumnVector &profile);

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        BOOST_LOG_TRIVIAL(debug) << "(De)serialising IdentityFilter";

        ar & boost::serialization::base_object<ProfileFilter>(*this);
    }
};

class DerivativeFilter : public ProfileFilter
{
public:
    enum Mode
    {
        Full,
        Positive,
        Negative
    };

    DerivativeFilter();
    DerivativeFilter(Mode mode);

    void SetMode(Mode mode);
    Mode GetMode() const;

    virtual NEWMAT::ColumnVector Filter(const NEWMAT::ColumnVector &profile);

private:
    Mode m_mode = Full;

    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        BOOST_LOG_TRIVIAL(debug) << "(De)serialising DerivativeFilter";

        ar & boost::serialization::base_object<ProfileFilter>(*this);

        ar & m_mode;
    }
};

#endif // PROFILEFILTERS_H
