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

/********************************************************************************
  Application for Vertical Profile.
  It takes a GRIB file as input (in addition to the values given by the user),
  and produces an NetCDF file as output. There is no metadata on output request,
  only the path to NetCDF file.

  First the GRIB while is read, and info about all parameters and level are stored.
  Then several flags is set, based on the data and the input request, to determine
  how the application should run.

  The file is rewound, and sorted by param, date, time, step and expver. All fields
  with the same values for the sorting parameters are one plot. If any of these
  values change, all data are written out as netcdf variables with names put
  together from the sorting values.
********************************************************************************/

#include "Xsect.h"

class Vprofile : public Xsect
{
public:
    // Constructors
    Vprofile();
    Vprofile(const char* kw);

    bool writeLevelInfoNetcdf(MvNetCDF&, ApplicationInfo&, ParamMap&, MvField*, double*) override;
    bool writeGeoCoordsNetcdf(MvNetCDF&, ApplicationInfo&) override;
    bool writeGlobalAttributesNetcdf(MvNetCDF&, ParamMap&, ApplicationInfo&) override;
    bool generateExtraData(MvNetCDF&, ApplicationInfo&, ParamMap&, MvFieldSetIterator&) override;
    bool generateDerivedData(MvNetCDF&, ApplicationInfo&, ParamMap&, MvFieldSetIterator&);
    bool generatePressureFromLNSP(MvNetCDF&, ApplicationInfo&, ParamMap&, MvFieldSetIterator&);
    bool generateQ2(MvNetCDF&, ApplicationInfo&, ParamMap&);
    bool generateOrography(MvNetCDF&, ApplicationInfo&, ParamMap&);
    bool generateSurftype(MvNetCDF&, ApplicationInfo&, ParamMap&);
    bool generateData(ApplicationInfo&, ParamMap&, MvNetCDF&, MvField&, const std::string&) override;

    // Get geogrpahical coordinates and application parameters
    bool getCoordinates(MvRequest&, ApplicationInfo&);
    bool getAppParameters(MvRequest&, ApplicationInfo&) override;

    // Create output request
    MvRequest createOutputRequest(ApplicationInfo&, ParamInfo*) override;

    int computeGeographicalPoints(ApplicationInfo&, MvField* = nullptr) override;

    bool fillValues(ApplicationInfo&, MvField&, double*) override;

    bool fieldConsistencyCheck(MvField&, ApplicationInfo&) override;

    // Check if parameters between two requests are consistent
    bool consistencyCheck(MvRequest&, MvRequest&) override;

    std::string titleVariable(ApplicationInfo&, ParamInfo*) override;

private:
    int inputMode_{0};   // VP_POINT/VP_GRIDPOINT/VP_AREA/VP_AREA2
    int outputMode_{0};  // VP_NORMAL/VP_RTTOV

    // RTTOV specific parameters
    double waterType_{0.}, cloudTP_{0.}, cloudFraction_{0.};
};

//---------------------------------------------------------------------

class VprofileM3 : public Vprofile
{
public:
    VprofileM3() :
        Vprofile("PM_VPROF") {}

    void serve(MvRequest&, MvRequest&) override;
};
