/*****************************************************************************
 * 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
// RooMultiCategory consolidates several RooAbsCategory objects into
// a single category. The states of the multi-category consist of all the permutations
// of the input categories. 
// <p>
// RooMultiCategory state are automatically defined and updated whenever an input
// category modifies its list of states
// END_HTML
//

#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include <stdlib.h>
#include <stdio.h>
#include "TString.h"
#include "RooMultiCategory.h"
#include "RooStreamParser.h"
#include "RooArgSet.h"
#include "RooMultiCatIter.h"
#include "RooAbsCategory.h"
#include "RooMsgService.h"

using namespace std;

ClassImp(RooMultiCategory)
;


//_____________________________________________________________________________
RooMultiCategory::RooMultiCategory(const char *name, const char *title, const RooArgSet& inputCatList2) :
  RooAbsCategory(name, title), _catSet("input","Input category set",this,kTRUE,kTRUE)
{  
  // Construct a product of the given set of input RooAbsCategories in 'inInputCatList'
  // The state names of this product category are {S1;S2,S3,...Sn} where Si are the state names
  // of the input categories. A RooMultiCategory is not an lvalue

  // Copy category list
  TIterator* iter = inputCatList2.createIterator() ;
  RooAbsArg* arg ;
  while ((arg=(RooAbsArg*)iter->Next())) {
    if (!dynamic_cast<RooAbsCategory*>(arg)) {
      coutE(InputArguments) << "RooMultiCategory::RooMultiCategory(" << GetName() << "): input argument " << arg->GetName() 
			    << " is not a RooAbsCategory" << endl ;
    }
    _catSet.add(*arg) ;
  }
  delete iter ;
  
  updateIndexList() ;
}



//_____________________________________________________________________________
RooMultiCategory::RooMultiCategory(const RooMultiCategory& other, const char *name) :
  RooAbsCategory(other,name), _catSet("input",this,other._catSet)
{
  // Copy constructor

  updateIndexList() ;
}



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

}



//_____________________________________________________________________________
void RooMultiCategory::updateIndexList()
{
  // Update the list of super-category states 

  // WVE broken if used with derived categories!
  clearTypes() ;

  RooMultiCatIter iter(_catSet) ;
  TObjString* obj ;
  while((obj=(TObjString*)iter.Next())) {
    // Register composite label
    defineType(obj->String()) ;
  }

  // Renumbering will invalidate cache
  setValueDirty() ;
}



//_____________________________________________________________________________
TString RooMultiCategory::currentLabel() const
{
  // Return the name of the current state, 
  // constructed from the state names of the input categories

  TIterator* lIter = _catSet.createIterator() ;

  // Construct composite label name
  TString label ;
  RooAbsCategory* cat ;
  Bool_t first(kTRUE) ;
  while((cat=(RooAbsCategory*) lIter->Next())) {
    label.Append(first?"{":";") ;
    label.Append(cat->getLabel()) ;      
    first=kFALSE ;
  }
  label.Append("}") ;  
  delete lIter ;

  return label ;
}



//_____________________________________________________________________________
RooCatType RooMultiCategory::evaluate() const
{
  // Calculate the current value 

  if (isShapeDirty()) const_cast<RooMultiCategory*>(this)->updateIndexList() ;

  // current label is can be looked up by definition 
  // coverity[NULL_RETURNS] 
  return *lookupType(currentLabel()) ;
}



//_____________________________________________________________________________
void RooMultiCategory::printMultiline(ostream& os, Int_t content, Bool_t verbose, TString indent) const
{
  // Print the state of this object to the specified output stream.

  RooAbsCategory::printMultiline(os,content,verbose,indent) ;
  
  if (verbose) {     
    os << indent << "--- RooMultiCategory ---" << endl;
    os << indent << "  Input category list:" << endl ;
    TString moreIndent(indent) ;
    moreIndent.Append("   ") ;
    _catSet.printStream(os,kName|kValue,kStandard,moreIndent.Data()) ;
  }
}



//_____________________________________________________________________________
Bool_t RooMultiCategory::readFromStream(istream& /*is*/, Bool_t /*compact*/, Bool_t /*verbose*/) 
{
  // Read object contents from given stream
  return kTRUE ;
}



//_____________________________________________________________________________
void RooMultiCategory::writeToStream(ostream& os, Bool_t compact) const
{
  // Write object contents to given stream
  RooAbsCategory::writeToStream(os,compact) ;
}
 RooMultiCategory.cxx:1
 RooMultiCategory.cxx:2
 RooMultiCategory.cxx:3
 RooMultiCategory.cxx:4
 RooMultiCategory.cxx:5
 RooMultiCategory.cxx:6
 RooMultiCategory.cxx:7
 RooMultiCategory.cxx:8
 RooMultiCategory.cxx:9
 RooMultiCategory.cxx:10
 RooMultiCategory.cxx:11
 RooMultiCategory.cxx:12
 RooMultiCategory.cxx:13
 RooMultiCategory.cxx:14
 RooMultiCategory.cxx:15
 RooMultiCategory.cxx:16
 RooMultiCategory.cxx:17
 RooMultiCategory.cxx:18
 RooMultiCategory.cxx:19
 RooMultiCategory.cxx:20
 RooMultiCategory.cxx:21
 RooMultiCategory.cxx:22
 RooMultiCategory.cxx:23
 RooMultiCategory.cxx:24
 RooMultiCategory.cxx:25
 RooMultiCategory.cxx:26
 RooMultiCategory.cxx:27
 RooMultiCategory.cxx:28
 RooMultiCategory.cxx:29
 RooMultiCategory.cxx:30
 RooMultiCategory.cxx:31
 RooMultiCategory.cxx:32
 RooMultiCategory.cxx:33
 RooMultiCategory.cxx:34
 RooMultiCategory.cxx:35
 RooMultiCategory.cxx:36
 RooMultiCategory.cxx:37
 RooMultiCategory.cxx:38
 RooMultiCategory.cxx:39
 RooMultiCategory.cxx:40
 RooMultiCategory.cxx:41
 RooMultiCategory.cxx:42
 RooMultiCategory.cxx:43
 RooMultiCategory.cxx:44
 RooMultiCategory.cxx:45
 RooMultiCategory.cxx:46
 RooMultiCategory.cxx:47
 RooMultiCategory.cxx:48
 RooMultiCategory.cxx:49
 RooMultiCategory.cxx:50
 RooMultiCategory.cxx:51
 RooMultiCategory.cxx:52
 RooMultiCategory.cxx:53
 RooMultiCategory.cxx:54
 RooMultiCategory.cxx:55
 RooMultiCategory.cxx:56
 RooMultiCategory.cxx:57
 RooMultiCategory.cxx:58
 RooMultiCategory.cxx:59
 RooMultiCategory.cxx:60
 RooMultiCategory.cxx:61
 RooMultiCategory.cxx:62
 RooMultiCategory.cxx:63
 RooMultiCategory.cxx:64
 RooMultiCategory.cxx:65
 RooMultiCategory.cxx:66
 RooMultiCategory.cxx:67
 RooMultiCategory.cxx:68
 RooMultiCategory.cxx:69
 RooMultiCategory.cxx:70
 RooMultiCategory.cxx:71
 RooMultiCategory.cxx:72
 RooMultiCategory.cxx:73
 RooMultiCategory.cxx:74
 RooMultiCategory.cxx:75
 RooMultiCategory.cxx:76
 RooMultiCategory.cxx:77
 RooMultiCategory.cxx:78
 RooMultiCategory.cxx:79
 RooMultiCategory.cxx:80
 RooMultiCategory.cxx:81
 RooMultiCategory.cxx:82
 RooMultiCategory.cxx:83
 RooMultiCategory.cxx:84
 RooMultiCategory.cxx:85
 RooMultiCategory.cxx:86
 RooMultiCategory.cxx:87
 RooMultiCategory.cxx:88
 RooMultiCategory.cxx:89
 RooMultiCategory.cxx:90
 RooMultiCategory.cxx:91
 RooMultiCategory.cxx:92
 RooMultiCategory.cxx:93
 RooMultiCategory.cxx:94
 RooMultiCategory.cxx:95
 RooMultiCategory.cxx:96
 RooMultiCategory.cxx:97
 RooMultiCategory.cxx:98
 RooMultiCategory.cxx:99
 RooMultiCategory.cxx:100
 RooMultiCategory.cxx:101
 RooMultiCategory.cxx:102
 RooMultiCategory.cxx:103
 RooMultiCategory.cxx:104
 RooMultiCategory.cxx:105
 RooMultiCategory.cxx:106
 RooMultiCategory.cxx:107
 RooMultiCategory.cxx:108
 RooMultiCategory.cxx:109
 RooMultiCategory.cxx:110
 RooMultiCategory.cxx:111
 RooMultiCategory.cxx:112
 RooMultiCategory.cxx:113
 RooMultiCategory.cxx:114
 RooMultiCategory.cxx:115
 RooMultiCategory.cxx:116
 RooMultiCategory.cxx:117
 RooMultiCategory.cxx:118
 RooMultiCategory.cxx:119
 RooMultiCategory.cxx:120
 RooMultiCategory.cxx:121
 RooMultiCategory.cxx:122
 RooMultiCategory.cxx:123
 RooMultiCategory.cxx:124
 RooMultiCategory.cxx:125
 RooMultiCategory.cxx:126
 RooMultiCategory.cxx:127
 RooMultiCategory.cxx:128
 RooMultiCategory.cxx:129
 RooMultiCategory.cxx:130
 RooMultiCategory.cxx:131
 RooMultiCategory.cxx:132
 RooMultiCategory.cxx:133
 RooMultiCategory.cxx:134
 RooMultiCategory.cxx:135
 RooMultiCategory.cxx:136
 RooMultiCategory.cxx:137
 RooMultiCategory.cxx:138
 RooMultiCategory.cxx:139
 RooMultiCategory.cxx:140
 RooMultiCategory.cxx:141
 RooMultiCategory.cxx:142
 RooMultiCategory.cxx:143
 RooMultiCategory.cxx:144
 RooMultiCategory.cxx:145
 RooMultiCategory.cxx:146
 RooMultiCategory.cxx:147
 RooMultiCategory.cxx:148
 RooMultiCategory.cxx:149
 RooMultiCategory.cxx:150
 RooMultiCategory.cxx:151
 RooMultiCategory.cxx:152
 RooMultiCategory.cxx:153
 RooMultiCategory.cxx:154
 RooMultiCategory.cxx:155
 RooMultiCategory.cxx:156
 RooMultiCategory.cxx:157
 RooMultiCategory.cxx:158
 RooMultiCategory.cxx:159
 RooMultiCategory.cxx:160
 RooMultiCategory.cxx:161
 RooMultiCategory.cxx:162
 RooMultiCategory.cxx:163
 RooMultiCategory.cxx:164
 RooMultiCategory.cxx:165
 RooMultiCategory.cxx:166
 RooMultiCategory.cxx:167
 RooMultiCategory.cxx:168
 RooMultiCategory.cxx:169
 RooMultiCategory.cxx:170
 RooMultiCategory.cxx:171
 RooMultiCategory.cxx:172
 RooMultiCategory.cxx:173
 RooMultiCategory.cxx:174
 RooMultiCategory.cxx:175
 RooMultiCategory.cxx:176
 RooMultiCategory.cxx:177
 RooMultiCategory.cxx:178
 RooMultiCategory.cxx:179
 RooMultiCategory.cxx:180
 RooMultiCategory.cxx:181
 RooMultiCategory.cxx:182
 RooMultiCategory.cxx:183
 RooMultiCategory.cxx:184
 RooMultiCategory.cxx:185
 RooMultiCategory.cxx:186