using namespace std;
#include <sstream>
#include <iostream>
#include "PDistributionManager.h"
#include "../Plugins.h"
#include "TFile.h"
PDistributionManager *gDM=0;          
PDistributionManager &fDistributionManager() {
    static PDistributionManager *ans = new PDistributionManager();
    return *ans;
}
PDistributionManager *makeDistributionManager() {
    return &fDistributionManager();
}
PDistributionManager::PDistributionManager() {
    collect_pointer = 0;
    makeStaticData();
    pdmutil = makeDistributionManagerUtil();
    
    pdmutil->no_warning = kTRUE;
	
    
    
    std_models = new PStdModels();
    std_models->Add(pdmutil);
    pdmutil->AddGroup("plugins", "Plugins");
    SetGroup("plugins");
    batch = NULL;
    loop_start = NULL;
#include "../Plugins.cc"
    pdmutil->no_warning = kFALSE; 
    from_pdecaymanager = 0;
    SetGroup("user");
    Info("PDistributionManager()", "(%s)", PRINT_CTOR);
}
int PDistributionManager::Attach(PChannel *ch) {
    
    
    
    
    pdmutil->LinkDB(); 
    ActivateStdModels();
    return pdmutil->Attach(ch);
}
void PDistributionManager::ActivateStdModels(void) {
    pdmutil->LinkDB(); 
    if (!makeStaticData()->GetFreezeOut()) {
        pdmutil->no_warning = kTRUE;
        
	
	std_models->Add(pdmutil);
        pdmutil->no_warning = kFALSE;
	Info("Attach", "Re-iteration of std plugin done");
	pdmutil->LinkDB(); 
    }    
}
Bool_t PDistributionManager::AddPlugin(PDistributionCollection *plugin) {
    if (collect_pointer == PDISTRIBUTIONMANAGER_MAX_COLLECT) {
	Warning("AddPlugin", "PDISTRIBUTIONMANAGER_MAX_COLLECT reached");
	return kFALSE;
    }
    collect[collect_pointer] = plugin;
    collect_pointer++;
    plugin->SetEnable(0);
    if (makeDistributionManagerUtil()->Add(plugin)) {
	return kFALSE;
    }
    return kTRUE;
}
Bool_t PDistributionManager::Activate(const char *name) {
    
    if (!GetDistribution(name)) {
	Warning("Activate","plugin %s does not exist", name);
	return kFALSE;
    }
    
    if (GetDistribution(name)->GetEnable() && GetDistribution(name)->GetActivated()) return kTRUE;
    
    for (int i=0; i<collect_pointer; i++) {
	if (strcmp(name,collect[i]->GetIdentifier()) == 0) {
	    
	    Int_t pointer = 0;
	    const char *depname = NULL;
	    while ((depname=collect[i]->GetDependency(&pointer)) !=NULL) {
		
		Exec(depname);
	    }
	    if (collect[i]->Activate()) {
		Info("Exec", "Plugin <%s> activated", name);
		collect[i]->SetEnable(1);
		collect[i]->SetActivated(1);
		SetGroup("user");
		return kTRUE;
	    }
	    Warning("Activate", "plugin %s could not be activated",name);
	    return kFALSE;
	}
    }
    Warning("Activate", "plugin %s does not exist",name);
    return kFALSE;
}
#if 1
Bool_t PDistributionManager::ExecAll(const char *command) {
    
    for (int i=0; i<collect_pointer; i++) {
	if (collect[i]->GetEnable()) {
	    collect[i]->ExecCommand(command,0);
	}
    }
    return kTRUE;
}
#endif
Bool_t PDistributionManager::Exec(const char *command) {
    
    
    
    char *array2[200];
    Int_t array2_s = 200; 
    PUtils::Tokenize(command, ":", array2, &array2_s);
    
    if (array2_s > 2) {
	Warning("Exec", "Syntax error: Too many :'s");
	return kFALSE;
    } else {
	
	PDistribution *dist = GetDistribution(array2[0]);
	if (!dist) {
	    Warning("Exec", "model/plugin %s does not exist", array2[0]);
	    return kFALSE;
	}
	if (Activate(array2[0])) {
	    if (array2_s == 2) {
		dist = GetDistribution(array2[0]);
		if (dist->Exec(array2[1])) {
		    SetGroup("user");
		    return kTRUE;
		}
		SetGroup("user");
		return kFALSE;
	    } else  { 
		dist = GetDistribution(array2[0]);
		if (dist->Exec("")) {
		    SetGroup("user");
		    return kTRUE;
		}
		SetGroup("user");
		return kFALSE;
	    }
	    
	}
    }
    return kFALSE;
};
void PDistributionManager::PluginInfo(const char *info) {   
    Info("PDistributionManager", info);
};
Bool_t PDistributionManager::Startup(const char *command) {
    if (!batch) 
	batch = new PBatch;
    batch->AddCommand(command);
    return kTRUE;
};
Bool_t PDistributionManager::Startup(void) {
    if (!batch) return kFALSE;
    return batch->Execute();
};
Bool_t PDistributionManager::Unpack(const char *filename) {
    
    
    
    TFile *current = gROOT->GetFile();
    new TFile(filename);
    
    PCommandList *main = (PCommandList*)gROOT->FindObject("_main");
    if (main) {
	PBatch *priv = new PBatch();
	int level = 0;
	char *cmd;
	while (main->GetCommand(&cmd, level)) {
	    level++;
	    if (cmd) {
		priv->AddCommand(cmd);
	    }
	    if (level > MAX_COMMAND_POINTER) return kFALSE; 
	}
	priv->Execute();
    }
    
    PCommandList *startup = (PCommandList*)gROOT->FindObject("_startup");
    if (startup) {
	int level = 0;
	char *cmd;
	while (startup->GetCommand(&cmd, level)) {
	    level++;
	    if (cmd) {
		Startup(cmd);
	    }
	    if (level > MAX_COMMAND_POINTER) return kFALSE; 
	}
    }
    
    PCommandList *loop_start_cmd = 
	(PCommandList*)gROOT->FindObject("_loop");
    if (loop_start_cmd) {
	if (loop_start) {
	    Error("Unpack", "Loop command list already defined");
	    
	} else {
	    loop_start = new PProjector();
	    loop_start->SetPriority(FILTER_PRIORITY);
	    int level = 0;
	    char *cmd;
	    TObject *obj = NULL;
	    while (loop_start_cmd->GetCommand(&cmd, level, &obj)) {
		level++;
		if (cmd) {
		    if (!obj)
			loop_start->AddCommand(cmd);
		    else if (!strncmp(obj->ClassName(), "TH1", 3)) {
			Info("Unpack", "Recovered TH1 <%s>", obj->GetName());
			loop_start->AddHistogram((TH1*)obj, cmd, 0); 
		    } else if (!strncmp(obj->ClassName(), "TH2", 3)) {
			Info("Unpack", "Recovered TH2 <%s>", obj->GetName());
			loop_start->AddHistogram((TH2*)obj,cmd,0); 
		    } else if (!strncmp(obj->ClassName(), "TH3", 3)) {
			Info("Unpack", "Recovered TH3 <%s>", obj->GetName());
			loop_start->AddHistogram((TH3*)obj, cmd, 0); 
		    } else {
			Warning("Unpack", "Object <%s> is of type <%s>. Unsupported and ignored",
				obj->GetName(), obj->ClassName());
			loop_start->AddCommand(cmd);
		    }
		}
		if (level>MAX_COMMAND_POINTER) return kFALSE; 
	    }	    
	}
    }
    if (current)
	current->cd();
    return kTRUE;
}
ClassImp(PDistributionManager)
 PDistributionManager.cc:1  PDistributionManager.cc:2  PDistributionManager.cc:3  PDistributionManager.cc:4  PDistributionManager.cc:5  PDistributionManager.cc:6  PDistributionManager.cc:7  PDistributionManager.cc:8  PDistributionManager.cc:9  PDistributionManager.cc:10  PDistributionManager.cc:11  PDistributionManager.cc:12  PDistributionManager.cc:13  PDistributionManager.cc:14  PDistributionManager.cc:15  PDistributionManager.cc:16  PDistributionManager.cc:17  PDistributionManager.cc:18  PDistributionManager.cc:19  PDistributionManager.cc:20  PDistributionManager.cc:21  PDistributionManager.cc:22  PDistributionManager.cc:23  PDistributionManager.cc:24  PDistributionManager.cc:25  PDistributionManager.cc:26  PDistributionManager.cc:27  PDistributionManager.cc:28  PDistributionManager.cc:29  PDistributionManager.cc:30  PDistributionManager.cc:31  PDistributionManager.cc:32  PDistributionManager.cc:33  PDistributionManager.cc:34  PDistributionManager.cc:35  PDistributionManager.cc:36  PDistributionManager.cc:37  PDistributionManager.cc:38  PDistributionManager.cc:39  PDistributionManager.cc:40  PDistributionManager.cc:41  PDistributionManager.cc:42  PDistributionManager.cc:43  PDistributionManager.cc:44  PDistributionManager.cc:45  PDistributionManager.cc:46  PDistributionManager.cc:47  PDistributionManager.cc:48  PDistributionManager.cc:49  PDistributionManager.cc:50  PDistributionManager.cc:51  PDistributionManager.cc:52  PDistributionManager.cc:53  PDistributionManager.cc:54  PDistributionManager.cc:55  PDistributionManager.cc:56  PDistributionManager.cc:57  PDistributionManager.cc:58  PDistributionManager.cc:59  PDistributionManager.cc:60  PDistributionManager.cc:61  PDistributionManager.cc:62  PDistributionManager.cc:63  PDistributionManager.cc:64  PDistributionManager.cc:65  PDistributionManager.cc:66  PDistributionManager.cc:67  PDistributionManager.cc:68  PDistributionManager.cc:69  PDistributionManager.cc:70  PDistributionManager.cc:71  PDistributionManager.cc:72  PDistributionManager.cc:73  PDistributionManager.cc:74  PDistributionManager.cc:75  PDistributionManager.cc:76  PDistributionManager.cc:77  PDistributionManager.cc:78  PDistributionManager.cc:79  PDistributionManager.cc:80  PDistributionManager.cc:81  PDistributionManager.cc:82  PDistributionManager.cc:83  PDistributionManager.cc:84  PDistributionManager.cc:85  PDistributionManager.cc:86  PDistributionManager.cc:87  PDistributionManager.cc:88  PDistributionManager.cc:89  PDistributionManager.cc:90  PDistributionManager.cc:91  PDistributionManager.cc:92  PDistributionManager.cc:93  PDistributionManager.cc:94  PDistributionManager.cc:95  PDistributionManager.cc:96  PDistributionManager.cc:97  PDistributionManager.cc:98  PDistributionManager.cc:99  PDistributionManager.cc:100  PDistributionManager.cc:101  PDistributionManager.cc:102  PDistributionManager.cc:103  PDistributionManager.cc:104  PDistributionManager.cc:105  PDistributionManager.cc:106  PDistributionManager.cc:107  PDistributionManager.cc:108  PDistributionManager.cc:109  PDistributionManager.cc:110  PDistributionManager.cc:111  PDistributionManager.cc:112  PDistributionManager.cc:113  PDistributionManager.cc:114  PDistributionManager.cc:115  PDistributionManager.cc:116  PDistributionManager.cc:117  PDistributionManager.cc:118  PDistributionManager.cc:119  PDistributionManager.cc:120  PDistributionManager.cc:121  PDistributionManager.cc:122  PDistributionManager.cc:123  PDistributionManager.cc:124  PDistributionManager.cc:125  PDistributionManager.cc:126  PDistributionManager.cc:127  PDistributionManager.cc:128  PDistributionManager.cc:129  PDistributionManager.cc:130  PDistributionManager.cc:131  PDistributionManager.cc:132  PDistributionManager.cc:133  PDistributionManager.cc:134  PDistributionManager.cc:135  PDistributionManager.cc:136  PDistributionManager.cc:137  PDistributionManager.cc:138  PDistributionManager.cc:139  PDistributionManager.cc:140  PDistributionManager.cc:141  PDistributionManager.cc:142  PDistributionManager.cc:143  PDistributionManager.cc:144  PDistributionManager.cc:145  PDistributionManager.cc:146  PDistributionManager.cc:147  PDistributionManager.cc:148  PDistributionManager.cc:149  PDistributionManager.cc:150  PDistributionManager.cc:151  PDistributionManager.cc:152  PDistributionManager.cc:153  PDistributionManager.cc:154  PDistributionManager.cc:155  PDistributionManager.cc:156  PDistributionManager.cc:157  PDistributionManager.cc:158  PDistributionManager.cc:159  PDistributionManager.cc:160  PDistributionManager.cc:161  PDistributionManager.cc:162  PDistributionManager.cc:163  PDistributionManager.cc:164  PDistributionManager.cc:165  PDistributionManager.cc:166  PDistributionManager.cc:167  PDistributionManager.cc:168  PDistributionManager.cc:169  PDistributionManager.cc:170  PDistributionManager.cc:171  PDistributionManager.cc:172  PDistributionManager.cc:173  PDistributionManager.cc:174  PDistributionManager.cc:175  PDistributionManager.cc:176  PDistributionManager.cc:177  PDistributionManager.cc:178  PDistributionManager.cc:179  PDistributionManager.cc:180  PDistributionManager.cc:181  PDistributionManager.cc:182  PDistributionManager.cc:183  PDistributionManager.cc:184  PDistributionManager.cc:185  PDistributionManager.cc:186  PDistributionManager.cc:187  PDistributionManager.cc:188  PDistributionManager.cc:189  PDistributionManager.cc:190  PDistributionManager.cc:191  PDistributionManager.cc:192  PDistributionManager.cc:193  PDistributionManager.cc:194  PDistributionManager.cc:195  PDistributionManager.cc:196  PDistributionManager.cc:197  PDistributionManager.cc:198  PDistributionManager.cc:199  PDistributionManager.cc:200  PDistributionManager.cc:201  PDistributionManager.cc:202  PDistributionManager.cc:203  PDistributionManager.cc:204  PDistributionManager.cc:205  PDistributionManager.cc:206  PDistributionManager.cc:207  PDistributionManager.cc:208  PDistributionManager.cc:209  PDistributionManager.cc:210  PDistributionManager.cc:211  PDistributionManager.cc:212  PDistributionManager.cc:213  PDistributionManager.cc:214  PDistributionManager.cc:215  PDistributionManager.cc:216  PDistributionManager.cc:217  PDistributionManager.cc:218  PDistributionManager.cc:219  PDistributionManager.cc:220  PDistributionManager.cc:221  PDistributionManager.cc:222  PDistributionManager.cc:223  PDistributionManager.cc:224  PDistributionManager.cc:225  PDistributionManager.cc:226  PDistributionManager.cc:227  PDistributionManager.cc:228  PDistributionManager.cc:229  PDistributionManager.cc:230  PDistributionManager.cc:231  PDistributionManager.cc:232  PDistributionManager.cc:233  PDistributionManager.cc:234  PDistributionManager.cc:235  PDistributionManager.cc:236  PDistributionManager.cc:237  PDistributionManager.cc:238  PDistributionManager.cc:239  PDistributionManager.cc:240  PDistributionManager.cc:241  PDistributionManager.cc:242  PDistributionManager.cc:243  PDistributionManager.cc:244  PDistributionManager.cc:245  PDistributionManager.cc:246  PDistributionManager.cc:247  PDistributionManager.cc:248  PDistributionManager.cc:249  PDistributionManager.cc:250  PDistributionManager.cc:251  PDistributionManager.cc:252  PDistributionManager.cc:253  PDistributionManager.cc:254  PDistributionManager.cc:255  PDistributionManager.cc:256  PDistributionManager.cc:257  PDistributionManager.cc:258  PDistributionManager.cc:259  PDistributionManager.cc:260  PDistributionManager.cc:261  PDistributionManager.cc:262  PDistributionManager.cc:263  PDistributionManager.cc:264  PDistributionManager.cc:265  PDistributionManager.cc:266  PDistributionManager.cc:267  PDistributionManager.cc:268  PDistributionManager.cc:269  PDistributionManager.cc:270  PDistributionManager.cc:271  PDistributionManager.cc:272  PDistributionManager.cc:273  PDistributionManager.cc:274  PDistributionManager.cc:275  PDistributionManager.cc:276  PDistributionManager.cc:277  PDistributionManager.cc:278  PDistributionManager.cc:279  PDistributionManager.cc:280  PDistributionManager.cc:281  PDistributionManager.cc:282  PDistributionManager.cc:283  PDistributionManager.cc:284  PDistributionManager.cc:285  PDistributionManager.cc:286  PDistributionManager.cc:287  PDistributionManager.cc:288  PDistributionManager.cc:289  PDistributionManager.cc:290  PDistributionManager.cc:291  PDistributionManager.cc:292  PDistributionManager.cc:293  PDistributionManager.cc:294  PDistributionManager.cc:295  PDistributionManager.cc:296  PDistributionManager.cc:297  PDistributionManager.cc:298  PDistributionManager.cc:299  PDistributionManager.cc:300  PDistributionManager.cc:301  PDistributionManager.cc:302  PDistributionManager.cc:303