/*

    Bist: a chemical drawing tool
    Copyright (C) 2008 Valerio Benfante

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
/*

grammatica


catena := (frammento)*

frammento := pivot (figlio)*

figlio := atomo numero? | par_tonda_ap frammento par_tonda_c numero*

pivot := 'C' | 'O'

atomo := '=O' | 'H'

par_tonda_ap := '('

par_tonda_c  := ')'




*/

/**

    R(r_x,r_y)
    +--------------+
    |              |
    |              |
    |              |
    |              |
    +--------------+S(s_x,s_y)

*/





struct res_aa_bb {
  float s_x;
  float s_y;
  float r_x;
  float r_y;
};


class parse_residue {

public:
  parse_residue(string res);
  ~parse_residue();

  gruppo return_fragment();

  bool has_error();


protected:

  void dump();

  parse_residue(){

  }

  void transl_branch(gruppo& group,atomo* start,atomo* parent,
		     float dx, float dy);

  void clean(gruppo& group, atomo& start);

  bool aa_bb_intersects(gruppo& grp, 
			atomo start);

  void clean_as_tree(gruppo& group, atomo& start,
		     float distmax, int level, int xst);


  void create_aa_bb(gruppo grp, int st,
		    int children,
		    res_aa_bb& res);

  void create_starter();


  void chain();

  void frammento();

  void pivot();

  void figlio();

  bool number(unsigned int& res);


  void add_atoms(gruppo* mol,
		 string et,int tipo,
		 bool new_sticky);

  string etich_sticky_atom(gruppo* mol);


  atomo* search_for_attach(gruppo* the_mol);

  string _res;
  int _pt_res;

  float _length_leg;

  stack<gruppo> _fragments;

  gruppo  _the_mol;
  string _the_pivot;
  bool _stop;

  bool _pivot_unknown;
  bool _has_error;

  const static string par_a;
  const static string par_c;
  const static string carb;
  const static string sulf;
  const static string nytr;
  const static string oxyg;
  const static string db_o;
  const static string hidr;
  const static string clor;
  const static string bromine;
  const static string iodine;
  const static string fluorine;

  const static float  _angle_exa;
  
};


vector<float> trova_pos_libere(gruppo& grp, atomo& atm, int numleg=2);


bool check_if_inside_arc(float angle_ref,
			float angle_probe,
			float tolerance);


void place_bonds(vector<float>& result, atomo atm,float lenght_leg,
		 float start_angle,int numleg=2,
		 float step=.523598775598298873078);


void no_of_leaf(gruppo& grp,atomo& start, int& res);
