/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// 
// BEGIN_HTML 
// RooAICRegistry is a utility class for operator p.d.f
// classes that keeps track of analytical integration codes and
// associated normalization and integration sets.  
// END_HTML
//

#include "RooFit.h"

#include "RooAICRegistry.h"
#include "RooMsgService.h"
#include "RooArgSet.h"
#include "RooMsgService.h"

#include "Riostream.h"


using namespace std;

ClassImp(RooAICRegistry)
;

//_____________________________________________________________________________
RooAICRegistry::RooAICRegistry(UInt_t size) 
  : _clArr(0), _asArr1(0), _asArr2(0), _asArr3(0), _asArr4(0)
{
  _clArr.reserve(size);
  _asArr1.reserve(size);
  _asArr2.reserve(size);
  _asArr3.reserve(size);
  _asArr4.reserve(size);
}

//_____________________________________________________________________________
RooAICRegistry::RooAICRegistry(const RooAICRegistry& other)
  : _clArr(other._clArr), _asArr1(other._clArr.size(), 0), _asArr2(other._clArr.size(), 0),
    _asArr3(other._clArr.size(), 0), _asArr4(other._clArr.size(), 0)
{
  // Copy constructor

  // Copy code-list array if other PDF has one
  UInt_t size = other._clArr.size();
  if (size) {
    _asArr1.resize(size, 0);
    _asArr2.resize(size, 0);
    _asArr3.resize(size, 0);
    _asArr4.resize(size, 0);
    for(UInt_t i = 0; i < size; ++i) {
      _asArr1[i] = other._asArr1[i] ? ((RooArgSet*)other._asArr1[i]->snapshot(kFALSE)) : 0; 
      _asArr2[i] = other._asArr2[i] ? ((RooArgSet*)other._asArr2[i]->snapshot(kFALSE)) : 0;
      _asArr3[i] = other._asArr3[i] ? ((RooArgSet*)other._asArr3[i]->snapshot(kFALSE)) : 0;
      _asArr4[i] = other._asArr4[i] ? ((RooArgSet*)other._asArr4[i]->snapshot(kFALSE)) : 0;
    }
  }
}

//_____________________________________________________________________________
RooAICRegistry::~RooAICRegistry() 
{
  // Destructor

  // Delete code list array, if allocated
  for (unsigned int i = 0; i < _clArr.size(); ++i) {
    if (_asArr1[i]) delete   _asArr1[i];
    if (_asArr2[i]) delete   _asArr2[i];
    if (_asArr3[i]) delete   _asArr3[i];
    if (_asArr4[i]) delete   _asArr4[i];
  }
}

//_____________________________________________________________________________
Int_t RooAICRegistry::store(const std::vector<Int_t>& codeList, RooArgSet* set1,
                            RooArgSet* set2, RooArgSet* set3, RooArgSet* set4)
{
  // Store given arrays of integer codes, and up to four RooArgSets in
  // the registry (each setX pointer may be null). The registry
  // clones all RooArgSets internally so the RooArgSets passed as
  // arguments do not need to live beyond the store() call. The return
  // value is a unique master code for the given configuration of
  // integers and RooArgSets. If an identical combination is
  // previously stored in the registry no objects are stored and the
  // unique code of the existing entry is returned.

  // Loop over code-list array  
  for (UInt_t i = 0; i < _clArr.size(); ++i) {
    // Existing slot, compare with current list, if matched return index
    Bool_t match(kTRUE) ;
    
    // Check that array contents is identical
    match &= _clArr[i] == codeList;

    // Check that supplied configuration of lists is identical
    if (_asArr1[i] && !set1) match=kFALSE ;
    if (!_asArr1[i] && set1) match=kFALSE ;
    if (_asArr2[i] && !set2) match=kFALSE ;
    if (!_asArr2[i] && set2) match=kFALSE ;
    if (_asArr3[i] && !set3) match=kFALSE ;
    if (!_asArr3[i] && set3) match=kFALSE ;
    if (_asArr4[i] && !set4) match=kFALSE ;
    if (!_asArr4[i] && set4) match=kFALSE ;
    
    // Check that contents of arrays is identical
    if (_asArr1[i] && set1 && !set1->equals(*_asArr1[i])) match=kFALSE ;
    if (_asArr2[i] && set2 && !set2->equals(*_asArr2[i])) match=kFALSE ;	
    if (_asArr3[i] && set3 && !set3->equals(*_asArr3[i])) match=kFALSE ;	
    if (_asArr4[i] && set4 && !set4->equals(*_asArr4[i])) match=kFALSE ;	
    
    if (match) {
      if (set1) delete set1 ;
      if (set2) delete set2 ;
      if (set3) delete set3 ;
      if (set4) delete set4 ;
      return i ;
    }
  }

  // Store code list and return index
  _clArr.push_back(codeList);
  _asArr1.push_back(set1 ? (RooArgSet*)set1->snapshot(kFALSE) : 0);
  _asArr2.push_back(set2 ? (RooArgSet*)set2->snapshot(kFALSE) : 0);
  _asArr3.push_back(set3 ? (RooArgSet*)set3->snapshot(kFALSE) : 0);
  _asArr4.push_back(set4 ? (RooArgSet*)set4->snapshot(kFALSE) : 0);

  if (set1) delete set1 ;
  if (set2) delete set2 ;
  if (set3) delete set3 ;
  if (set4) delete set4 ;
  return _clArr.size() - 1;
}

//_____________________________________________________________________________
const std::vector<Int_t>& RooAICRegistry::retrieve(Int_t masterCode) const 
{
  // Retrieve the array of integer codes associated with the given master code
  return _clArr[masterCode] ;
}

//_____________________________________________________________________________
const std::vector<Int_t>& RooAICRegistry::retrieve(Int_t masterCode, pRooArgSet& set1) const 
{
  // Retrieve the array of integer codes associated with the given master code
  // and set the passed set1 pointer to the first RooArgSet associated with this master code

  set1 = _asArr1[masterCode] ;
  return _clArr[masterCode] ;
}

//_____________________________________________________________________________
const std::vector<Int_t>& RooAICRegistry::retrieve
(Int_t masterCode, pRooArgSet& set1, pRooArgSet& set2) const 
{
  // Retrieve the array of integer codes associated with the given master code
  // and set the passed set1,set2 pointers to the first and second  RooArgSets associated with this 
  // master code respectively

  set1 = _asArr1[masterCode] ;
  set2 = _asArr2[masterCode] ;
  return _clArr[masterCode] ;
}

//_____________________________________________________________________________
const std::vector<Int_t>& RooAICRegistry::retrieve
(Int_t masterCode, pRooArgSet& set1, pRooArgSet& set2, pRooArgSet& set3, pRooArgSet& set4) const 
{
  // Retrieve the array of integer codes associated with the given master code
  // and set the passed set1-4 pointers to the four  RooArgSets associated with this 
  // master code respectively
  set1 = _asArr1[masterCode] ;
  set2 = _asArr2[masterCode] ;
  set3 = _asArr3[masterCode] ;
  set4 = _asArr4[masterCode] ;
  return _clArr[masterCode] ;
}
 RooAICRegistry.cxx:1
 RooAICRegistry.cxx:2
 RooAICRegistry.cxx:3
 RooAICRegistry.cxx:4
 RooAICRegistry.cxx:5
 RooAICRegistry.cxx:6
 RooAICRegistry.cxx:7
 RooAICRegistry.cxx:8
 RooAICRegistry.cxx:9
 RooAICRegistry.cxx:10
 RooAICRegistry.cxx:11
 RooAICRegistry.cxx:12
 RooAICRegistry.cxx:13
 RooAICRegistry.cxx:14
 RooAICRegistry.cxx:15
 RooAICRegistry.cxx:16
 RooAICRegistry.cxx:17
 RooAICRegistry.cxx:18
 RooAICRegistry.cxx:19
 RooAICRegistry.cxx:20
 RooAICRegistry.cxx:21
 RooAICRegistry.cxx:22
 RooAICRegistry.cxx:23
 RooAICRegistry.cxx:24
 RooAICRegistry.cxx:25
 RooAICRegistry.cxx:26
 RooAICRegistry.cxx:27
 RooAICRegistry.cxx:28
 RooAICRegistry.cxx:29
 RooAICRegistry.cxx:30
 RooAICRegistry.cxx:31
 RooAICRegistry.cxx:32
 RooAICRegistry.cxx:33
 RooAICRegistry.cxx:34
 RooAICRegistry.cxx:35
 RooAICRegistry.cxx:36
 RooAICRegistry.cxx:37
 RooAICRegistry.cxx:38
 RooAICRegistry.cxx:39
 RooAICRegistry.cxx:40
 RooAICRegistry.cxx:41
 RooAICRegistry.cxx:42
 RooAICRegistry.cxx:43
 RooAICRegistry.cxx:44
 RooAICRegistry.cxx:45
 RooAICRegistry.cxx:46
 RooAICRegistry.cxx:47
 RooAICRegistry.cxx:48
 RooAICRegistry.cxx:49
 RooAICRegistry.cxx:50
 RooAICRegistry.cxx:51
 RooAICRegistry.cxx:52
 RooAICRegistry.cxx:53
 RooAICRegistry.cxx:54
 RooAICRegistry.cxx:55
 RooAICRegistry.cxx:56
 RooAICRegistry.cxx:57
 RooAICRegistry.cxx:58
 RooAICRegistry.cxx:59
 RooAICRegistry.cxx:60
 RooAICRegistry.cxx:61
 RooAICRegistry.cxx:62
 RooAICRegistry.cxx:63
 RooAICRegistry.cxx:64
 RooAICRegistry.cxx:65
 RooAICRegistry.cxx:66
 RooAICRegistry.cxx:67
 RooAICRegistry.cxx:68
 RooAICRegistry.cxx:69
 RooAICRegistry.cxx:70
 RooAICRegistry.cxx:71
 RooAICRegistry.cxx:72
 RooAICRegistry.cxx:73
 RooAICRegistry.cxx:74
 RooAICRegistry.cxx:75
 RooAICRegistry.cxx:76
 RooAICRegistry.cxx:77
 RooAICRegistry.cxx:78
 RooAICRegistry.cxx:79
 RooAICRegistry.cxx:80
 RooAICRegistry.cxx:81
 RooAICRegistry.cxx:82
 RooAICRegistry.cxx:83
 RooAICRegistry.cxx:84
 RooAICRegistry.cxx:85
 RooAICRegistry.cxx:86
 RooAICRegistry.cxx:87
 RooAICRegistry.cxx:88
 RooAICRegistry.cxx:89
 RooAICRegistry.cxx:90
 RooAICRegistry.cxx:91
 RooAICRegistry.cxx:92
 RooAICRegistry.cxx:93
 RooAICRegistry.cxx:94
 RooAICRegistry.cxx:95
 RooAICRegistry.cxx:96
 RooAICRegistry.cxx:97
 RooAICRegistry.cxx:98
 RooAICRegistry.cxx:99
 RooAICRegistry.cxx:100
 RooAICRegistry.cxx:101
 RooAICRegistry.cxx:102
 RooAICRegistry.cxx:103
 RooAICRegistry.cxx:104
 RooAICRegistry.cxx:105
 RooAICRegistry.cxx:106
 RooAICRegistry.cxx:107
 RooAICRegistry.cxx:108
 RooAICRegistry.cxx:109
 RooAICRegistry.cxx:110
 RooAICRegistry.cxx:111
 RooAICRegistry.cxx:112
 RooAICRegistry.cxx:113
 RooAICRegistry.cxx:114
 RooAICRegistry.cxx:115
 RooAICRegistry.cxx:116
 RooAICRegistry.cxx:117
 RooAICRegistry.cxx:118
 RooAICRegistry.cxx:119
 RooAICRegistry.cxx:120
 RooAICRegistry.cxx:121
 RooAICRegistry.cxx:122
 RooAICRegistry.cxx:123
 RooAICRegistry.cxx:124
 RooAICRegistry.cxx:125
 RooAICRegistry.cxx:126
 RooAICRegistry.cxx:127
 RooAICRegistry.cxx:128
 RooAICRegistry.cxx:129
 RooAICRegistry.cxx:130
 RooAICRegistry.cxx:131
 RooAICRegistry.cxx:132
 RooAICRegistry.cxx:133
 RooAICRegistry.cxx:134
 RooAICRegistry.cxx:135
 RooAICRegistry.cxx:136
 RooAICRegistry.cxx:137
 RooAICRegistry.cxx:138
 RooAICRegistry.cxx:139
 RooAICRegistry.cxx:140
 RooAICRegistry.cxx:141
 RooAICRegistry.cxx:142
 RooAICRegistry.cxx:143
 RooAICRegistry.cxx:144
 RooAICRegistry.cxx:145
 RooAICRegistry.cxx:146
 RooAICRegistry.cxx:147
 RooAICRegistry.cxx:148
 RooAICRegistry.cxx:149
 RooAICRegistry.cxx:150
 RooAICRegistry.cxx:151
 RooAICRegistry.cxx:152
 RooAICRegistry.cxx:153
 RooAICRegistry.cxx:154
 RooAICRegistry.cxx:155
 RooAICRegistry.cxx:156
 RooAICRegistry.cxx:157
 RooAICRegistry.cxx:158
 RooAICRegistry.cxx:159
 RooAICRegistry.cxx:160
 RooAICRegistry.cxx:161
 RooAICRegistry.cxx:162
 RooAICRegistry.cxx:163
 RooAICRegistry.cxx:164
 RooAICRegistry.cxx:165
 RooAICRegistry.cxx:166
 RooAICRegistry.cxx:167
 RooAICRegistry.cxx:168
 RooAICRegistry.cxx:169
 RooAICRegistry.cxx:170
 RooAICRegistry.cxx:171
 RooAICRegistry.cxx:172
 RooAICRegistry.cxx:173
 RooAICRegistry.cxx:174
 RooAICRegistry.cxx:175
 RooAICRegistry.cxx:176
 RooAICRegistry.cxx:177
 RooAICRegistry.cxx:178
 RooAICRegistry.cxx:179
 RooAICRegistry.cxx:180
 RooAICRegistry.cxx:181
 RooAICRegistry.cxx:182
 RooAICRegistry.cxx:183
 RooAICRegistry.cxx:184
 RooAICRegistry.cxx:185
 RooAICRegistry.cxx:186
 RooAICRegistry.cxx:187
 RooAICRegistry.cxx:188
 RooAICRegistry.cxx:189
 RooAICRegistry.cxx:190
 RooAICRegistry.cxx:191