// Author: I. Froehlich
// Written: 11.04.2007
// Revised: 
// PDataBase
// Replacement for the particle data base in PData

#ifndef _PDATABASE_H_
#define _PDATABASE_H_

#include "TROOT.h"
#include <iostream>
#include "PDefines.h"

#define PDATABASE_MAX_DOUBLE_PARAM 20
#define PDATABASE_MAX_STRING_PARAM 20
#define PDATABASE_MAX_INT_PARAM 150
#define PDATABASE_MAX_TOBJ_PARAM 10

#define PDATABASE_MAX_LINES 5000

using namespace std;

class PDataBase;
PDataBase* makeDataBase();
PDataBase& fDataBase();

class PDataBase : public TObject {

 private:

    //Entries properties
    const char *param_double_name[PDATABASE_MAX_DOUBLE_PARAM]; //the parameter name matching the ID
    const char *param_string_name[PDATABASE_MAX_STRING_PARAM]; 
    const char *param_int_name[PDATABASE_MAX_INT_PARAM];       
    const char *param_tobj_name[PDATABASE_MAX_INT_PARAM]; 
    const char *param_double_descr[PDATABASE_MAX_DOUBLE_PARAM]; //the parameter long description
    const char *param_string_descr[PDATABASE_MAX_STRING_PARAM]; 
    const char *param_int_descr[PDATABASE_MAX_INT_PARAM];       
    const char *param_tobj_descr[PDATABASE_MAX_INT_PARAM]; 
    Int_t   param_double_pointer;
    Int_t   param_string_pointer;
    Int_t   param_int_pointer;
    Int_t   param_tobj_pointer;

    //TODO: Params need description

    Int_t  *param_int_key[PDATABASE_MAX_INT_PARAM];
    Int_t   param_int_key_max[PDATABASE_MAX_INT_PARAM];

    //The entries array itself
    //for each entry, we add the pointer array to our params
    const char *strings[PDATABASE_MAX_LINES][PDATABASE_MAX_STRING_PARAM];
    Double_t   *doubles[PDATABASE_MAX_LINES][PDATABASE_MAX_DOUBLE_PARAM];
    Int_t      *ints[PDATABASE_MAX_LINES][PDATABASE_MAX_INT_PARAM];
    TObject    *tobjs[PDATABASE_MAX_LINES][PDATABASE_MAX_TOBJ_PARAM];

    Int_t  lastkey;

    Bool_t CheckEntry(Int_t key);  //check if key with unique name already existing
    Int_t  ConvertParamKey(const char * &newparamname, Int_t key);

 public:

    //constructor
    PDataBase();

    void    Performance(void);

    void    SetFastKey(Int_t pkey, Int_t maxkey);
    //return value of the makeParam's: the param_id of -1 on failure
    Int_t   MakeParamDouble(const char *paramname, 
			    const char *descr);//add "paramname" to double database
    Int_t   MakeParamString(const char *paramname, 
			    const char *descr); //add "paramname" to string database
    Int_t   MakeParamInt(const char *paramname, 
			 const char *descr);    //add "paramname" to int database
    Int_t   MakeParamTObj(const char *paramname, 
			  const char *descr);   //add "paramname" to object database

    Int_t   GetParamDouble(const char *paramname); //get "paramname" from double database
    Int_t   GetParamString(const char *paramname); //get "paramname" from string database
    Int_t   GetParamInt   (const char *paramname, Int_t length=-1);  //get "paramname" from string database
    Int_t   GetParamTObj  (const char *paramname);

    char   *GetDescription(const char* paramname);

    void    GetFastParamInt(const char* paramname, Int_t *pkey) {
	    if ((*pkey)<0) *pkey = GetParamInt(paramname);
	};  
    void    GetFastParamString(const char* paramname, Int_t *pkey) {
	    if ((*pkey)<0) *pkey = GetParamString(paramname);
	}; 
    void    GetFastParamDouble(const char* paramname, Int_t *pkey) {
	    if ((*pkey)<0) *pkey = GetParamDouble(paramname);
	}; 
    void    GetFastParamTObj(const char* paramname, Int_t *pkey) {
	    if ((*pkey)<0) *pkey = GetParamTObj(paramname);
	}; 
    
    using TObject::GetName;
    const char *GetName(Int_t key);
    //getting particle/decay properties from data base 
    //return kFALSE if 1.) key not existing or 2.) Param not existing or 3.) Param not used for entry
    Bool_t  GetParamDouble (Int_t key, const char *paramname, Double_t **result);
    Bool_t  GetParamString (Int_t key, const char *paramname, const char **result);
    Bool_t  GetParamInt  (Int_t key, const char *paramname, Int_t **result, Int_t length=-1);
    Bool_t  GetParamTObj (Int_t key, const char *paramname, TObject **result);

    //same as above but with the pkey as obtained by the getFastParam's
    Bool_t GetParamInt (Int_t key, Int_t pkey, Int_t **result);
    Bool_t GetParamString (Int_t key, Int_t pkey, const char **result);
    Bool_t GetParamDouble (Int_t key, Int_t pkey, Double_t **result);
    Bool_t GetParamTObj   (Int_t key, Int_t pkey, TObject **result);

    //setting value instead of pointer
    Bool_t GetParamInt (Int_t key, Int_t pkey, Int_t *result) {
	Int_t *p;
	Bool_t b = GetParamInt (key, pkey, &p);
	if (b && p)
	    *result = *p;
	else 
	    *result = 0;
	return b;
    };

    //getting param by primary name
    Bool_t GetParamInt(const char *name, const char *paramname, Int_t **result) {
	return GetParamInt(GetEntry(name), paramname, result);
	};
    Bool_t GetParamDouble(const char *name, const char *paramname, Double_t **result) {
	return GetParamDouble(GetEntry(name), paramname, result);
	};
    Bool_t GetParamString(const char *name, const char *paramname, const char **result) {
	return GetParamString(GetEntry(name), paramname, result);
	};
    Bool_t GetParamTObj(const char *name, const char *paramname, TObject **result) {
	return GetParamTObj(GetEntry(name), paramname, result);
	};

    //Getting param by matching integer value
    Bool_t GetParamInt(const char *paramname1, Int_t value1, const char *paramname2, Int_t **result) {	
	return GetParamInt(GetEntryInt(paramname1,value1), paramname2, result);
    };
    Bool_t GetParamDouble(const char *paramname1, Int_t value1, const char *paramname2, Double_t **result) {	
	return GetParamDouble(GetEntryInt(paramname1,value1), paramname2, result);
    };
    Bool_t GetParamString(const char *paramname1, Int_t value1, const char *paramname2, const char **result) {	
	return GetParamString (GetEntryInt(paramname1,value1), paramname2, result);
    };
    Bool_t GetParamTObj(const char *paramname1, Int_t value1, const char *paramname2, TObject **result) {	
	return GetParamTObj(GetEntryInt(paramname1,value1), paramname2, result);
    };

    //same as above when the pkey are known...
    Bool_t GetParamInt (Int_t pkey1, Int_t value1, Int_t pkey2, Int_t **result) {
	return GetParamInt(GetEntryInt(pkey1,value1), pkey2, result);
    };
    Bool_t GetParamDouble(Int_t pkey1, Int_t value1, Int_t pkey2, Double_t **result) {	
	return GetParamDouble(GetEntryInt(pkey1,value1), pkey2, result);
    };
    Bool_t GetParamString(Int_t pkey1, Int_t value1, Int_t pkey2, const char **result) {	
	return GetParamString(GetEntryInt(pkey1,value1), pkey2, result);
    };
    Bool_t GetParamTObj(Int_t pkey1, Int_t value1, Int_t pkey2, TObject **result) {	
	return GetParamTObj(GetEntryInt(pkey1,value1), pkey2, result);
    };


    Bool_t SetParamDouble (Int_t key, const char *paramname, Double_t *result);
    Bool_t SetParamString (Int_t key, const char *paramname, char *result);   
    Bool_t SetParamInt    (Int_t key, const char *paramname, Int_t *result);   
    Bool_t SetParamTObj   (Int_t key, const char *paramname, TObject *result);   

    //faster:
    Bool_t SetParamTObj(Int_t key, Int_t pp, TObject *result);

    Bool_t SetParamDouble(const char *name, const char *paramname, Double_t result) {
	Int_t key = GetEntry(name);
	if (key<0) return kFALSE;
	return SetParamDouble(key, paramname, new Double_t(result));
    }
    Bool_t SetParamInt(const char *name, const char *paramname, Int_t result) {
	Int_t key = GetEntry(name);
	if (key<0) return kFALSE;
	return SetParamInt(key, paramname, new Int_t(result));
    }
    Bool_t SetParamString(const char *name, const char *paramname, char *result) {
	Int_t key = GetEntry(name);
	if (key<0) return kFALSE;
	return SetParamString(key, paramname, result);
    };   
    Bool_t SetParamTObj(const char *name, const char *paramname, TObject *result) {
	Int_t key = GetEntry(name);
	if (key<0) return kFALSE;
	return SetParamTObj(key, paramname, result);
    }; 

    //Dealing with the entries
    Bool_t  AddEntry(Int_t key, const char *name);
    Int_t   AddEntry(const char *name);
    Int_t   GetEntry(const char *name); 
    Int_t   GetEntryInt(const char *paramname, Int_t value); 
    Int_t   GetEntryInt(Int_t pkey, Int_t value); 

    //listings
    Int_t   AddListEntry(const char *name, const char *count, const char *link, const char *newname);
    Bool_t  MakeListIterator(Int_t key, const char *count, const char *link, Int_t *listkey);
    Bool_t  MakeListIterator(Int_t key, Int_t count, Int_t link, Int_t *listkey);

    Bool_t  ListEntries(Int_t key=-1, Int_t option=0, const char *pattern=NULL);

    void Print(const Option_t* delme=NULL) const ;


    ClassDef(PDataBase, 0)  //Relational data base for pluto
};

#endif
 PDataBase.h:1
 PDataBase.h:2
 PDataBase.h:3
 PDataBase.h:4
 PDataBase.h:5
 PDataBase.h:6
 PDataBase.h:7
 PDataBase.h:8
 PDataBase.h:9
 PDataBase.h:10
 PDataBase.h:11
 PDataBase.h:12
 PDataBase.h:13
 PDataBase.h:14
 PDataBase.h:15
 PDataBase.h:16
 PDataBase.h:17
 PDataBase.h:18
 PDataBase.h:19
 PDataBase.h:20
 PDataBase.h:21
 PDataBase.h:22
 PDataBase.h:23
 PDataBase.h:24
 PDataBase.h:25
 PDataBase.h:26
 PDataBase.h:27
 PDataBase.h:28
 PDataBase.h:29
 PDataBase.h:30
 PDataBase.h:31
 PDataBase.h:32
 PDataBase.h:33
 PDataBase.h:34
 PDataBase.h:35
 PDataBase.h:36
 PDataBase.h:37
 PDataBase.h:38
 PDataBase.h:39
 PDataBase.h:40
 PDataBase.h:41
 PDataBase.h:42
 PDataBase.h:43
 PDataBase.h:44
 PDataBase.h:45
 PDataBase.h:46
 PDataBase.h:47
 PDataBase.h:48
 PDataBase.h:49
 PDataBase.h:50
 PDataBase.h:51
 PDataBase.h:52
 PDataBase.h:53
 PDataBase.h:54
 PDataBase.h:55
 PDataBase.h:56
 PDataBase.h:57
 PDataBase.h:58
 PDataBase.h:59
 PDataBase.h:60
 PDataBase.h:61
 PDataBase.h:62
 PDataBase.h:63
 PDataBase.h:64
 PDataBase.h:65
 PDataBase.h:66
 PDataBase.h:67
 PDataBase.h:68
 PDataBase.h:69
 PDataBase.h:70
 PDataBase.h:71
 PDataBase.h:72
 PDataBase.h:73
 PDataBase.h:74
 PDataBase.h:75
 PDataBase.h:76
 PDataBase.h:77
 PDataBase.h:78
 PDataBase.h:79
 PDataBase.h:80
 PDataBase.h:81
 PDataBase.h:82
 PDataBase.h:83
 PDataBase.h:84
 PDataBase.h:85
 PDataBase.h:86
 PDataBase.h:87
 PDataBase.h:88
 PDataBase.h:89
 PDataBase.h:90
 PDataBase.h:91
 PDataBase.h:92
 PDataBase.h:93
 PDataBase.h:94
 PDataBase.h:95
 PDataBase.h:96
 PDataBase.h:97
 PDataBase.h:98
 PDataBase.h:99
 PDataBase.h:100
 PDataBase.h:101
 PDataBase.h:102
 PDataBase.h:103
 PDataBase.h:104
 PDataBase.h:105
 PDataBase.h:106
 PDataBase.h:107
 PDataBase.h:108
 PDataBase.h:109
 PDataBase.h:110
 PDataBase.h:111
 PDataBase.h:112
 PDataBase.h:113
 PDataBase.h:114
 PDataBase.h:115
 PDataBase.h:116
 PDataBase.h:117
 PDataBase.h:118
 PDataBase.h:119
 PDataBase.h:120
 PDataBase.h:121
 PDataBase.h:122
 PDataBase.h:123
 PDataBase.h:124
 PDataBase.h:125
 PDataBase.h:126
 PDataBase.h:127
 PDataBase.h:128
 PDataBase.h:129
 PDataBase.h:130
 PDataBase.h:131
 PDataBase.h:132
 PDataBase.h:133
 PDataBase.h:134
 PDataBase.h:135
 PDataBase.h:136
 PDataBase.h:137
 PDataBase.h:138
 PDataBase.h:139
 PDataBase.h:140
 PDataBase.h:141
 PDataBase.h:142
 PDataBase.h:143
 PDataBase.h:144
 PDataBase.h:145
 PDataBase.h:146
 PDataBase.h:147
 PDataBase.h:148
 PDataBase.h:149
 PDataBase.h:150
 PDataBase.h:151
 PDataBase.h:152
 PDataBase.h:153
 PDataBase.h:154
 PDataBase.h:155
 PDataBase.h:156
 PDataBase.h:157
 PDataBase.h:158
 PDataBase.h:159
 PDataBase.h:160
 PDataBase.h:161
 PDataBase.h:162
 PDataBase.h:163
 PDataBase.h:164
 PDataBase.h:165
 PDataBase.h:166
 PDataBase.h:167
 PDataBase.h:168
 PDataBase.h:169
 PDataBase.h:170
 PDataBase.h:171
 PDataBase.h:172
 PDataBase.h:173
 PDataBase.h:174
 PDataBase.h:175
 PDataBase.h:176
 PDataBase.h:177
 PDataBase.h:178
 PDataBase.h:179
 PDataBase.h:180
 PDataBase.h:181
 PDataBase.h:182
 PDataBase.h:183
 PDataBase.h:184
 PDataBase.h:185
 PDataBase.h:186
 PDataBase.h:187
 PDataBase.h:188
 PDataBase.h:189
 PDataBase.h:190
 PDataBase.h:191
 PDataBase.h:192
 PDataBase.h:193
 PDataBase.h:194
 PDataBase.h:195
 PDataBase.h:196
 PDataBase.h:197
 PDataBase.h:198
 PDataBase.h:199
 PDataBase.h:200
 PDataBase.h:201
 PDataBase.h:202
 PDataBase.h:203
 PDataBase.h:204
 PDataBase.h:205
 PDataBase.h:206
 PDataBase.h:207
 PDataBase.h:208
 PDataBase.h:209
 PDataBase.h:210
 PDataBase.h:211
 PDataBase.h:212
 PDataBase.h:213
 PDataBase.h:214
 PDataBase.h:215
 PDataBase.h:216
 PDataBase.h:217
 PDataBase.h:218