/***************************** 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 MvMessageMetaData_H
#define MvMessageMetaData_H

#include <string>
#include <vector>

#ifdef METVIEW
//For off_t
#include "mars.h"
#else
#include <sys/types.h>
#endif

using namespace std;

class MvKeyProfile;
class MvMessageMetaDataObserver;

class MvMessageMetaData
{
public:
    enum Type
    {
        GribType,
        BufrType,
        Notype
    };

    MvMessageMetaData(Type type) :
        type_(type),
        messageNum_(0),
        totalMessageNum_(0),
        firstScan_(true),
        filterEnabled_(false) {}
    virtual ~MvMessageMetaData() {}

    Type type() const { return type_; }
    const string& fileName() const { return fileName_; }
    virtual void setFileName(string) = 0;
    int messageNum() { return messageNum_; }
    int totalMessageNum() { return totalMessageNum_; }
    virtual void setTotalMessageNum(int) = 0;

    void registerObserver(MvMessageMetaDataObserver* obs);
    virtual bool useMessageSizeForProgressIndicator() { return false; }
    bool isFilterEnabled() { return filterEnabled_; }
    virtual void setFilter(const vector<off_t>&, const vector<int>&) {}
    virtual void updateFilterCnt(const std::vector<off_t>& offset, const std::vector<int>& cnt) {}
    int unfilteredMessageCnt(int cntStartFromZero)
    {
        return (filterEnabled_) ? (filterCnt_[cntStartFromZero]) : cntStartFromZero + 1;
    }

    bool firstScan() const { return firstScan_; }
    void setFirstScan(bool b) { firstScan_ = b; }

    const std::vector<off_t>& filterOffset() const { return filterOffset_; }
    const std::vector<int>& filterLen() const { return filterLen_; }
    const std::vector<int>& filterCnt() const { return filterCnt_; }

    virtual void clearData()
    {
        messageNum_      = 0;
        totalMessageNum_ = 0;
        firstScan_       = true,
        filterEnabled_   = false,
        filterOffset_.clear();
        filterLen_.clear();
        filterCnt_.clear();
    }

protected:
    typedef void (MvMessageMetaDataObserver::*IntMethod)(int);
    typedef void (MvMessageMetaDataObserver::*VoidMethod)();
    void broadcast(IntMethod, int);
    void broadcast(VoidMethod);

    virtual void clear()
    {
        fileName_.clear();
        messageNum_      = 0;
        totalMessageNum_ = 0;
        firstScan_       = true,
        filterEnabled_   = false,
        filterOffset_.clear();
        filterLen_.clear();
        filterCnt_.clear();
    }

    Type type_;
    string fileName_;
    int messageNum_;
    int totalMessageNum_;
    bool firstScan_;
    bool filterEnabled_;
    std::vector<off_t> filterOffset_;
    std::vector<int> filterLen_;
    std::vector<int> filterCnt_;

    std::vector<MvMessageMetaDataObserver*> observers_;
};


class MvMessageMetaDataObserver
{
public:
    MvMessageMetaDataObserver() {}
    virtual ~MvMessageMetaDataObserver() {}

    virtual void messageScanStepChanged(int) {}
    virtual void locationScanStepChanged(int) {}
    virtual void messageFilterStarted() {}
    virtual void messageFilterFinished() {}
};

#endif
