/*

    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/>.
*/

/**
 *Un plugin per bist; per scriverne uno basta ereditare da questa classe
 *ridefinendo i metodi virtuali puri.
 *
 *Il      plugin     viene      crerato     ed      inizializzato     da
 *editor::start_plugin_cb(Fl_Widget* w, void* d)  il quale prima apre la
 *libreria     e    crea    l'oggetto     e    richiama     il    metodo
 *bist_plugin::inizialize. Questo metodo puo' essere utile per richiamae
 *finestre  di dialogo  ad  esempio.  L'oggetto  specifico (derivato  da
 *bist_plugin non puo' essere  inizializzato direttamente perche in fase
 *di compilazione il  linker nulla sa diei tipi  presenti nella libreria
 *dinamica dove  e' definito il  plugin.  quindi bisogna  definire anche
 *due funzioni:
 *
 *extern "C" bist_plugin* create_plugin(immagine* imm,  string libpath); 
 *extern "C" void destroy_plugin(bist_plugin* j);
 *
 *che, rispettivamente, creano e distruggono l'oggetto plugin effettivio
 *derivato da bist_plugin
 *
 *Successivamente il metodo mol_canvas::handle richiama come prima istruzione 
 *mol_canvas::plugin()->need_to_act() e se questo vale true allora viene richiamato
 *mol_canvas::plugin()->act() che fa agire il plugin ed esce da handle().
 *
 *E' importante  capire che mol_canvas::plugin()->need_to_act()  serve a
 *far "capire" al  plugin se e' il momento di agire  in quanto il plugin
 *puo' valutare di "rivegliarsi" ed agire solo quando almeno un elemento
 *e' stato selezionato, ad esempio.
 *
 *e' conveniente dare un'occhiata  ai sorgenti nella directory pluginsrc
 *(in particolare  join_ring.cpp e insert_template.cpp)  per capire come
 *funzioni il sistema di plugin e come scriverne uno.
 */


class bist_plugin {

public:
  /**
   *Crea il plugin
   *\param imm l'immagine da modificare
   *\param libpath il path della libreria da inizializzare
   */
  
  bist_plugin(immagine* imm,string libpath);

  virtual ~bist_plugin();

  /**
   *Registra il plugin
   *Serve a scoprire quali informazioni elaborera' il plugin
   */
  virtual void register_plugin()=0;

  /**
   *questo   metodo   viene   richiamato   come  prima   istruzione   da
   *mol_canvas::handle,  se ritorna  true, allora  viene successivamente
   *richiamato bist_plugin::act()
   */
  virtual bool time_to_act()=0;
  
  /**
   *Il plugin agisce
   *\return true if no error happened
   */

  virtual bool act(int event)=0;

  /**
   *Viene  richiamato immediatamente  dopo  aver caricato  il plugin  ed
   *istanziata la classe
   */

  virtual void inizialize()=0;
  /**
   * Ritorna  true se  il plugin  necessita del  vettore  contenente gli
   * atomi le procedure e le etichette selezionate
   */

  virtual bool need_atom()=0;

  /**
   * Ritorna  true se  il plugin  necessita del  vettore  contenente i
   * legami selezionati
   */
  virtual bool need_leg()=0;

  virtual std::string menu_path();
  
  /**
   *inutilzzato
   */
  virtual bool consume_push_evt(){ return false; }
  /**
   *inutilzzato
   */
  virtual bool consume_keydown_evt(){ return false; }
  /**
   *inutilzzato
   */
  virtual bool consume_drag_evt(){ return false;}
  /**
   *inutilzzato
   */
  virtual bool consume_release_evt(){ return false; }
  


  virtual string libpath();
  /**
   *Ritorna un puntatore a the_image::_stringhe;
   */
  vector <etichetta*>*  r_etich();

  /**
   *Ritorna un puntatore a the_image::_gruppi
   */
  vector <gruppo>* r_groups();
  /**
   *Ritorna un puntatore a the_image::_elem_selected
   */
  vector< pair < int, pair<int,int> > >*  r_elem_selected();
  /*
   *Ritorna un puntatore a the_image::_legami_selected
   */
  vector<int*>* r_legami_selected();

  /**
   *Setta l'immagine
   */
  void image(immagine* imm);


protected:

  std::vector<etichetta*> get_all_etich_as_vector();
  std::vector<gruppo*>    get_all_molecule_as_vector();
  std::vector<procedura*> get_all_proc_as_vector();



  string _lib;
  immagine* _the_image;
};


