// @(#)root/tree:$Id$
// Author: Axel Naumann, 2010-08-02

/*************************************************************************
 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TTreeReaderValue
#define ROOT_TTreeReaderValue


////////////////////////////////////////////////////////////////////////////
//                                                                        //
// TTreeReaderValue                                                    //
//                                                                        //
// A simple interface for reading data from trees or chains.              //
//                                                                        //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TString
#include "TString.h"
#endif
#ifndef ROOT_TDictionary
#include "TDictionary.h"
#endif
#ifndef ROOT_TBranchProxy
#include "TBranchProxy.h"
#endif

class TBranch;
class TBranchElement;
class TLeaf;
class TTreeReader;

namespace ROOT {

   class TTreeReaderValueBase {
   public:

      // Status flags, 0 is good
      enum ESetupStatus {
         kSetupNotSetup = -7,
         kSetupTreeDestructed = -8,
         kSetupMakeClassModeMismatch = -7, // readers disagree on whether TTree::SetMakeBranch() should be on
         kSetupMissingCounterBranch = -6,
         kSetupMissingBranch = -5,
         kSetupInternalError = -4,
         kSetupMissingCompiledCollectionProxy = -3,
         kSetupMismatch = -2,
         kSetupClassMismatch = -1,
         kSetupMatch = 0,
         kSetupMatchBranch = 0,
         kSetupMatchConversion,
         kSetupMatchConversionCollection,
         kSetupMakeClass,
         kSetupVoidPtr,
         kSetupNoCheck,
         kSetupMatchLeaf
      };
      enum EReadStatus {
         kReadSuccess = 0, // data read okay
         kReadNothingYet, // data now yet accessed
         kReadError // problem reading data
      };

      EReadStatus ProxyRead();

      Bool_t IsValid() const { return fProxy && 0 == (int)fSetupStatus && 0 == (int)fReadStatus; }
      ESetupStatus GetSetupStatus() const { return fSetupStatus; }
      virtual EReadStatus GetReadStatus() const { return fReadStatus; }

      TLeaf* GetLeaf();

      void* GetAddress();

      const char* GetBranchName() const { return fBranchName; }
      
   protected:
      TTreeReaderValueBase(TTreeReader* reader = 0, const char* branchname = 0, TDictionary* dict = 0);

      virtual ~TTreeReaderValueBase();

      virtual void CreateProxy();
      const char* GetBranchDataType(TBranch* branch,
                                    TDictionary* &dict) const;

      virtual const char* GetDerivedTypeName() const = 0;

      ROOT::TBranchProxy* GetProxy() const { return fProxy; }

      void MarkTreeReaderUnavailable() { fTreeReader = 0; }

      TString      fBranchName; // name of the branch to read data from.
      TString      fLeafName;
      TTreeReader* fTreeReader; // tree reader we belong to
      TDictionary* fDict; // type that the branch should contain
      ROOT::TBranchProxy* fProxy; // proxy for this branch, owned by TTreeReader
      TLeaf*       fLeaf;
      Long64_t     fTreeLastOffset;
      ESetupStatus fSetupStatus; // setup status of this data access
      EReadStatus  fReadStatus; // read status of this data access
      std::vector<Long64_t> fStaticClassOffsets;

      // FIXME: re-introduce once we have ClassDefInline!
      //ClassDef(TTreeReaderValueBase, 0);//Base class for accessors to data via TTreeReader

      friend class ::TTreeReader;
   };

} // namespace ROOT


template <typename T>
class TTreeReaderValue: public ROOT::TTreeReaderValueBase {
public:
   TTreeReaderValue() {}
   TTreeReaderValue(TTreeReader& tr, const char* branchname):
      TTreeReaderValueBase(&tr, branchname, TDictionary::GetDictionary(typeid(T))) {}

   T* Get() {
      if (!fProxy){
         Error("Get()", "Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?");
         return 0;
      }
      void *address = GetAddress(); // Needed to figure out if it's a pointer
      return fProxy->IsaPointer() ? *(T**)address : (T*)address; }
   T* operator->() { return Get(); }
   T& operator*() { return *Get(); }

protected:
   // FIXME: use IsA() instead once we have ClassDefTInline
#define R__TTreeReaderValue_TypeString(T) #T
   virtual const char* GetDerivedTypeName() const { return R__TTreeReaderValue_TypeString(T); }
#undef R__TTreeReaderValue_TypeString

   // FIXME: re-introduce once we have ClassDefTInline!
   //ClassDefT(TTreeReaderValue, 0);//Accessor to data via TTreeReader
};

#endif // ROOT_TTreeReaderValue
 TTreeReaderValue.h:1
 TTreeReaderValue.h:2
 TTreeReaderValue.h:3
 TTreeReaderValue.h:4
 TTreeReaderValue.h:5
 TTreeReaderValue.h:6
 TTreeReaderValue.h:7
 TTreeReaderValue.h:8
 TTreeReaderValue.h:9
 TTreeReaderValue.h:10
 TTreeReaderValue.h:11
 TTreeReaderValue.h:12
 TTreeReaderValue.h:13
 TTreeReaderValue.h:14
 TTreeReaderValue.h:15
 TTreeReaderValue.h:16
 TTreeReaderValue.h:17
 TTreeReaderValue.h:18
 TTreeReaderValue.h:19
 TTreeReaderValue.h:20
 TTreeReaderValue.h:21
 TTreeReaderValue.h:22
 TTreeReaderValue.h:23
 TTreeReaderValue.h:24
 TTreeReaderValue.h:25
 TTreeReaderValue.h:26
 TTreeReaderValue.h:27
 TTreeReaderValue.h:28
 TTreeReaderValue.h:29
 TTreeReaderValue.h:30
 TTreeReaderValue.h:31
 TTreeReaderValue.h:32
 TTreeReaderValue.h:33
 TTreeReaderValue.h:34
 TTreeReaderValue.h:35
 TTreeReaderValue.h:36
 TTreeReaderValue.h:37
 TTreeReaderValue.h:38
 TTreeReaderValue.h:39
 TTreeReaderValue.h:40
 TTreeReaderValue.h:41
 TTreeReaderValue.h:42
 TTreeReaderValue.h:43
 TTreeReaderValue.h:44
 TTreeReaderValue.h:45
 TTreeReaderValue.h:46
 TTreeReaderValue.h:47
 TTreeReaderValue.h:48
 TTreeReaderValue.h:49
 TTreeReaderValue.h:50
 TTreeReaderValue.h:51
 TTreeReaderValue.h:52
 TTreeReaderValue.h:53
 TTreeReaderValue.h:54
 TTreeReaderValue.h:55
 TTreeReaderValue.h:56
 TTreeReaderValue.h:57
 TTreeReaderValue.h:58
 TTreeReaderValue.h:59
 TTreeReaderValue.h:60
 TTreeReaderValue.h:61
 TTreeReaderValue.h:62
 TTreeReaderValue.h:63
 TTreeReaderValue.h:64
 TTreeReaderValue.h:65
 TTreeReaderValue.h:66
 TTreeReaderValue.h:67
 TTreeReaderValue.h:68
 TTreeReaderValue.h:69
 TTreeReaderValue.h:70
 TTreeReaderValue.h:71
 TTreeReaderValue.h:72
 TTreeReaderValue.h:73
 TTreeReaderValue.h:74
 TTreeReaderValue.h:75
 TTreeReaderValue.h:76
 TTreeReaderValue.h:77
 TTreeReaderValue.h:78
 TTreeReaderValue.h:79
 TTreeReaderValue.h:80
 TTreeReaderValue.h:81
 TTreeReaderValue.h:82
 TTreeReaderValue.h:83
 TTreeReaderValue.h:84
 TTreeReaderValue.h:85
 TTreeReaderValue.h:86
 TTreeReaderValue.h:87
 TTreeReaderValue.h:88
 TTreeReaderValue.h:89
 TTreeReaderValue.h:90
 TTreeReaderValue.h:91
 TTreeReaderValue.h:92
 TTreeReaderValue.h:93
 TTreeReaderValue.h:94
 TTreeReaderValue.h:95
 TTreeReaderValue.h:96
 TTreeReaderValue.h:97
 TTreeReaderValue.h:98
 TTreeReaderValue.h:99
 TTreeReaderValue.h:100
 TTreeReaderValue.h:101
 TTreeReaderValue.h:102
 TTreeReaderValue.h:103
 TTreeReaderValue.h:104
 TTreeReaderValue.h:105
 TTreeReaderValue.h:106
 TTreeReaderValue.h:107
 TTreeReaderValue.h:108
 TTreeReaderValue.h:109
 TTreeReaderValue.h:110
 TTreeReaderValue.h:111
 TTreeReaderValue.h:112
 TTreeReaderValue.h:113
 TTreeReaderValue.h:114
 TTreeReaderValue.h:115
 TTreeReaderValue.h:116
 TTreeReaderValue.h:117
 TTreeReaderValue.h:118
 TTreeReaderValue.h:119
 TTreeReaderValue.h:120
 TTreeReaderValue.h:121
 TTreeReaderValue.h:122
 TTreeReaderValue.h:123
 TTreeReaderValue.h:124
 TTreeReaderValue.h:125
 TTreeReaderValue.h:126
 TTreeReaderValue.h:127
 TTreeReaderValue.h:128
 TTreeReaderValue.h:129
 TTreeReaderValue.h:130
 TTreeReaderValue.h:131
 TTreeReaderValue.h:132
 TTreeReaderValue.h:133
 TTreeReaderValue.h:134
 TTreeReaderValue.h:135
 TTreeReaderValue.h:136
 TTreeReaderValue.h:137
 TTreeReaderValue.h:138
 TTreeReaderValue.h:139
 TTreeReaderValue.h:140
 TTreeReaderValue.h:141
 TTreeReaderValue.h:142
 TTreeReaderValue.h:143
 TTreeReaderValue.h:144
 TTreeReaderValue.h:145