/*
    Bist: a chemical drawing tool
    Copyright (C) 2010 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 <wordexp.h>
#include <sys/stat.h>
#include <dirent.h>
#include <cerrno>
//portability problem?
#include <pthread.h>

#include <cstdio>


#include <FL/Fl.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Scroll.H>
#include <FL/fl_ask.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_Light_Button.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Help_Dialog.H>
#include <FL/Fl_Check_Button.H>
//#include <FL/Fl_PNG_Image.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 <finestra_pr.hpp>
#include <editor.hpp>

#include <prefs.hpp>

#include <set_conf.hpp>
#include <command_line.hpp>
#include <2D_vector.hpp>

#include <util.hpp>


#include <change_layer.hpp>
#include <change_layer_dialog.hpp>



typedef immagine Image;

extern finestra_pr* MainWindow;

extern Preferences  __pref;

extern bool __close;





ChangeLayer::ChangeLayer(immagine* image,string libpath)
  :bist_plugin(image,libpath),
   _has_to_act(true),
   _has_acted(false)
{

}


void ChangeLayer::inizialize(){
  
  ChangeLayerDialog dialog_ch(this);

  while(dialog_ch.shown()){
    Fl::wait();
  }

  _has_to_act=false;
}



bool ChangeLayer::need_atom(){
  return false;
}

bool ChangeLayer::need_leg(){
  return false;
}

bool ChangeLayer::act(int e){

  return _has_to_act;
}


ChangeLayer::~ChangeLayer(){


}

void ChangeLayer::register_plugin(){

}


bool ChangeLayer::time_to_act(){
  return _has_to_act;
}


string ChangeLayer::libpath(){
  return _lib;
}



std::string ChangeLayer::menu_path(){
  return "align and distribuite/";
}


void ChangeLayer::push_down(bool go_background){
  vector< pair < int, pair<int,int> > >* elem=r_elem_selected();
  vector <gruppo>* gruppi=r_groups();

  for(unsigned int i=0;i<gruppi->size();i++){
    if((*gruppi)[i].id_gruppo()==((*elem)[0].second).first &&  i>0 ){
      unsigned int fst=i-1;
      unsigned int second=i;

      if(go_background){
        (*gruppi)[second].id(-1);
        for(unsigned int i2=0;i2<gruppi->size();i2++){
          (*gruppi)[i2].id((*gruppi)[i2].id()+1);
        }
        std::sort(gruppi->begin(),gruppi->end(),ordina_gruppo_id);
        gruppo* found=_the_image->find_group_id(0);
        _the_image->elimina_elem_selected();
        
        if(found){
          _the_image->aggiungi_tutto_selected(*found);
          break;
        }

      }else{
        int bkid=(*gruppi)[fst].id();
        (*gruppi)[fst].id((*gruppi)[second].id());
        (*gruppi)[second].id(bkid);
        std::sort(gruppi->begin(),gruppi->end(),ordina_gruppo_id);
        gruppo* found=_the_image->find_group_id(bkid);
        _the_image->elimina_elem_selected();
        
        if(found){
          _the_image->aggiungi_tutto_selected(*found);
          break;
        }
      }
    }
  }
}


void ChangeLayer::push_up(bool go_foreground){
  vector< pair < int, pair<int,int> > >* elem=r_elem_selected();

  vector <gruppo>* gruppi=r_groups();


  for(unsigned int i=0;i< gruppi->size() -1 ;i++){
    if((*gruppi)[i].id_gruppo()==((*elem)[0].second).first){

      unsigned int fst=i+1;
      unsigned int second=i;

      if(go_foreground){
        (*gruppi)[second].id((*gruppi)[gruppi->size() -1].id()+1);
        
        std::sort(gruppi->begin(),gruppi->end(),ordina_gruppo_id);
        for(unsigned int i2=0;i2<gruppi->size();i2++){ //remove "holes"
          (*gruppi)[i2].id((*gruppi)[i2].id()+1);
        }
        std::sort(gruppi->begin(),gruppi->end(),ordina_gruppo_id);
        break;
      }else{

        int bkid=(*gruppi)[fst].id();
        (*gruppi)[fst].id((*gruppi)[i].id());
        (*gruppi)[second].id(bkid);
        std::sort(gruppi->begin(),gruppi->end(),ordina_gruppo_id);
        gruppo* found=_the_image->find_group_id(bkid);
        _the_image->elimina_elem_selected();
        
        if(found){
          _the_image->aggiungi_tutto_selected(*found);
          if(!go_foreground){
            break;
          }
        }
      }
    }
  }
}


extern "C" bist_plugin* create_plugin(immagine* imm, string libpath){
  return new ChangeLayer(imm, libpath);
}

extern "C" void destroy_plugin(bist_plugin* j){
  delete j;
}


