/*

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

#include <config.h>
#include <global.hpp>

#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include <cairo_t_singleton.hpp>
#include <glib.h>


#include <config_path.h>
#include <sys/stat.h>
#include <dirent.h>

#include <FL/Fl_Image.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Toggle_Button.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Light_Button.H>
#include <FL/Fl_Help_Dialog.H>
//#include <FL/Fl_PNG_Image.H>
#include <FL/Fl_Tree.H>

#include <interfacce.hpp>
#include <legame.hpp>
#include <etichetta.hpp>
#include <multiline_label.hpp>
#include <multifont_label.hpp>
#include <paragraph_text.hpp>
#include <atomo.hpp>
#include <procedura.hpp>
#include <gruppo.hpp>
#include <immagine.hpp>
#include <bist_plugin.hpp>
#include <mol_canvas.hpp>

#include <util.hpp>

#include <finestra_pr.hpp>
#include <editor.hpp>
#include <bond_prop.hpp>
#include <string_prop.hpp>

#include <lib_dialog.hpp>


void lib_dialog_tree_callback(Fl_Widget* w, void* ){
  lib_dialog* dia=dynamic_cast<lib_dialog*>(w->window());
  dia->redraw();

  Fl_Tree      *tree=dynamic_cast<Fl_Tree*>(w);
  Fl_Tree_Item *item=dynamic_cast<Fl_Tree_Item*>(tree->callback_item());
  switch (tree->callback_reason()) {
  case FL_TREE_REASON_SELECTED: 
    {
      char selected[1024];
      tree->item_pathname(selected,sizeof(selected),item);
      std::string actual_path= s_replace(lib_dialog::root_bra,std::string(selected), std::string(""),true);
      dia->_imm->reset_all();
      dia->_imm->filebist(actual_path);
      dia->_imm->start();
      dia->_imm->print_warn();
      dia->_imm->print_errors();
      dia->_template_file=actual_path;
      dia->redraw();

    }
  default:
    break;
  }
}

void lib_dialog_ok_callback(Fl_Widget* w, void* ){
  lib_dialog* dia=dynamic_cast<lib_dialog*>(w->window());
  dia->hide();
}

void lib_dialog_cancel_callback(Fl_Widget* w, void* ){
  lib_dialog* dia=dynamic_cast<lib_dialog*>(w->window());
  dia->_template_file="";
  dia->hide();
}


string lib_dialog::get_template_file(){
  return _template_file;
}

lib_dialog::lib_dialog()
  :Fl_Double_Window(W_D,H_D,_("Insert object")),
   _preview(10+GAP_ELE*3+W_TREE+GAP_BOX,
	    GAP_ELE+GAP_BOX,
	    W_TREE*3-GAP_ELE,
	    H_TREE*3-GAP_ELE)

   
{

  string home_dir=getenv("HOME");
  _preview.action(ACT_NOTHING);
  _imm=new immagine(true);
  _grp=new Fl_Scroll(10+W_TREE+GAP_ELE*2+GAP_BOX,GAP_BOX,W_TREE+GAP_ELE, H_TREE+GAP_ELE);
  _grp->type(Fl_Scroll::BOTH_ALWAYS);
  _grp->box(FL_UP_FRAME);
  _grp->add(_preview);
  _preview.add_immagine(_imm);
  add(_grp); 

  _tree=new Fl_Tree(GAP_BOX+GAP_ELE, GAP_BOX+GAP_ELE, W_TREE, H_TREE);
  _tree->callback(lib_dialog_tree_callback);
  _tree->root_label(root_bra.c_str());
  _tree->begin();
  make_tree(home_dir + LIB_PATH_HOME );
  make_tree(LIB_PATH_SHARE);
  _tree->end();

  add(_tree);

  _ok = new Fl_Return_Button(w()/2-LARG_BUTTON_DEFAULT*3, h()- LARG_BUTTON_DEFAULT, 
			     LARG_BUTTON_DEFAULT*3, LARG_BUTTON_DEFAULT, _("Apply"));
  _ok->callback(lib_dialog_ok_callback);

  _cancel = new Fl_Return_Button(w()/2, h()- LARG_BUTTON_DEFAULT, 
			     LARG_BUTTON_DEFAULT*3, LARG_BUTTON_DEFAULT, _("Cancel"));
  _cancel->callback(lib_dialog_cancel_callback);

  add(_ok);
  add(_cancel);
  end();
  set_modal();
}


lib_dialog::~lib_dialog(){
  //  cout << "Chiamato distruttore lib_dialog" << endl;
  delete _imm;
}

void lib_dialog::make_tree(string pt){
  string home_dir=getenv("HOME");
  DIR* direc=opendir(pt.c_str());

  if(direc==NULL){
    fl_alert(_("Can not open library directory %s"),pt.c_str());
    return;
  }

  dirent* acc;
  struct stat attrb;
  while((acc=readdir(direc))!=NULL){
    string file=pt+"/"+acc->d_name;
    stat(file.c_str(),&attrb);
    if(S_ISDIR(attrb.st_mode) && 
       string(acc->d_name)!="." &&
       string(acc->d_name)!=".."){
      make_tree(file);
    }else if(S_ISREG(attrb.st_mode)){
      std::vector<std::string> match_ext_res;
      s_regmatch("bist$",file,match_ext_res,true);
      if(match_ext_res.size() >0){ 
	_tree->add(file.c_str());
      }
    }
  }
  
}


Fl_Scroll*  lib_dialog::ritorna_scroll(){
  return _grp;
}

immagine*   lib_dialog::ritorna_immagine(){
  return _imm;
}

mol_canvas* lib_dialog::ritorna_mol_canvas(){
  return &_preview;
}

const  string lib_dialog::home_bra=_("home");
const  string lib_dialog::share_bra=_("shared");
const  string lib_dialog::root_bra=_("library");
