/*
 * AresVExtraFunctions.cpp
 *
 *  Created on: 11-Jul-08
 *      Author: indurks
 */

#include "AresV.h"

using namespace std;

int Exponentiate(int a, int b) {
	int t = 1;
	for(int i = 0; i < b; i++)
		t *= a;
	return t;
}

void InitializeTree(int &myBefore, int &myAfter, int &myDepth, int numEntries) {
	// First figure out what is the biggest power of Stellar
	int depth = 2, k = 64;
	while(k < numEntries) {
		depth += 1;
		k *= Stellar;
	}

	// Now we know how many levels deep the tree is, so trim off the extra
	// entries
	int before = 1;

	for(int i = 0; i < depth - 1; i++)
		before += Exponentiate(Stellar, i);

	//before += 1; // Starting point of our reactions

	int after = before + numEntries; // entry after our reactions

	myBefore = before;
	myAfter = after;
	myDepth = depth;
}

void ImportChemsAndReactionsAndSumProp(
			string strBRxn_FileName,
			string strBChem_FileName,
			string strSumProp_FileName,
			vector<Reaction> &myRxns,
			vector<Chemical> &myChems) {

	ifstream BRxnInput(strBRxn_FileName.c_str());
	ifstream BChemInput(strBChem_FileName.c_str());
	ifstream SumPropInput(strSumProp_FileName.c_str());

	int numChems, numRxns;

	BChemInput >> numChems;

	for(int i = 0; i < numChems; i++) {
		Chemical c;
		BChemInput >> c.ID >> c.Name >> c.initConc;
		myChems.push_back(c);
	}

	BRxnInput >> numRxns;

	for(int i = 0; i < numRxns; i++) {
		Reaction r;
		BRxnInput >> r.r1 >> r.r2 >> r.p1 >> r.p2 >> r.rate;
		if(r.r1 == r.r2)
			r.rate /= 2.0;
		float t;
		SumPropInput >> t >> r.sumPropensity;
		myRxns.push_back(r);
	}
}

list<int> getRxnTapeFromReaction(Reaction r)
{
	map<int, int> changes;
	changes[r.r1] = changes[r.r2] = changes[r.p1] = changes[r.p2] = 0;
	changes[r.r1] -= 1;
	changes[r.r2] -= 1;
	changes[r.p1] += 1;
	changes[r.p2] += 1;

	list<int> answer;

	for(map<int, int>::iterator iter = changes.begin(); iter != changes.end(); iter++)
		if(iter->first != 0 && iter->second != 0)
		{
			if(iter->first < 0)
			{
				cout << std::endl << r.r1 << "	" << r.r2 << "	" << r.p1 << "	" << r.p2 << std::endl;
				cout << iter->first << "	" << iter->second << std::endl;
				exit(0);
			}
			answer.push_back(iter->first);
			answer.push_back(iter->second);
		}

	return answer;
}
