// Author: I. Froehlich
// Written: 14.02.2008
// 

#ifndef _PBATCH_H_
#define _PBATCH_H_

#include "TInterpreter.h"
#include "TMethodCall.h"
#include "TMethodArg.h"

#include "PFormula.h"
#include "PValues.h"
#include "PParticle.h"

#include "TROOT.h"
#include "TTree.h"
#include "TH1.h"
#include "TH2.h"
#include "TH3.h"
#include "TGraph.h"
#include "TGraph2D.h"

#include <iostream>
#include "PDefines.h"

using namespace std;

#define MAX_COMMAND_POINTER    1000
#define MAX_COMMAND_TMETHODS   100
#define MAX_COMMAND_OPTIONS    10
#define MAX_STACK_GOSUB        20
#define MAX_READLINE_ARGS      20


#define IS_OBJECT 1
#define IS_DOUBLE 2

#define kFOREACH    2
#define kGOTO       4
#define kFOREACHEND 8
#define kUPDATE     16
#define kEOF        32
#define kPUSH       64
#define kPUSHBRANCH 128
#define kELSE       256

#define COMMAND_MASS  '1'
#define COMMAND_MASS2 '2'
#define COMMAND_GETBEAM   '3'
#define COMMAND_GETTARGET '4'
#define COMMAND_IF    '?'
#define COMMAND_ELSE  '%'
#define COMMAND_PLUS  '+'
#define COMMAND_MINUS '-'
#define COMMAND_DIV   '/'
#define COMMAND_MULT  '*'
#define COMMAND_IS    '='
#define COMMAND_EQUAL '~'


#define COMMAND_BOOST     'b'
#define COMMAND_COS       'c'
#define COMMAND_EVAL      'e'
#define COMMAND_FABS      'f'
#define COMMAND_INTERNAL  'i'
#define COMMAND_PRINT     'p'
#define COMMAND_ROT       'r'
#define COMMAND_THETA     't'
#define COMMAND_GETRANDOM 'v'
#define COMMAND_GETRANDOMX 'x'
#define COMMAND_GETRANDOMY 'y'


#define COMMAND_ANGLE    'A'
#define COMMAND_BRANCH   'B'
#define COMMAND_P3E      'E'
#define COMMAND_GOTO     'G'
#define COMMAND_PUSH     'H'
#define COMMAND_LABEL    'L'
#define COMMAND_PFORMULA 'P'
#define COMMAND_P3M      'Q'
#define COMMAND_RETURN   'R'
#define COMMAND_GOSUB    'S'
#define COMMAND_PVALUE   'V'
#define COMMAND_EXIT     'X'
#define COMMAND_ECHO     'Y'
#define COMMAND_READLINE 'Z'
#define COMMAND_FORMORE  '>'
#define COMMAND_FOREACH  '<'



#define METHOD_RETURN_DOUBLE 1
#define METHOD_RETURN_INT    2
#define METHOD_RETURN_VOID   4
#define METHOD_RETURN_PPARTICLE   8

#define STREAM_MAX_POS       "npar"
#define STREAM_DEFAULT_POS   "cpos"

class PBatch;
PBatch& fBatch();
PBatch* makeGlobalBatch();


class PBatch : public TObject {

 private:

    Bool_t CheckAndSplit(char * arg, char delim, int *key1, int *key2);
    
    Bool_t GetArguments(const char *a, /* const char *b, */ 
			char *name, char **function, char **arg1, char **arg2);
    Int_t  CheckObjectType(Int_t key);
    Int_t  GetKey(char *name, int fl, int makeflag);
    Int_t  GetDelimPosition(char *arg, char delim, Int_t *yes=NULL);

    Int_t  GetMethodHandle(char *name, Int_t flag=0);
    Int_t  CrackMethodArgs(char *name);
    Int_t  arg1, arg2, arg3, arg4;

    Int_t command_pointer, method_pointer, last_command_pointer;
    TMethodCall *methods[MAX_COMMAND_TMETHODS];
    char *method_name[MAX_COMMAND_TMETHODS];
    Int_t methods_flags[MAX_COMMAND_TMETHODS],
	methods_arg_flags[4][MAX_COMMAND_TMETHODS];

    char lst_command[MAX_COMMAND_POINTER];
    Int_t lst_command_int[MAX_COMMAND_POINTER];
    Int_t flag_command_int[MAX_COMMAND_POINTER];  //=0: PParticle, =1: PUtilsRengine
    Int_t lst_key_a[MAX_COMMAND_POINTER];
    Int_t error_flag[MAX_COMMAND_POINTER];
    Int_t lst_key[MAX_COMMAND_OPTIONS][MAX_COMMAND_POINTER];
    Int_t  lst_options_counter[MAX_COMMAND_POINTER];
    PFormula *lst_form[MAX_COMMAND_POINTER];
    //    Int_t lst_key2[MAX_COMMAND_POINTER];
    //    Int_t lst_key3[MAX_COMMAND_POINTER];
    //    Int_t lst_key4[MAX_COMMAND_POINTER];

    char *echo_string[MAX_COMMAND_POINTER];
    char *readline_format_string[MAX_COMMAND_POINTER];
    char *readline_string[MAX_COMMAND_POINTER];
    Double_t **readline_args[MAX_COMMAND_POINTER];
    int readline_num_args[MAX_COMMAND_POINTER];
    char *varlist;   //Allowed command for new variables

    Int_t batch_particle_param, batch_value_param, pid_param, num_command_param, num_batch_param, num_bulk_param,
	stream_default_pos_param, stream_max_pos_param, batch_update_param, batch_models_param;
    Int_t batch_histogram_param;
    Int_t num_batch,num_bulk, locnum_batch, locnum_bulk, locnum_command, locnum_old_command;  //Position in the projector & reaction loop
    Int_t locnum_branch; //current branch number
    Int_t else_position;
    Int_t current_position;

    static Int_t stack_num_batch[MAX_STACK_GOSUB], stack_num_bulk[MAX_STACK_GOSUB], 
	stack_num_command[MAX_STACK_GOSUB], stack_num_pos;

    void  AddSpacePlaceholder(char *command);
    void  RemoveSpacePlaceholder(char *command);
    Int_t EvalPFormula(char *command);
    

    PValues pdummy;

    TH1       *fHisto1;
    TH2       *fHisto2;
    TH3       *fHisto3;
    TGraph    *fGraph;
    TGraph2D  *fGraph2D;
    Int_t      is_readonly;
    TH1D      **slicesx, **slicesy;

    FILE      *file, *tmp_file;
    PParticle *current_particle; //For push command

    Double_t *x, *y, *z;  //Axis values for _eval
    Int_t eval_err_dumped;

    Int_t status;

    TTree *tree;         //Pointer to storage tree
    Int_t *size_branches;
    Int_t *key_branches;
    

 public:

    //constructor
    PBatch();

    void Print(const Option_t *delme=NULL) const ;

    Bool_t AddCommand(const char *command); //adds a command line to batch
    Bool_t AddCommand(char command, int key_a, int key1, int key2, int key3=-1, int key4=-1, int key5=-1);

    void SetPosition(Int_t my_num_batch, Int_t my_num_bulk) {
	num_batch = my_num_batch; 
	num_bulk  = my_num_bulk;
    };
    Int_t GetNewBatch()   {return locnum_batch;};
    Int_t GetNewBulk()    {return locnum_bulk;};
    Int_t GetNewCommand() {return locnum_command;};
    Int_t GetOldCommand() {return locnum_old_command;};
    Int_t GetBranch()     {return locnum_branch;};
    Int_t GetElsePosition() {return else_position;};
    Int_t GetCurrentPosition() {return current_position;};

    using TObject::Execute;
    Int_t Execute(Int_t command_pos=0, Int_t retval=kFALSE);
    Int_t ExecuteLastLine(void) {
	Bool_t retval = Execute(last_command_pointer);
	last_command_pointer = command_pointer;
	return retval;
    }
    Bool_t Execute(const char *command) {
	if (AddCommand(command)) {
	    return (Bool_t)ExecuteLastLine();
	}
	last_command_pointer = command_pointer;
	Error("Execute", "Command not executed");
	return kFALSE;
    }

    void SetToolObject(TH1 *Histo1) {
	fHisto1 = Histo1;
    }
    void SetToolObject(TH2 *Histo2) {
	fHisto2 = Histo2;
    }
    void SetToolObject(TH3 *Histo3) {
	fHisto3 = Histo3;
    }
    void SetToolObject(TGraph *Graph) {
	fGraph = Graph;
    }
    void SetToolObject(TGraph2D *Graph2D) {
	fGraph2D = Graph2D;
    }
    void SetToolObject(FILE *f) {
	file = f;
    }
    void SetToolObjectTmp(FILE *f) {
	tmp_file = f;
    }
    Int_t IsReadonly() {
	return is_readonly;
    }

    PParticle *GetCurrentParticle(void) {
	return current_particle;
    }

    Int_t Status(void) {
	//workaround to check for a "[+]"
	//=1 for such a case
	//=0 in all other cases
	return status;
    }

    void SetVarList(char *my_x) {
	//Allowed commands for new variables
	//Format must be "a;b;c;" with trailing ;'s 
	//If NULL don't care!
	varlist = my_x;
    };

    void ReplaceAll(TString *op, const char *oldstring, const char *newstring);

    void SetTree(TTree *my_tree) {tree = my_tree;};
    TTree *GetTree(void)         {return tree;};

    void SetSizeBranches(Int_t *my_size_branches) {size_branches = my_size_branches;};
    void SetKeysBranches(Int_t *my_key_branches)  {key_branches = my_key_branches;};

    ClassDef(PBatch, 0)  //Batch commands
};

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