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

//--

#ifndef DIVROT_H
#define DIVROT_H

#include "Metview.h"

#define VORTICITY 138
#define DIVERGENCE 155


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

const string cVORTICITY("138.128");
const string cDIVERGENCE("155.128");
const 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)
    string DfileOut;            // tmp output file name
    long DoutputValsLen;        // nr of (truncated) U/V values

public:
    Divrot(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(char* a) :
        Divrot(a) {}
    virtual bool GetData(MvRequest&);
};

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

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

#endif
//-- DIVROT_H
