#include "sTable.h"

#define S_ZERO 0
#define S_FALSE 0
#define S_TRUE 1
#define S_DONTCARE 2

STable * symbTable;
ostream * g_output;
TreeArray * treeArray;
string l_name;
Element * elem;
Node * root = (Node * )0xf;
Symbol * symb;
clock_t gt1, gt2;
bool measure = false;
bool absorbtion = true;
bool autoprint = false;
string command_str = "";
unsigned int added_formulas = 0;
//unsigned int terms = 0;


//polozka v tabulce symbolu
Symbol::Symbol(string s) : name(s), value(S_ZERO), valid(false), next(NULL) {}


	//tabulka symbolu
	STable::STable() : first(NULL), last(NULL), act(NULL), count(0) {}
	
	/*unsigned int STable::getValue (string s)
	{
		Symbol * ptr = first;
		while (ptr != NULL)
		{
			if (ptr->name == s) return (ptr->value);
			ptr = ptr->next;
		}
		
		return 0; //pokud tam dany symbol neni
	}*/
	
	void STable::refresh()
	{
		Symbol * ptr = first;
		act = first;
		while (ptr != NULL)
		{
			ptr->valid = false;
			ptr = ptr->next;
		}
		
	}
	
	bool STable::empty()
	{
		return (first == NULL);
	}
	
	Symbol * STable::getPtr (string s)
	{
		Symbol * ptr = first;
		while (ptr != NULL)
		{
			if (ptr->name == s) return (ptr);
			ptr = ptr->next;
		}
		
		return NULL; //pokud tam dany symbol neni
	}
	
	void STable::setValue (string s, unsigned int val)
	{
		Symbol * ptr = first;
		while (ptr != NULL)
		{
			if (ptr->name == s)
			{
				ptr->value = val;
				ptr->valid = true;
				return;
			}
			ptr = ptr->next;
		}
		
	}
	
	void STable::add (string s)
	{
		if ( exists(s) ) return;
		count++;
		if (first == NULL)
		{
			last = new Symbol (s);
			first = last;
		}
		
		else
		{
			last->next = new Symbol (s);
			last = last->next;
		}
		
	}
	
	bool STable::exists (string s)
	{
		Symbol * ptr = first;
		while (ptr != NULL)
		{
			if (ptr->name == s) return true;
			ptr = ptr->next;
		}
		
		return false;
	}
	
	void STable::print(ostream * output)
	{
		Symbol * ptr = first;
		 
		while (ptr != NULL)
		{
			int val = ptr->value&1;
			*output<<" "<<ptr->name<<"=";
			if (ptr->valid) { *output<<val; }
			else { *output<<"x"; }
			ptr = ptr->next;
		}
		
	}
	
	void STable::printvals(ostream * output)
	{
		Symbol * ptr = first;
		 
		while (ptr != NULL)
		{
			int val = ptr->value&1;
			if (ptr->valid) { *output<<val; }
			else { *output<<"-"; }
			ptr = ptr->next;
		}
	}
	
	void STable::printnames(ostream * output)
	{
		Symbol * ptr = first;
		 
		while (ptr != NULL)
		{
			*output<<" "<<ptr->name;
			ptr = ptr->next;
		}
	}
	
	void STable::printnamescomma(ostream * output)
	{
		Symbol * ptr = first;
		 
		while (ptr != NULL)
		{
			if (ptr == first) *output<<" "<<ptr->name;
			else *output<<", "<<ptr->name;
			ptr = ptr->next;
		}
	}
	
	Symbol * STable::find (int i)
	{
		Symbol * ptr = first;
		int num = 0;
		
		while (ptr != NULL)
		{
			if (num == i) return ptr;
			num++;
			ptr = ptr->next;
		}
		return NULL;
	}
	
	Symbol * STable::get()
	{
		Symbol * ptr = act;
		if (act != NULL) act = act->next;
		return ptr;
	}
	
	
	STable::~STable()
	{
		Symbol *ptr = first;
		Symbol *del;
		while (ptr != NULL)
		{
			del = ptr;
			delete del;
			ptr = ptr->next;
		} 
	}
	
	
	//*********************************************************
	
	
	Element::Element(Node * ptr = NULL, STable * tab = NULL, string str = "") : root(ptr), symbTable(tab), name(str), terms(0), next(NULL) {}
	
	Element::~Element()
	{
		delete root;
		delete symbTable;
	}
	
	//***********************************************************
	

	TreeArray::TreeArray() : first(NULL), last(NULL), terms(0), invars(0), outvars(0), namedi(0), namedo(0), symbNames(NULL) {}
	
	//prida element
	void TreeArray:: add (Node * root, STable * table, string s)
	{
		outvars++;
		
		if (first == NULL)
		{
			last = new Element (root, table, s);
			first = last;
		}
		
		else
		{
			last->next = new Element (root, table, s);
			last = last->next;
		}
	}
	
	//smaze element
	void TreeArray::remove (int num)
	{
		if (first == NULL) {return;}
		Element * ptr = first;
		Element * prev = NULL;
		int count = 0;
		
		while (ptr != NULL)
		{
			if (count == num)
			{
				if (ptr == first)
				{
					first = first->next;
					delete ptr;
					if (first == NULL) {last = NULL;}
				}
				else {prev->next = ptr->next; delete ptr;}
				return;
			}
			count++;
			prev = ptr;
			ptr = ptr->next;
		}
	}
	
	//najde element
	Element * TreeArray:: find (int num)
	{
		Element * ptr = first;
		int count = 0;
		
		while (ptr != NULL)
		{
			if (count == num) return ptr;
			count++;
			ptr = ptr->next;
		}
		return NULL;
	}
	
	TreeArray::~TreeArray()
	{
		Element * ptr, * del;
		ptr = first;
		while (ptr != NULL)
		{
			del = ptr;
			ptr = ptr->next;
			delete del;
		}
		
		if (symbNames != NULL) {delete symbNames;}
	}
