// This may look like C code, but it is really -*- C++ -*-
//
// $Id: datacards.h,v 1.5 2006-07-07 11:16:02 ansari Exp $
//
// Datacards, acquisition EROS II
//
//
// Eric Aubourg, Decembre 95
// Reza Ansari, Aout 96
//
// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)

#ifndef DATACARDS_SEEN
#define DATACARDS_SEEN

#include "machdefs.h"
#include <string.h>
#include <string>
#include <functional>
#include <list>
#include <vector>


namespace SOPHYA {  

typedef int (*ProcCard)(string const& key, string const& toks);
 
//! Class for decoding parameters from  an ascii file.
    
class DataCards  {
public:

   DataCards();                  
   DataCards(string const& fn);

           // nom dans variable d'environnement SOPHYA_DATACARDS
           // par defaut, sophya.datacards                        
           // Si pas chemin complet, on tente dans repertoire 
           // en cours, puis dans SOPHYA_WORK

   virtual ~DataCards() {}

   void    AddProcF(ProcCard f, string const& mtch="*");

   void    Clear();
   void    ReadFile(string const& fn);
   void    AppendCard(string const& line);

   int     NbCards() const; 
   bool    HasKey(string const& key) const;
   int     NbParam(string const& key) const;
   string  GetKey(int num) const;
   string  GetParams(string const& key) const;
   string  SParam(string const& key, int numero = 0, string def="") const;
   long    IParam(string const& key, int numero = 0, long def = 0) const;
   double  DParam(string const& key, int numero = 0, double def = 0) const;
   
   void    Print(ostream& s) const;

protected:
  /*! \cond 
    Card structure - for internal use by DataCard 
  */
   struct Card {
     string kw;
     vector<string> tokens;
     bool operator == (Card const & b) const { return(kw == b.kw); }
     bool operator < (Card const & b) const { return(kw < b.kw); }
   };
   struct CrdPF {
     ProcCard pf;
     string  patt;
     bool operator == (CrdPF const & b) const { return(pf == b.pf); }
     bool operator < (CrdPF const & b) const { return(pf == b.pf); }
   };
  /*! \endcond */
   void  DoReadFile(string const& fn);

   int   ApplyPF(CrdPF & cpf, string const& key, string const& toks);
   int   ApplyPFL(string const& key, string const& toks);

   void  RemoveCard(string const& key);
   
   Card* FindKey(string const& key) ;

   typedef list<Card> CardList;
   typedef list<CrdPF> CrdPFList;

   CardList::const_iterator FindKeyC(string const& key) const;

   CardList cards;
   CrdPFList cpfs;

   struct KeyEq : binary_function<Card, string, bool> {
    bool operator()(const Card& x, const string& y) const { return x.kw == y; }
   };
};

//! operator << overloading - calls Print()
inline ostream& operator << (ostream& s, DataCards const & c)
{ c.Print(s); return s; }

} // namespace SOPHYA

#endif
