////////////////////////////////////////////////////////
//  
//
//                    Author: I. Froehlich
//                    Written: 6.10.2007
//
////////////////////////////////////////////////////////


#include "PCommandList.h"
#include "PUtils.h"
#include <iostream>
#include "TROOT.h"


using namespace std;

PCommandList::PCommandList() {
    fNextP = NULL;
    fLevel = 0;
}

PCommandList::PCommandList(TString name) : TObjString(name) {
    fNextP = NULL;
    fLevel = 0;
};

PCommandList::PCommandList(TObject *obj, TString name, TString cmd) : TObjString(name) {
    fCmd.SetString(cmd);
    fNextP = NULL;
    fLevel = 0;
    if (obj) {
	Info("PCommandList", "Added object %s", obj->GetName());
	fTool.SetString(obj->GetName());
    }
};

PCommandList::PCommandList(TString name, TString cmd) : TObjString(name) {
    fCmd.SetString(cmd);
    fNextP = NULL;
    fLevel = 0;
};

PCommandList::~PCommandList() {
};

Bool_t PCommandList::AddCommand(const char *cmd, const char *basename, int level) {
    return AddCommand(NULL, cmd, basename, level);
};

Bool_t PCommandList::AddCommand(TObject *obj, const char *cmd, const char *basename, int level) {
    //if (basename && !fNextP) cout << "PCommandList::AddCommand " << basename << ":" << level << endl;
    //else if (!fNextP) cout << "PCommandList::AddCommand " << GetName() << ":" << level << endl;
    if (fNextP) {
	if (basename && level) return fNextP->AddCommand(obj,cmd,basename,level+1);
	else return fNextP->AddCommand(obj,cmd,GetName(),1);
    } else {
	if (basename && level) {
	    TString tmp(basename);
	    tmp += "_";
	    tmp += (level+1);
	    fNextP = new PCommandList(obj, tmp, cmd);    
	    fNext.SetString(PUtils::NewString(tmp));
	    return kTRUE;
	} else {
	    TString tmp(GetName());
	    tmp += "_1";
	    fNextP = new PCommandList(obj, tmp, cmd);  
	    fNext.SetString(PUtils::NewString(tmp));
	    return kTRUE;
	}
    }
    return kFALSE;
};

Bool_t PCommandList::GetCommand(char **cmd, int level, TObject **obj) {
    if (level == 0) {
	(*cmd) = PUtils::NewString(fCmd.GetString().Data());
	if (obj) {
	    if (fTool.GetString().Data() && strlen(fTool.GetString().Data())) {
		//Try to recover tool object
		*obj = gROOT->FindObject(fTool.GetString().Data());
		if (!(*obj)) {
		    Error("GetCommand", "Object %s could not be recovered", fTool.GetString().Data());
		    return kFALSE;
		}
		return kTRUE;
	    } else (*obj)=NULL;
	}
	return kTRUE;
    }

    if (fNextP) return fNextP->GetCommand(cmd, level-1, obj);
 
    if (fNext.GetString().Data() && strlen(fNext.GetString().Data())) {
	fNextP = (PCommandList*)gROOT->FindObject(fNext.GetString().Data());
	if (!fNextP) return kFALSE;
    }

    if (fNextP) return fNextP->GetCommand(cmd, level-1, obj);
    return kFALSE;
}

void PCommandList::Print(const Option_t *) const {
    
    if (fTool.GetString().Data() && strlen(fTool.GetString().Data())) {
	cout<< "<" <<  fTool.GetString().Data() << "> " << fCmd.GetString() << endl;
    } else {
	cout << "> " << fCmd.GetString() << endl;
    }
    //print following:
    if (fNext.GetString().Data() && strlen(fNext.GetString().Data())) {
	PCommandList *fNextP = (PCommandList*)gROOT->FindObject(fNext.GetString().Data());
	if (!fNextP) {
	    Error("Print", "Object %s not found", fNext.GetString().Data());
	    return;
	}
	fNextP->Print();
    }
};


Int_t PCommandList::Write(const char *name, Int_t option, Int_t bufsize) const {
    
    if (fNextP) 
	fNextP->Write(name, option, bufsize);
    return TObject::Write(name, option, bufsize);
}


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