/***************************** 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 *************************************/

// Macro Converter
// Classes for converting different types of requests to
// macros
//
// Geir Austad
//
#pragma once

#include "Prototype.hpp"
#include "MvRequest.h"
class MacroConverter;
class ObjectInfo;

struct ConverterTraits
{
    using Type = MacroConverter;
    static Type& DefaultObject();
};

class MacroConverter : public Prototype<ConverterTraits>
{
public:
    // Contructors
    MacroConverter(const Cached& converterName) :
        Prototype<ConverterTraits>(converterName, this) {}

    // Destructors
    ~MacroConverter() override = default;

    // Methods
    virtual Cached Convert(MvRequest&, ObjectInfo* oi) = 0;

private:
    // No copy allowed
    MacroConverter(const MacroConverter&) = delete;
    MacroConverter& operator=(const MacroConverter&) { return *this; }
};

class DefaultMacroConverter : public MacroConverter
{
public:
    DefaultMacroConverter(const Cached& name) :
        MacroConverter(name) {}

    ~DefaultMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo*) override;
};

class ReadMacroConverter : public MacroConverter
{
public:
    ReadMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~ReadMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class FamilyMacroConverter : public MacroConverter
{
public:
    FamilyMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~FamilyMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class CurveFamilyMacroConverter : public MacroConverter
{
public:
    CurveFamilyMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~CurveFamilyMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class FormulaFamilyMacroConverter : public MacroConverter
{
public:
    FormulaFamilyMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~FormulaFamilyMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class ComputeMacroConverter : public MacroConverter
{
public:
    ComputeMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~ComputeMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class DataMacroConverter : public MacroConverter
{
public:
    DataMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~DataMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo* oi) override;
};

class EmptyMacroConverter : public MacroConverter
{
public:
    EmptyMacroConverter(const Cached& name) :
        MacroConverter(name) {}
    ~EmptyMacroConverter() override = default;

    Cached Convert(MvRequest&, ObjectInfo*) override;
};
