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

//
// .NAME:
//  MagicsTranslator
//
// .AUTHOR:
//  Gilberto Camara, Baudouin Raoult and Fernando Ii
//
// .SUMMARY:
//  A general class for translatiopn of METVIEW requests
//  into MAGICS requests
//
// .CLIENTS:
//  MagicsAction, MapView
//
// .RESPONSABILITIES:
//  - Read the incoming METVIEW requests
//  - Find the appropriate MAGIS equivalents
//  - Provide new magics request
//
// .COLLABORATORS:
//
// .BASE CLASS:
//  Prototype
//
// .DERIVED CLASSES:
//  GribTranslator, ImageTranslator, BufrTranslator
//
// .REFERENCES:
//
//
#ifndef MagicsTranslator_H
#define MagicsTranslator_H

#include <Prototype.hpp>
#include <MvRequest.h>

class MagicsTranslator;

struct MagicsTranslatorTraits
{
    typedef MagicsTranslator Type;
    static Type& DefaultObject();
};

class MagicsTranslator : public Prototype<MagicsTranslatorTraits>
{
public:
    // Contructors
    MagicsTranslator(const Cached& actionName) :
        Prototype<MagicsTranslatorTraits>(actionName, this) {}

    // Destructor
    virtual ~MagicsTranslator();

    // Translator functions
    virtual MvRequest Execute(const MvRequest&)                                     = 0;
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)                   = 0;
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&) = 0;
};

class GribTranslator : public MagicsTranslator
{
public:
    // Contructors
    GribTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~GribTranslator() {}

    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);

    static MagicsTranslator& Instance();  // for the default object
};

class BufrTranslator : public MagicsTranslator
{
public:
    // Contructors
    BufrTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~BufrTranslator() {}

    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);
};

class ObsTranslator : public MagicsTranslator
{
public:
    // Contructors
    ObsTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~ObsTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class CoastTranslator : public MagicsTranslator
{
public:
    // Contructors
    CoastTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~CoastTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class ContTranslator : public MagicsTranslator
{
public:
    // Contructors
    ContTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~ContTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class MContTranslator : public MagicsTranslator
{
public:
    // Contructors
    MContTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~MContTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class TextTranslator : public MagicsTranslator
{
public:
    // Contructors
    TextTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~TextTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class AxisTranslator : public MagicsTranslator
{
public:
    // Contructors
    AxisTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~AxisTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class GraphTranslator : public MagicsTranslator
{
public:
    // -- Contructors
    GraphTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // -- Destructor
    ~GraphTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class PageTranslator : public MagicsTranslator
{
public:
    // Contructors
    PageTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~PageTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }

protected:
    void loadPredefAreas();
    MvRequest findPredefArea(const std::string& name);

    MvRequest predefAreas_;
};

class GribVectorsTranslator : public MagicsTranslator
{
public:
    // -- Contructors
    GribVectorsTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // -- Destructor
    ~GribVectorsTranslator() {}

    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);
};

class WindTranslator : public MagicsTranslator
{
public:
    // Contructors
    WindTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~WindTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class NetCDFTranslator : public MagicsTranslator
{
public:
    // Contructors
    NetCDFTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~NetCDFTranslator() {}

    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);
};

class VoidTranslator : public MagicsTranslator
{
public:
    // Contructors
    VoidTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~VoidTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest&, const MvRequest&);
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);
};

class VisDefTranslator : public MagicsTranslator
{
public:
    // Contructors
    VisDefTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~VisDefTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class GeopointsTranslator : public MagicsTranslator
{
public:
    // Contructors
    GeopointsTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~GeopointsTranslator() {}

    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&);
};

class SymbolTranslator : public MagicsTranslator
{
public:
    // Contructors
    SymbolTranslator(const Cached& actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~SymbolTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class ImportTranslator : public MagicsTranslator
{
public:
    // Contructors
    ImportTranslator(const char* actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~ImportTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

class ThermoTranslator : public MagicsTranslator
{
public:
    // Contructors
    ThermoTranslator(const char* actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~ThermoTranslator() {}

    virtual MvRequest Execute(const MvRequest&, const MvRequest&);
    virtual MvRequest Execute(const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
    virtual MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&)
    {
        return MvRequest("EMPTY");
    }
};

class ThermoGridTranslator : public MagicsTranslator
{
public:
    ThermoGridTranslator(const char* actionName) :
        MagicsTranslator(actionName) {}

    ~ThermoGridTranslator() {}

    MvRequest Execute(const MvRequest&, const MvRequest&) override {return MvRequest("EMPTY");}
    MvRequest Execute(const MvRequest&) override;
    MvRequest Execute(const MvRequest&, const MvRequest&, const MvRequest&) override {return MvRequest("EMPTY");}
};



class TableTranslator : public MagicsTranslator
{
public:
    // Contructors
    TableTranslator(const char* actionName) :
        MagicsTranslator(actionName) {}

    // Destructor
    ~TableTranslator() {}

    virtual MvRequest Execute(const MvRequest&);
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&)
    {
        return this->Execute(req);
    }
    virtual MvRequest Execute(const MvRequest& req, const MvRequest&, const MvRequest&)
    {
        return this->Execute(req);
    }
};

#endif
