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

// File Decoder
// Gilberto Camara - ECMWF Jul 97
//
// .NAME:	
//  Decoder
//
// .AUTHOR:
//  Gilberto Camara and Fernando Ii
//
// .SUMMARY:
//  An abstract data class for decoding different types
//  of meteorological data processed by PlotMod
//  (which uses EMOSlib and Mars' interface to Emoslib)
//
// .CLIENTS:
//  PlotModMatcher, Graphics Engine
//
//
// .RESPONSABILITIES:
//  For each data time, provide information on parameter,
//  date, time and level
//
//  
// .COLLABORATORS:
//  Date, Time, Emos, PathName
//
//
// .BASE CLASS:
//  Decoder
//
// .DERIVED CLASSES:
//  GribDecoder, BufrDecoder, MatrixDecoder, GeoPointsDecoder,
//  NetCDFDecoder
//
// .REFERENCES:
//
//  The design of this class is based on the "Factory" pattern
//  ("Design Patterns", page. 107).
//
//  For additional references please see Coplien's chapter 8
//  ("Programming with Exemplars")
//
//
//  The templated factory is based on the idea of "traits"
//  described in the article "A New and Useful Template Technique: "Traits"
//  by Nathan Myers, included in the "C++ Gems" book
//  (see also Stroustrup, 3rd. edition, page 580ff).
//
#ifndef MvDecoder_H
#define MvDecoder_H

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

class Decoder;
class MatchingInfo;

// Class Decoder Factory - clones a new Decoder

struct DecoderFactoryTraits {
  typedef Decoder             Type;
  typedef const MvRequest&    Parameter;
  static  Cached              FactoryName   ( Parameter );
  static  Type*               DefaultObject ( Parameter );
};


class DecoderFactory : public Factory<DecoderFactoryTraits> 
{
public:
  DecoderFactory(const Cached& name) :
    Factory<DecoderFactoryTraits>(name) {}	
};

//typedef vector<Cached> VariableNamesList;
//typedef vector<float>  DataVector;

class Decoder {
public:

  // Contructors
  Decoder (  const MvRequest& );

  // Destructor
  virtual ~Decoder();

  virtual MatchingInfo CreateMatchingInfo () = 0;

  // Methods with are overriden by derived classes. Default 
  // implementations provided for convenience of derived classes,
  // as some of the functions are irrelevant to most derived classes.

  // Goes to the next data (returns false if no more data)
  virtual bool ReadNextData () { return false; }

  virtual bool GetData ( vector<double>&, const char* ) { return false; }
  virtual bool GetRequest(MvRequest&, const char *) { return false; }
  // for netcf decoder;
  virtual Cached GetView() { return Cached(""); }

  // Overridden by decoders that need to update their request
  virtual bool UpdateDataRequest(MvRequest &) { return false; }

  // Derived decoders are responsible for setting values correctly
  virtual void GetMinMax(double &minX, double &maxX, double &minY, double &maxY)
    {  minX = minX_;maxX = maxX_;minY = minY_;maxY = maxY_; }

  // Returns the offset (data size)
  virtual long CurrentOffset ()
    { return offset_; }

  MvRequest Request () const
    { return metadataRequest_; }

protected:

  // Utilities for derived classes
  void AddData( MvRequest& out, vector<double> &dataVector, const char *outName );
  void AddData( MvRequest& out, vector<string> &dataVector, const char *outName );

  void CheckMinMax(vector<double> &values, double &oldMax, double &oldMin);

  void SetTitle(MvRequest&);

  // Members
  MvRequest metadataRequest_; // request which contains metadata info
  long      offset_;
  bool      nextData_;
  double    minX_,maxX_,minY_,maxY_;

private:

  // No copy allowed
  Decoder(const Decoder&);
  Decoder& operator=(const Decoder&){return *this;}
};
#endif
