/*****************************************************************************
 * 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
// RooListProxy is the concrete proxy for RooArgList objects.
// A RooListProxy is the only safe mechanism to store a RooArgList
// with RooAbsArg contents in another RooAbsArg.
// <p>
// The list proxy has the semantic of a RooArgList but also 
// takes care of all bookkeeping required when composite objects
// are clone and client-server links need to be redirected.
// END_HTML
//


#include "RooFit.h"
#include "Riostream.h"

#include "RooListProxy.h"
#include "RooArgList.h"
#include "RooAbsArg.h"

using namespace std;

ClassImp(RooListProxy)
;



//_____________________________________________________________________________
RooListProxy::RooListProxy(const char* inName, const char* /*desc*/, RooAbsArg* owner, 
			 Bool_t defValueServer, Bool_t defShapeServer) :
  RooArgList(inName), _owner(owner), 
  _defValueServer(defValueServer), 
  _defShapeServer(defShapeServer)
{
  // Constructor with proxy name, description and pointer to ownder of
  // the RooListProxy. The default strategy for value/shape dirty flag
  // propagation of the list contents to the list owner is controlled
  // by the defValueServer and defShapeServer flags.

  _owner->registerProxy(*this) ;
  _iter = createIterator() ;
}



//_____________________________________________________________________________
RooListProxy::RooListProxy(const char* inName, RooAbsArg* owner, const RooListProxy& other) : 
  RooArgList(other,inName), _owner(owner),  
  _defValueServer(other._defValueServer), 
  _defShapeServer(other._defShapeServer)
{
  // Copy constructor with name of proxy, pointer to owner of this proxy and
  // reference to list proxy to be copied

  _owner->registerProxy(*this) ;
  _iter = createIterator() ;
}



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

  if (_owner) _owner->unRegisterProxy(*this) ;
  delete _iter ;
}



//_____________________________________________________________________________
Bool_t RooListProxy::add(const RooAbsArg& var, Bool_t valueServer, Bool_t shapeServer, Bool_t silent)
{
  // Add object to list with explicitl directives on value and shape dirty flag propagation
  // of inserted object to list owner

  Bool_t ret=RooArgList::add(var,silent) ;
  if (ret && _owner) {
    _owner->addServer((RooAbsArg&)var,valueServer,shapeServer) ;
  }
  return ret ;  
}



//_____________________________________________________________________________
Bool_t RooListProxy::add(const RooAbsArg& var, Bool_t silent) 
{
  // Reimplementation of standard RooArgList::add()

  return add(var,_defValueServer,_defShapeServer,silent) ;
}



//_____________________________________________________________________________
Bool_t RooListProxy::addOwned(RooAbsArg& var, Bool_t silent)
{
  // Reimplementation of standard RooArgList::addOwned()

  Bool_t ret=RooArgList::addOwned(var,silent) ;
  if (ret) {
    _owner->addServer((RooAbsArg&)var,_defValueServer,_defShapeServer) ;
  }
  return ret ;  
}


//_____________________________________________________________________________
Bool_t RooListProxy::replace(const RooAbsArg& var1, const RooAbsArg& var2) 
{
  // Reimplementation of standard RooArgList::replace()

  Bool_t ret=RooArgList::replace(var1,var2) ;
  if (ret) {
    _owner->removeServer((RooAbsArg&)var1) ;
    _owner->addServer((RooAbsArg&)var2,_owner->isValueServer(var1),
		                       _owner->isShapeServer(var2)) ;
  }
  return ret ;
}



//_____________________________________________________________________________
Bool_t RooListProxy::remove(const RooAbsArg& var, Bool_t silent, Bool_t matchByNameOnly) 
{
  // Reimplementation of standard RooArgList::remove()

  Bool_t ret=RooArgList::remove(var,silent,matchByNameOnly) ;
  if (ret) {
    _owner->removeServer((RooAbsArg&)var) ;
  }
  return ret ;
}



//_____________________________________________________________________________
void RooListProxy::removeAll() 
{
  // Reimplementation of standard RooArgList::removeAll()

  TIterator* iter = createIterator() ;
  RooAbsArg* arg ;
  while ((arg=(RooAbsArg*)iter->Next())) {
    _owner->removeServer(*arg) ;
  }
  delete iter ;

  RooArgList::removeAll() ;
}




//_____________________________________________________________________________
RooListProxy& RooListProxy::operator=(const RooArgList& other) 
{
  // Reimplementation of standard RooArgList assignment operator

  RooArgList::operator=(other) ;
  return *this ;
}




//_____________________________________________________________________________
Bool_t RooListProxy::changePointer(const RooAbsCollection& newServerList, Bool_t nameChange, Bool_t factoryInitMode) 
{
  // Internal function that implements consequences of a server redirect on the
  // owner. If the list contains any element with names identical to those in newServerList
  // replace them with the instance in newServerList

  if (getSize()==0) {
    if (factoryInitMode) {
      TIterator* iter = newServerList.createIterator() ;
      RooAbsArg* arg ;
      while((arg=(RooAbsArg*)iter->Next())) {
	if (arg!=_owner) {
	  add(*arg,kTRUE) ;
	}
      }
      delete iter ;
    } else {
      return kTRUE ;	
    }
  }
  _iter->Reset() ;
  RooAbsArg* arg ;
  Bool_t error(kFALSE) ;
  while ((arg=(RooAbsArg*)_iter->Next())) {
    
    RooAbsArg* newArg= arg->findNewServer(newServerList, nameChange);
    if (newArg && newArg!=_owner) error |= !RooArgList::replace(*arg,*newArg) ;
  }
  return !error ;
}



//_____________________________________________________________________________
void RooListProxy::print(ostream& os, Bool_t addContents) const 
{ 
  // Print the name of the proxy, and if requested a summary of
  // the contained elements as well

  if (!addContents) {
    os << name() << "=" ; printStream(os,kValue,kInline) ; 
  } else {
    os << name() << "=(" ;
    TIterator* iter = createIterator() ;
    RooAbsArg* arg ;
    Bool_t first2(kTRUE) ;
    while ((arg=(RooAbsArg*)iter->Next())) {
      if (first2) {
	first2 = kFALSE ;
      } else {
	os << "," ;
      }
      arg->printStream(os,kValue|kName,kInline) ;
    }
    os << ")" ;
    delete iter ;
  }
}
 RooListProxy.cxx:1
 RooListProxy.cxx:2
 RooListProxy.cxx:3
 RooListProxy.cxx:4
 RooListProxy.cxx:5
 RooListProxy.cxx:6
 RooListProxy.cxx:7
 RooListProxy.cxx:8
 RooListProxy.cxx:9
 RooListProxy.cxx:10
 RooListProxy.cxx:11
 RooListProxy.cxx:12
 RooListProxy.cxx:13
 RooListProxy.cxx:14
 RooListProxy.cxx:15
 RooListProxy.cxx:16
 RooListProxy.cxx:17
 RooListProxy.cxx:18
 RooListProxy.cxx:19
 RooListProxy.cxx:20
 RooListProxy.cxx:21
 RooListProxy.cxx:22
 RooListProxy.cxx:23
 RooListProxy.cxx:24
 RooListProxy.cxx:25
 RooListProxy.cxx:26
 RooListProxy.cxx:27
 RooListProxy.cxx:28
 RooListProxy.cxx:29
 RooListProxy.cxx:30
 RooListProxy.cxx:31
 RooListProxy.cxx:32
 RooListProxy.cxx:33
 RooListProxy.cxx:34
 RooListProxy.cxx:35
 RooListProxy.cxx:36
 RooListProxy.cxx:37
 RooListProxy.cxx:38
 RooListProxy.cxx:39
 RooListProxy.cxx:40
 RooListProxy.cxx:41
 RooListProxy.cxx:42
 RooListProxy.cxx:43
 RooListProxy.cxx:44
 RooListProxy.cxx:45
 RooListProxy.cxx:46
 RooListProxy.cxx:47
 RooListProxy.cxx:48
 RooListProxy.cxx:49
 RooListProxy.cxx:50
 RooListProxy.cxx:51
 RooListProxy.cxx:52
 RooListProxy.cxx:53
 RooListProxy.cxx:54
 RooListProxy.cxx:55
 RooListProxy.cxx:56
 RooListProxy.cxx:57
 RooListProxy.cxx:58
 RooListProxy.cxx:59
 RooListProxy.cxx:60
 RooListProxy.cxx:61
 RooListProxy.cxx:62
 RooListProxy.cxx:63
 RooListProxy.cxx:64
 RooListProxy.cxx:65
 RooListProxy.cxx:66
 RooListProxy.cxx:67
 RooListProxy.cxx:68
 RooListProxy.cxx:69
 RooListProxy.cxx:70
 RooListProxy.cxx:71
 RooListProxy.cxx:72
 RooListProxy.cxx:73
 RooListProxy.cxx:74
 RooListProxy.cxx:75
 RooListProxy.cxx:76
 RooListProxy.cxx:77
 RooListProxy.cxx:78
 RooListProxy.cxx:79
 RooListProxy.cxx:80
 RooListProxy.cxx:81
 RooListProxy.cxx:82
 RooListProxy.cxx:83
 RooListProxy.cxx:84
 RooListProxy.cxx:85
 RooListProxy.cxx:86
 RooListProxy.cxx:87
 RooListProxy.cxx:88
 RooListProxy.cxx:89
 RooListProxy.cxx:90
 RooListProxy.cxx:91
 RooListProxy.cxx:92
 RooListProxy.cxx:93
 RooListProxy.cxx:94
 RooListProxy.cxx:95
 RooListProxy.cxx:96
 RooListProxy.cxx:97
 RooListProxy.cxx:98
 RooListProxy.cxx:99
 RooListProxy.cxx:100
 RooListProxy.cxx:101
 RooListProxy.cxx:102
 RooListProxy.cxx:103
 RooListProxy.cxx:104
 RooListProxy.cxx:105
 RooListProxy.cxx:106
 RooListProxy.cxx:107
 RooListProxy.cxx:108
 RooListProxy.cxx:109
 RooListProxy.cxx:110
 RooListProxy.cxx:111
 RooListProxy.cxx:112
 RooListProxy.cxx:113
 RooListProxy.cxx:114
 RooListProxy.cxx:115
 RooListProxy.cxx:116
 RooListProxy.cxx:117
 RooListProxy.cxx:118
 RooListProxy.cxx:119
 RooListProxy.cxx:120
 RooListProxy.cxx:121
 RooListProxy.cxx:122
 RooListProxy.cxx:123
 RooListProxy.cxx:124
 RooListProxy.cxx:125
 RooListProxy.cxx:126
 RooListProxy.cxx:127
 RooListProxy.cxx:128
 RooListProxy.cxx:129
 RooListProxy.cxx:130
 RooListProxy.cxx:131
 RooListProxy.cxx:132
 RooListProxy.cxx:133
 RooListProxy.cxx:134
 RooListProxy.cxx:135
 RooListProxy.cxx:136
 RooListProxy.cxx:137
 RooListProxy.cxx:138
 RooListProxy.cxx:139
 RooListProxy.cxx:140
 RooListProxy.cxx:141
 RooListProxy.cxx:142
 RooListProxy.cxx:143
 RooListProxy.cxx:144
 RooListProxy.cxx:145
 RooListProxy.cxx:146
 RooListProxy.cxx:147
 RooListProxy.cxx:148
 RooListProxy.cxx:149
 RooListProxy.cxx:150
 RooListProxy.cxx:151
 RooListProxy.cxx:152
 RooListProxy.cxx:153
 RooListProxy.cxx:154
 RooListProxy.cxx:155
 RooListProxy.cxx:156
 RooListProxy.cxx:157
 RooListProxy.cxx:158
 RooListProxy.cxx:159
 RooListProxy.cxx:160
 RooListProxy.cxx:161
 RooListProxy.cxx:162
 RooListProxy.cxx:163
 RooListProxy.cxx:164
 RooListProxy.cxx:165
 RooListProxy.cxx:166
 RooListProxy.cxx:167
 RooListProxy.cxx:168
 RooListProxy.cxx:169
 RooListProxy.cxx:170
 RooListProxy.cxx:171
 RooListProxy.cxx:172
 RooListProxy.cxx:173
 RooListProxy.cxx:174
 RooListProxy.cxx:175
 RooListProxy.cxx:176
 RooListProxy.cxx:177
 RooListProxy.cxx:178
 RooListProxy.cxx:179
 RooListProxy.cxx:180
 RooListProxy.cxx:181
 RooListProxy.cxx:182
 RooListProxy.cxx:183
 RooListProxy.cxx:184
 RooListProxy.cxx:185
 RooListProxy.cxx:186
 RooListProxy.cxx:187
 RooListProxy.cxx:188
 RooListProxy.cxx:189
 RooListProxy.cxx:190
 RooListProxy.cxx:191
 RooListProxy.cxx:192
 RooListProxy.cxx:193
 RooListProxy.cxx:194
 RooListProxy.cxx:195
 RooListProxy.cxx:196
 RooListProxy.cxx:197
 RooListProxy.cxx:198
 RooListProxy.cxx:199
 RooListProxy.cxx:200
 RooListProxy.cxx:201
 RooListProxy.cxx:202
 RooListProxy.cxx:203
 RooListProxy.cxx:204
 RooListProxy.cxx:205
 RooListProxy.cxx:206
 RooListProxy.cxx:207
 RooListProxy.cxx:208
 RooListProxy.cxx:209
 RooListProxy.cxx:210
 RooListProxy.cxx:211
 RooListProxy.cxx:212
 RooListProxy.cxx:213
 RooListProxy.cxx:214
 RooListProxy.cxx:215
 RooListProxy.cxx:216
 RooListProxy.cxx:217
 RooListProxy.cxx:218
 RooListProxy.cxx:219
 RooListProxy.cxx:220
 RooListProxy.cxx:221
 RooListProxy.cxx:222
 RooListProxy.cxx:223
 RooListProxy.cxx:224
 RooListProxy.cxx:225
 RooListProxy.cxx:226
 RooListProxy.cxx:227
 RooListProxy.cxx:228
 RooListProxy.cxx:229
 RooListProxy.cxx:230
 RooListProxy.cxx:231
 RooListProxy.cxx:232
 RooListProxy.cxx:233
 RooListProxy.cxx:234
 RooListProxy.cxx:235
 RooListProxy.cxx:236
 RooListProxy.cxx:237
 RooListProxy.cxx:238
 RooListProxy.cxx:239
 RooListProxy.cxx:240
 RooListProxy.cxx:241
 RooListProxy.cxx:242
 RooListProxy.cxx:243
 RooListProxy.cxx:244
 RooListProxy.cxx:245