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

//--

#pragma once

#include "Metview.h"

extern "C" void vod2uv_(fortfloat* VOR, fortfloat* DIV, fortint* KTIN, fortfloat* U, fortfloat* V, fortint* KTOUT);

const std::string cVORTICITY("138.128");
const std::string cDIVERGENCE("155.128");
const std::string cSPECTRAL("sh");

enum eParam
{
    eVorticity,
    eDivergence,
    eVorticityAndDivergence,
    eUnknown
};

enum eResultParam  // what we would like to compute
{
    eRotational,
    eDivergent,
    eUV,
    eResultUnknown
};


class Divrot : public MvService
{
protected:
    char Dsmoothing[4];         // smoothing (1 Yes/0 No)
    eParam Dparam;              // eVorticity or eDivergence
    eResultParam DresultParam;  // eRotational, eDivergent or eUV
    int DtruncIn;               // truncation of input field
    int DtruncOut;              // output truncation
    double Dfltc;               // constant
    double Dmfltexp;            // exponent
    int Dnfield;                // number of fields
    int Dnfield2;               // number of fields (used if deriving U/V)
    MvFieldSet Dfieldset;       // Vorticity or divergence field set
    MvFieldSet Dfieldset2;      // Vorticity or divergence field set (used if deriving U/V)
    std::string DfileOut;       // tmp output file name
    long DoutputValsLen;        // nr of (truncated) U/V values
    int divParamId_{155};
    int vorParamId_{138};

public:
    Divrot(const char* a) :
        MvService(a) {}
    ~Divrot() {}
    void serve(MvRequest&, MvRequest&);

    virtual bool GetData(MvRequest&) = 0;
    bool GetDataGen(MvRequest&);
    bool Apply(MvRequest&);
    int GetField(MvRequest&, int, MvFieldSet&);

    bool isValidData_DVVALID(grib_handle* gh);
    bool checkOutputTruncation(grib_handle* gh);
    bool convert_DIVROT(MvRequest& out);
    bool smooth_BPPSMTH(grib_handle* gh);
    bool appendWindComponent(grib_handle* gh);
    //    bool check_ecCodes( int ret, const char* gribApiFunc, const char* MvFunc );
};

class Rotwind : public Divrot
{
public:
    Rotwind(const char* a) :
        Divrot(a) {}
    virtual bool GetData(MvRequest&);
};

class Divwind : public Divrot
{
public:
    Divwind(const char* a) :
        Divrot(a) {}
    virtual bool GetData(MvRequest&);
};

class UVwind : public Divrot
{
public:
    UVwind(const char* a) :
        Divrot(a) {}
    virtual bool GetData(MvRequest&);
};

//-- DIVROT_H
