/*
 * AresV.h
 *
 *  Created on: 11-Jul-08
 *      Author: indurks
 */

#include "Intel_Compatibility.h"
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <list>
#include <string>
#include <algorithm>

using namespace std;

typedef map<int, pair<double, map<int, list<int> > > > SuperDuperMap;

const int Stellar = 64;
const int SUB_TREE_THRESHOLD = 4;
const bool NULL_SUBTREES_ALLOWED = false;

struct Reaction
{
	int r1, r2, p1, p2, ID;
	double rate;
	double sumPropensity;
	list<int> affectedChemicals;
};

struct Chemical {
	int ID;
	string Name;
	int initConc;
};

class GuardedTables {
public:
	vector<Reaction> myRxns;
	vector<Chemical> myChems;

	GuardedTables(vector<Reaction> &rxns, vector<Chemical> &chems);

	Reaction getRxn(int n);
	Chemical getChem(int n);
	int getNumRxns();
	int getNumChems();
};

class ChemicalMatrix
{
public:
	SuperDuperMap chemMatrix;
	int numReactionsRemoved;

	ChemicalMatrix(GuardedTables &myGuardedTables);

	void ProcessReaction(Reaction &r, int z);
	void ComputeAffectedChemicalsForReaction(Reaction &r);
	bool hasChemical(int chem);
	int getNumReactions(int chem);
	double getScore(int chem);
	bool listContainsInt(list<int> &theList, int n);
	Reaction RemoveReaction(Reaction r);
};

class MyTree {
public:
	int numRxns;
	int deMultiplierChemical;
	int myBefore, myAfter, myDepth;

	double mySumPropensity;
	vector<Reaction> myRxns;

	MyTree(int mySpecialChem, vector<Reaction> &rxns, int orientation);
	int getOffSet();
	void CalculateSumPropensity();
	void SortReactions();
};

class MyCloud
{
public:
	int deMultiplierChemical;
	int myPreviousOffset;
	double mySumPropensity;

	MyTree* mainTree;
	vector<MyTree*> trees;

	MyCloud(int deMul);
	void SetMainTree(MyTree *t);
	void AddTree(MyTree *t);
	void SortCloud();
	int getOffSet();
	void CalculateSumPropensity();
};

// Extra functions
void ImportChemsAndReactionsAndSumProp(
			string strBRxn_FileName,
			string strBChem_FileName,
			string strSumProp_FileName,
			vector<Reaction> &myRxns,
			vector<Chemical> &myChems);

void InitializeTree(int &myBefore, int &myAfter, int &myDepth, int numEntries);
void HandleChemical(int c, GuardedTables &myGuardTables, ChemicalMatrix &myCM, list<MyCloud> &myClouds);
list<int> getRxnTapeFromReaction(Reaction r);
