#ifdef STATISTICS
#include "Behavioural/include/Stat_binary_tree.h"

namespace morpheo {
namespace behavioural {

#define string2operator(x) (x=="+")?add:((x=="-")?sub:((x=="*")?mul:((x=="/" )?div:((x=="++")?inc:dec))))

  void Stat_binary_tree::import (std::string expr,
                                 std::map<std::string, counter_t*> * operand)
  {
    const std::string delims  (" ");          // délimiteur : " "
    const std::string numbers ("0123456789"); // délimiteur : " "
    std::string::size_type index_begin, index_end;

    Stat_binary_tree * tree = this;

    index_begin = expr.find_first_not_of(delims);

    while (index_begin != std::string::npos)
      {
	index_end = expr.find_first_of(delims, index_begin);

	if (index_end == std::string::npos)
	  {
	    index_end = expr.length();
	  }
	
	std::string str = expr.substr(index_begin, index_end-index_begin);
	
	// 3 possibilités :
	//  * operator
	//  * constante
	//  * variable
	{
	  // Test constantes
	  std::string::size_type index = str.find_first_not_of(numbers);
	  if (index  == std::string::npos)
	    {
// 	      std::cout << " * c'est une constante." << std::endl; 
              counter_t cst = atoi(str.c_str());

              if (tree->_data_type == NONE)
                change_type(cst);
              else
                if (tree==NULL)
                  tree = new Stat_binary_tree (cst);
                else
                  tree = tree->insert_tree (cst);
	    }
	  else
	    {
	      // Test variables
              std::map<std::string, counter_t*>::iterator it = operand->find(str);
	      if (it != operand->end())
		{
// 		  std::cout << " * c'est une variable." << std::endl; 
                  counter_t * var = it->second;

                  if (tree->_data_type == NONE)
                    change_type(var);
                  else
                    if (tree==NULL)
                      tree = new Stat_binary_tree (var);
                    else
                      tree = tree->insert_tree (var);
		}
	      else
		{
		  if ((str == "+") or
		      (str == "-") or
		      (str == "*") or
		      (str == "/"))
		    {
// 		      std::cout << " * c'est un operator à 2 opérandes." << std::endl; 
		 
                      operator_t op = string2operator(str);

                      if (tree->_data_type == NONE)
                        change_type(op);
                      else
                        if (tree==NULL)
                          tree = new Stat_binary_tree (op);
                        else
                          tree = tree->insert_tree (op);
		    }
		  else
		    {
		      if ((str == "++") or
			  (str == "--"))
			{
// 			  std::cout << " * c'est un operator à 1 opérande." << std::endl; 

                          operator_t op = string2operator(str);
                          
                          if (tree->_data_type == NONE)
                            change_type(op);
                          else
                            if (tree==NULL)
                              tree = new Stat_binary_tree (op);
                            else
                              tree = tree->insert_tree (op);
			}
		      else
			{
// 			  std::cout << " * c'est autre chose." << std::endl; 
			  throw(ERRORMORPHEO("Stat_binary_tree::string2tree",toString(_("expression '%s' doesn't a constant, a declarated variable or an operator.\n"),str.c_str())));
			}
		    }
		}
	    }
	}

	index_begin = expr.find_first_not_of(delims, index_end);

	if (index_begin != std::string::npos)
	  tree = tree->goto_next_root();
      }

    if (tree == NULL)
      throw (ERRORMORPHEO("Stat_binary_tree::string2tree",_("The tree generated is empty.\n")));

//     std::cout << "<Stat::string2tree> goto_top_level" << std::endl;

    tree = tree->goto_top_level();

//     std::cout << "<Stat::string2tree> valid" << std::endl;

//     print();

    if ((not tree->valid()) or (not valid()))
      throw (ERRORMORPHEO("Stat_binary_tree::string2tree",_("the tree generated is invalid.\n")));

//     std::cout << "<Stat::string2tree> End" << std::endl;
  }
  
};
};
#endif
