/*****************************************************************************
 * 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
// RooCategory represents a fundamental (non-derived) discrete value object. The class
// has a public interface to define the possible value states.
// END_HTML
//


#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include <stdlib.h>
#include <string.h>
#include "TTree.h"
#include "TString.h"
#include "TH1.h"
#include "RooCategory.h"
#include "RooArgSet.h"
#include "RooStreamParser.h"
#include "RooMsgService.h"
#include "RooTrace.h"

using namespace std;

ClassImp(RooCategory) 
;

RooSharedPropertiesList RooCategory::_sharedPropList ;
RooCategorySharedProperties RooCategory::_nullProp("00000000-0000-0000-0000-000000000000") ;

//_____________________________________________________________________________
RooCategory::RooCategory() : _sharedProp(0)
{
  TRACE_CREATE 
}



//_____________________________________________________________________________
RooCategory::RooCategory(const char *name, const char *title) : 
  RooAbsCategoryLValue(name,title)
{
  // Constructor. Types must be defined using defineType() before variable can be used

  _sharedProp = (RooCategorySharedProperties*) _sharedPropList.registerProperties(new RooCategorySharedProperties()) ;

  setValueDirty() ;  
  setShapeDirty() ;  
  TRACE_CREATE 
}



//_____________________________________________________________________________
RooCategory::RooCategory(const RooCategory& other, const char* name) :
  RooAbsCategoryLValue(other, name)
{
  // Copy constructor
  _sharedProp =  (RooCategorySharedProperties*) _sharedPropList.registerProperties(other._sharedProp) ;
  TRACE_CREATE   
}



//_____________________________________________________________________________
RooCategory::~RooCategory()
{
  // Destructor
  _sharedPropList.unregisterProperties(_sharedProp) ;
  TRACE_DESTROY
}




//_____________________________________________________________________________
Bool_t RooCategory::setIndex(Int_t index, Bool_t printError) 
{
  // Set value by specifying the index code of the desired state.
  // If printError is set, a message will be printed if
  // the specified index does not represent a valid state.

  const RooCatType* type = lookupType(index,printError) ;
  if (!type) return kTRUE ;
  _value = *type ;
  setValueDirty() ;
  return kFALSE ;
}



//_____________________________________________________________________________
Bool_t RooCategory::setLabel(const char* label, Bool_t printError) 
{
  // Set value by specifying the name of the desired state
  // If printError is set, a message will be printed if
  // the specified label does not represent a valid state.

  const RooCatType* type = lookupType(label,printError) ;
  if (!type) return kTRUE ;
  _value = *type ;
  setValueDirty() ;
  return kFALSE ;
}



//_____________________________________________________________________________
Bool_t RooCategory::defineType(const char* label) 
{ 
  // Define a state with given name, the lowest available
  // positive integer is assigned as index. Category
  // state labels may not contain semicolons.
  // Error status is return if state with given name
  // is already defined

  if (TString(label).Contains(";")) {
  coutE(InputArguments) << "RooCategory::defineType(" << GetName() 
			<< "): semicolons not allowed in label name" << endl ;
  return kTRUE ;
  }

  return RooAbsCategory::defineType(label)?kFALSE:kTRUE ; 
}


//_____________________________________________________________________________
Bool_t RooCategory::defineType(const char* label, Int_t index) 
{
  // Define a state with given name and index. Category
  // state labels may not contain semicolons
  // Error status is return if state with given name
  // or index is already defined

  if (TString(label).Contains(";")) {
  coutE(InputArguments) << "RooCategory::defineType(" << GetName() 
			<< "): semicolons not allowed in label name" << endl ;
  return kTRUE ;
  }

  return RooAbsCategory::defineType(label,index)?kFALSE:kTRUE ; 
}


//_____________________________________________________________________________
Bool_t RooCategory::readFromStream(istream& is, Bool_t /*compact*/, Bool_t verbose) 
{
  // Read object contents from given stream

  // Read single token
  RooStreamParser parser(is) ;
  TString token = parser.readToken() ;

  return setLabel(token,verbose) ;
}



//_____________________________________________________________________________
void RooCategory::writeToStream(ostream& os, Bool_t compact) const
{
  // compact only at the moment
  if (compact) {
    os << getIndex() ;
  } else {
    os << getLabel() ;
  }
}


//_____________________________________________________________________________
void RooCategory::clearRange(const char* name, Bool_t silent)
{
  // Check that both input arguments are not null pointers
  if (!name) {
    coutE(InputArguments) << "RooCategory::clearRange(" << GetName() << ") ERROR: must specificy valid range name" << endl ;
    return ;
  }
  
  // Find the list that represents this range
  TList* rangeNameList = static_cast<TList*>(_sharedProp->_altRanges.FindObject(name)) ;

  // If it exists, clear it 
  if (rangeNameList) {
    rangeNameList->Clear() ;
  } else if (!silent) {
    coutE(InputArguments) << "RooCategory::clearRange(" << GetName() << ") ERROR: range '" << name << "' does not exist" << endl ;
  } 
}


//_____________________________________________________________________________
void RooCategory::setRange(const char* name, const char* stateNameList) 
{
  clearRange(name,kTRUE) ;
  addToRange(name,stateNameList) ;
}



//_____________________________________________________________________________
void RooCategory::addToRange(const char* name, const char* stateNameList) 
{
  // Check that both input arguments are not null pointers
  if (!name || !stateNameList) {
    coutE(InputArguments) << "RooCategory::setRange(" << GetName() << ") ERROR: must specificy valid name and state name list" << endl ;
    return ;
  }
  
  // Find the list that represents this range
  TList* rangeNameList = static_cast<TList*>(_sharedProp->_altRanges.FindObject(name)) ;

  // If it does not exist, create it on the fly
  if (!rangeNameList) {
    coutI(Contents) << "RooCategory::setRange(" << GetName() 
		    << ") new range named '" << name << "' created with state list " << stateNameList << endl ;

    rangeNameList = new TList ;
    rangeNameList->SetOwner(kTRUE) ;
    rangeNameList->SetName(name) ;
    _sharedProp->_altRanges.Add(rangeNameList) ;    
  }

  // Parse list of state names, verify that each is valid and add them to the list
  const size_t bufSize = strlen(stateNameList)+1;
  char* buf = new char[bufSize] ;
  strlcpy(buf,stateNameList,bufSize) ;
  char* token = strtok(buf,",") ;
  while(token) {
    const RooCatType* state = lookupType(token,kFALSE) ;
    if (state && !rangeNameList->FindObject(token)) {
      rangeNameList->Add(new RooCatType(*state)) ;	
    } else {
      coutW(InputArguments) << "RooCategory::setRange(" << GetName() << ") WARNING: Ignoring invalid state name '" 
			    << token << "' in state name list" << endl ;
    }
    token = strtok(0,",") ;
  }

  delete[] buf ;
}



//_____________________________________________________________________________
Bool_t RooCategory::isStateInRange(const char* rangeName, const char* stateName) const
{
  // If no range is specified [ i.e. the default range ] all category states are in range
  if (!rangeName) {
    return kTRUE ;
  }

  // Check that both input arguments are not null pointers
  if (!stateName) {
    coutE(InputArguments) << "RooCategory::isStateInRange(" << GetName() << ") ERROR: must specificy valid state name" << endl ;
    return kFALSE ;
  }

  
  // Find the list that represents this range
  TList* rangeNameList = static_cast<TList*>(_sharedProp->_altRanges.FindObject(rangeName)) ;

  // If the range doesn't exist create range with all valid states included
  if (rangeNameList) {
    return rangeNameList->FindObject(stateName) ? kTRUE : kFALSE ;  
  }

  // Range does not exists -- create it on the fly with full set of states (analoguous to RooRealVar)
  return kTRUE ;

}


//______________________________________________________________________________
void RooCategory::Streamer(TBuffer &R__b)
{
  UInt_t R__s, R__c;
  if (R__b.IsReading()) {
    
    Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }    
    RooAbsCategoryLValue::Streamer(R__b);
    if (R__v==1) {
      // Implement V1 streamer here
      R__b >> _sharedProp;      
    } else { 
      RooCategorySharedProperties* tmpSharedProp = new RooCategorySharedProperties() ;
      tmpSharedProp->Streamer(R__b) ;
      if (!(_nullProp==*tmpSharedProp)) {
	_sharedProp = (RooCategorySharedProperties*) _sharedPropList.registerProperties(tmpSharedProp,kFALSE) ;
      } else {
	delete tmpSharedProp ;
	_sharedProp = 0 ;
      }
    }

    R__b.CheckByteCount(R__s, R__c, RooCategory::IsA());
    
  } else {
    
    R__c = R__b.WriteVersion(RooCategory::IsA(), kTRUE);
    RooAbsCategoryLValue::Streamer(R__b);
    if (_sharedProp) {
      _sharedProp->Streamer(R__b) ;
    } else {
      _nullProp.Streamer(R__b) ;
    }
    R__b.SetByteCount(R__c, kTRUE);      
    
  }
}


 RooCategory.cxx:1
 RooCategory.cxx:2
 RooCategory.cxx:3
 RooCategory.cxx:4
 RooCategory.cxx:5
 RooCategory.cxx:6
 RooCategory.cxx:7
 RooCategory.cxx:8
 RooCategory.cxx:9
 RooCategory.cxx:10
 RooCategory.cxx:11
 RooCategory.cxx:12
 RooCategory.cxx:13
 RooCategory.cxx:14
 RooCategory.cxx:15
 RooCategory.cxx:16
 RooCategory.cxx:17
 RooCategory.cxx:18
 RooCategory.cxx:19
 RooCategory.cxx:20
 RooCategory.cxx:21
 RooCategory.cxx:22
 RooCategory.cxx:23
 RooCategory.cxx:24
 RooCategory.cxx:25
 RooCategory.cxx:26
 RooCategory.cxx:27
 RooCategory.cxx:28
 RooCategory.cxx:29
 RooCategory.cxx:30
 RooCategory.cxx:31
 RooCategory.cxx:32
 RooCategory.cxx:33
 RooCategory.cxx:34
 RooCategory.cxx:35
 RooCategory.cxx:36
 RooCategory.cxx:37
 RooCategory.cxx:38
 RooCategory.cxx:39
 RooCategory.cxx:40
 RooCategory.cxx:41
 RooCategory.cxx:42
 RooCategory.cxx:43
 RooCategory.cxx:44
 RooCategory.cxx:45
 RooCategory.cxx:46
 RooCategory.cxx:47
 RooCategory.cxx:48
 RooCategory.cxx:49
 RooCategory.cxx:50
 RooCategory.cxx:51
 RooCategory.cxx:52
 RooCategory.cxx:53
 RooCategory.cxx:54
 RooCategory.cxx:55
 RooCategory.cxx:56
 RooCategory.cxx:57
 RooCategory.cxx:58
 RooCategory.cxx:59
 RooCategory.cxx:60
 RooCategory.cxx:61
 RooCategory.cxx:62
 RooCategory.cxx:63
 RooCategory.cxx:64
 RooCategory.cxx:65
 RooCategory.cxx:66
 RooCategory.cxx:67
 RooCategory.cxx:68
 RooCategory.cxx:69
 RooCategory.cxx:70
 RooCategory.cxx:71
 RooCategory.cxx:72
 RooCategory.cxx:73
 RooCategory.cxx:74
 RooCategory.cxx:75
 RooCategory.cxx:76
 RooCategory.cxx:77
 RooCategory.cxx:78
 RooCategory.cxx:79
 RooCategory.cxx:80
 RooCategory.cxx:81
 RooCategory.cxx:82
 RooCategory.cxx:83
 RooCategory.cxx:84
 RooCategory.cxx:85
 RooCategory.cxx:86
 RooCategory.cxx:87
 RooCategory.cxx:88
 RooCategory.cxx:89
 RooCategory.cxx:90
 RooCategory.cxx:91
 RooCategory.cxx:92
 RooCategory.cxx:93
 RooCategory.cxx:94
 RooCategory.cxx:95
 RooCategory.cxx:96
 RooCategory.cxx:97
 RooCategory.cxx:98
 RooCategory.cxx:99
 RooCategory.cxx:100
 RooCategory.cxx:101
 RooCategory.cxx:102
 RooCategory.cxx:103
 RooCategory.cxx:104
 RooCategory.cxx:105
 RooCategory.cxx:106
 RooCategory.cxx:107
 RooCategory.cxx:108
 RooCategory.cxx:109
 RooCategory.cxx:110
 RooCategory.cxx:111
 RooCategory.cxx:112
 RooCategory.cxx:113
 RooCategory.cxx:114
 RooCategory.cxx:115
 RooCategory.cxx:116
 RooCategory.cxx:117
 RooCategory.cxx:118
 RooCategory.cxx:119
 RooCategory.cxx:120
 RooCategory.cxx:121
 RooCategory.cxx:122
 RooCategory.cxx:123
 RooCategory.cxx:124
 RooCategory.cxx:125
 RooCategory.cxx:126
 RooCategory.cxx:127
 RooCategory.cxx:128
 RooCategory.cxx:129
 RooCategory.cxx:130
 RooCategory.cxx:131
 RooCategory.cxx:132
 RooCategory.cxx:133
 RooCategory.cxx:134
 RooCategory.cxx:135
 RooCategory.cxx:136
 RooCategory.cxx:137
 RooCategory.cxx:138
 RooCategory.cxx:139
 RooCategory.cxx:140
 RooCategory.cxx:141
 RooCategory.cxx:142
 RooCategory.cxx:143
 RooCategory.cxx:144
 RooCategory.cxx:145
 RooCategory.cxx:146
 RooCategory.cxx:147
 RooCategory.cxx:148
 RooCategory.cxx:149
 RooCategory.cxx:150
 RooCategory.cxx:151
 RooCategory.cxx:152
 RooCategory.cxx:153
 RooCategory.cxx:154
 RooCategory.cxx:155
 RooCategory.cxx:156
 RooCategory.cxx:157
 RooCategory.cxx:158
 RooCategory.cxx:159
 RooCategory.cxx:160
 RooCategory.cxx:161
 RooCategory.cxx:162
 RooCategory.cxx:163
 RooCategory.cxx:164
 RooCategory.cxx:165
 RooCategory.cxx:166
 RooCategory.cxx:167
 RooCategory.cxx:168
 RooCategory.cxx:169
 RooCategory.cxx:170
 RooCategory.cxx:171
 RooCategory.cxx:172
 RooCategory.cxx:173
 RooCategory.cxx:174
 RooCategory.cxx:175
 RooCategory.cxx:176
 RooCategory.cxx:177
 RooCategory.cxx:178
 RooCategory.cxx:179
 RooCategory.cxx:180
 RooCategory.cxx:181
 RooCategory.cxx:182
 RooCategory.cxx:183
 RooCategory.cxx:184
 RooCategory.cxx:185
 RooCategory.cxx:186
 RooCategory.cxx:187
 RooCategory.cxx:188
 RooCategory.cxx:189
 RooCategory.cxx:190
 RooCategory.cxx:191
 RooCategory.cxx:192
 RooCategory.cxx:193
 RooCategory.cxx:194
 RooCategory.cxx:195
 RooCategory.cxx:196
 RooCategory.cxx:197
 RooCategory.cxx:198
 RooCategory.cxx:199
 RooCategory.cxx:200
 RooCategory.cxx:201
 RooCategory.cxx:202
 RooCategory.cxx:203
 RooCategory.cxx:204
 RooCategory.cxx:205
 RooCategory.cxx:206
 RooCategory.cxx:207
 RooCategory.cxx:208
 RooCategory.cxx:209
 RooCategory.cxx:210
 RooCategory.cxx:211
 RooCategory.cxx:212
 RooCategory.cxx:213
 RooCategory.cxx:214
 RooCategory.cxx:215
 RooCategory.cxx:216
 RooCategory.cxx:217
 RooCategory.cxx:218
 RooCategory.cxx:219
 RooCategory.cxx:220
 RooCategory.cxx:221
 RooCategory.cxx:222
 RooCategory.cxx:223
 RooCategory.cxx:224
 RooCategory.cxx:225
 RooCategory.cxx:226
 RooCategory.cxx:227
 RooCategory.cxx:228
 RooCategory.cxx:229
 RooCategory.cxx:230
 RooCategory.cxx:231
 RooCategory.cxx:232
 RooCategory.cxx:233
 RooCategory.cxx:234
 RooCategory.cxx:235
 RooCategory.cxx:236
 RooCategory.cxx:237
 RooCategory.cxx:238
 RooCategory.cxx:239
 RooCategory.cxx:240
 RooCategory.cxx:241
 RooCategory.cxx:242
 RooCategory.cxx:243
 RooCategory.cxx:244
 RooCategory.cxx:245
 RooCategory.cxx:246
 RooCategory.cxx:247
 RooCategory.cxx:248
 RooCategory.cxx:249
 RooCategory.cxx:250
 RooCategory.cxx:251
 RooCategory.cxx:252
 RooCategory.cxx:253
 RooCategory.cxx:254
 RooCategory.cxx:255
 RooCategory.cxx:256
 RooCategory.cxx:257
 RooCategory.cxx:258
 RooCategory.cxx:259
 RooCategory.cxx:260
 RooCategory.cxx:261
 RooCategory.cxx:262
 RooCategory.cxx:263
 RooCategory.cxx:264
 RooCategory.cxx:265
 RooCategory.cxx:266
 RooCategory.cxx:267
 RooCategory.cxx:268
 RooCategory.cxx:269
 RooCategory.cxx:270
 RooCategory.cxx:271
 RooCategory.cxx:272
 RooCategory.cxx:273
 RooCategory.cxx:274
 RooCategory.cxx:275
 RooCategory.cxx:276
 RooCategory.cxx:277
 RooCategory.cxx:278
 RooCategory.cxx:279
 RooCategory.cxx:280
 RooCategory.cxx:281
 RooCategory.cxx:282
 RooCategory.cxx:283
 RooCategory.cxx:284
 RooCategory.cxx:285
 RooCategory.cxx:286
 RooCategory.cxx:287
 RooCategory.cxx:288
 RooCategory.cxx:289
 RooCategory.cxx:290
 RooCategory.cxx:291
 RooCategory.cxx:292
 RooCategory.cxx:293
 RooCategory.cxx:294
 RooCategory.cxx:295
 RooCategory.cxx:296
 RooCategory.cxx:297
 RooCategory.cxx:298
 RooCategory.cxx:299
 RooCategory.cxx:300
 RooCategory.cxx:301
 RooCategory.cxx:302
 RooCategory.cxx:303
 RooCategory.cxx:304
 RooCategory.cxx:305
 RooCategory.cxx:306
 RooCategory.cxx:307
 RooCategory.cxx:308
 RooCategory.cxx:309
 RooCategory.cxx:310
 RooCategory.cxx:311
 RooCategory.cxx:312
 RooCategory.cxx:313
 RooCategory.cxx:314
 RooCategory.cxx:315
 RooCategory.cxx:316
 RooCategory.cxx:317
 RooCategory.cxx:318
 RooCategory.cxx:319
 RooCategory.cxx:320
 RooCategory.cxx:321
 RooCategory.cxx:322
 RooCategory.cxx:323
 RooCategory.cxx:324
 RooCategory.cxx:325
 RooCategory.cxx:326
 RooCategory.cxx:327
 RooCategory.cxx:328
 RooCategory.cxx:329
 RooCategory.cxx:330