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

#include <MvGeoPoints.h>

#include <iomanip>

#include "GeopointsDecoder.h"
#include "MatchingInfo.h"
#include "PlotMod.h"
#include "MvLog.h"


// =====================================================
// class GeopointsDecoderFactory - builds  decoders
//

class GeopointsDecoderFactory : public DecoderFactory
{
    // Virtual Constructor - Builds a new GeopointsDecoder
    Decoder* Build(const MvRequest& inRequest) override
    {
        return new GeopointsDecoder(inRequest);
    }

public:
    GeopointsDecoderFactory() :
        DecoderFactory("GeopointsDecoder") {}
};

static GeopointsDecoderFactory geopointsDecoderFactoryInstance;

//=======================================================
//
// Methods for the GeopointsDecoder class
//

GeopointsDecoder::GeopointsDecoder(const MvRequest& dataUnitRequest) :
    Decoder(dataUnitRequest)
{
    nextData_ = true;
    metadataRequest_ = dataUnitRequest;
}

GeopointsDecoder::~GeopointsDecoder() = default;

// Read Next Data
//
// -- Returns true first time it's called, then false.
bool GeopointsDecoder::ReadNextData()
{
    if (nextData_) {
        nextData_ = false;
        return true;
    }
    else
        return false;
}

// Create MatchingInfo
//
// -- Use the first geopoint line to get date & time values.
//    If date is suspicious, ignore it (hopefully this gives
//    better backward compatibility!)
//
MatchingInfo
GeopointsDecoder::CreateMatchingInfo()
{
    MvRequest matchingRequest("MATCHING_INFO");

    matchingRequest("DATA_TYPE") = "GEOPOINTS";
    SetTitle(matchingRequest);

    //-- get date and time from the first geopoint
    MvGeoPoints gpts((const char*)metadataRequest_("PATH"), 1);
    long myDate = gpts.date(0);

    if (myDate > 19010101)  //-- a very simple date value check
    {
        matchingRequest("DATE") = myDate;

        long myTime = gpts.time(0);
        if (myTime < 24 && myTime != 0)  //-- simple check for format HH
        {
            MvLog().popup().warn() << "Suspicuous geopoints time; HHMM needed for overlay matching!";
        }

        //-- overlay matching checks strings, add leading zeros to make format 'HHMM'
        std::ostringstream os;
        os << std::setfill('0') << std::setw(4) << myTime;
        matchingRequest("TIME") = os.str().c_str();
    }
    else if (myDate != 0)  //-- date 0 is probably format XYV
    {
        //-- not adding DATE/TIME will prevent overlay matching --//
        MvLog().popup().warn() << "Invalid geopoints date; no overlay matching!";
    }

    // Save format info
    if (!(const char*)metadataRequest_("FORMAT")) {
        metadataRequest_("FORMAT") = (const char*)gpts.sFormat().c_str();
        metadataRequest_("VECTOR_FORMAT") = gpts.hasVectors();
        if (gpts.hasVectors())
            metadataRequest_("_VISDEF") = "MWIND";
    }

    // Save data dimension info
    matchingRequest("_NDIM_FLAG") = gpts.hasVectors() ? 2 : 1;

    return {matchingRequest};
}

// Add a proper datarequest with a geopoints record
bool GeopointsDecoder::UpdateDataRequest(MvRequest& geo)
{
    geo = metadataRequest_;
    MvRequest record("RECORD");
    record("PATH") = metadataRequest_("PATH");
    geo.setValue("RECORD", record);

    return true;
}
