#include "geoedit.h"
#include "geoeditview.h"

#include <odinqt/boolbutton.h>


GeoEditView::GeoEditView(Geometry& geometry, ImageSet& pilot, unsigned int blowup, QWidget *parent)
 : QWidget(parent), geometry_cache(geometry), pilot_cache(pilot) {
  Log<GeoEditComp> odinlog("GeoEditView","GeoEditView(...)");

  old_mode=n_geometry_modes; // invalid value to trigger generation of first widget
  for(int imode=0; imode<n_geometry_modes; imode++) blockwidget[imode]=0;

  int nimages=pilot.get_numof_images();

  ODINLOG(odinlog,normalDebug) << "nimages=" << nimages << STD_endl;

  int ncol=2*nimages;
  if(ncol<6) ncol=6;

  grid = new GuiGridLayout( this, 7, ncol );


  // iterate over 3D volume images in set and display each in a separate widget
  for(int i=0; i<nimages; i++) {

    Image& img=pilot.get_image(i);

    int nx=img.size(xAxis);
    int ny=img.size(yAxis);
    ODINLOG(odinlog,normalDebug) << "nx/ny=" << nx << "/" << ny << STD_endl;

    coarse=1;

    if(nx*ny>0) {

      coarse=(unsigned int)secureDivision(MIN_MATRIX_SIZE,(nx+ny)/2);
      if(!coarse) coarse=1;

      ODINLOG(odinlog,normalDebug) << "coarse[" << i<< "]=" << coarse << STD_endl;

      img.normalize_magnitude();

      GeoEditLabel* imglabel=new GeoEditLabel(img,coarse*blowup,this);
      if(i==0) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify0(int,int,int)));
      if(i==1) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify1(int,int,int)));
      if(i==2) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify2(int,int,int)));

      grid->add_widget( imglabel, 0, 2*i, GuiGridLayout::Center, 1,2);

      labels.push_back(imglabel);
    }

  }



  /* ------------ draw projection button -----------------*/
   projection=new buttonBox("Hide","Show",true, this, "Projection" );
   grid->add_widget( projection, 1,5, GuiGridLayout::Center);
   connect(projection,SIGNAL(buttonToggled(bool)),this,SLOT( setProjection(bool)));

  /* ------------ draw cross section button -----------------*/
   crosssect=new buttonBox("Hide","Show",true, this, "CrossSection" );
   grid->add_widget( crosssect, 2,5, GuiGridLayout::Center);
   connect(crosssect,SIGNAL(buttonToggled(bool)),this,SLOT( setCrossSection(bool)));

  /* ------------ set sagittal button -----------------*/
   buttonBox *sagbutton=new buttonBox("Set", this, "Sagittal" );
   grid->add_widget( sagbutton, 3,5, GuiGridLayout::Center);
   connect(sagbutton,SIGNAL(buttonClicked()),this,SLOT( sagSet()));

  /* ------------ set coronal button -----------------*/
   buttonBox *corbutton=new buttonBox("Set", this, "Coronal" );
   grid->add_widget( corbutton, 4,5, GuiGridLayout::Center);
   connect(corbutton,SIGNAL(buttonClicked()),this,SLOT( corSet()));

  /* ------------ set axial button -----------------*/
   buttonBox *axibutton=new buttonBox("Set", this, "Axial" );
   grid->add_widget( axibutton, 5,5, GuiGridLayout::Center);
   connect(axibutton,SIGNAL(buttonClicked()),this,SLOT( axiSet()));


  /* ------------ save & exit button -----------------*/
   buttonBox *saveexit=new buttonBox("Done", this, "Save & Exit" );
   grid->add_widget( saveexit, 6,5, GuiGridLayout::Center);
   connect(saveexit,SIGNAL(buttonClicked()),this,SLOT( emitDone()));

   ODINLOG(odinlog,normalDebug) << "Buttons done" << STD_endl;

   this->showNormal();
   geometryChanged();
}


void GeoEditView::geometryChanged() {
  Log<GeoEditComp> odinlog("GeoEditView","geometryChanged");

  geometry_cache.update();
  ODINLOG(odinlog,normalDebug) << "update done" << STD_endl;

  geometryMode mode=geometry_cache.get_Mode();

  if(old_mode!=mode) {
    if(old_mode!=n_geometry_modes) blockwidget[old_mode]->hide();
    if(blockwidget[mode]==0) blockwidget[mode]=new LDRwidget(geometry_cache,3,this);
    blockwidget[mode]->show();
    grid->add_widget( blockwidget[mode], 1,0, GuiGridLayout::Center, 6,5);
    connect(blockwidget[mode],SIGNAL(valueChanged()),this,SLOT(geometryChanged()));
  }
  blockwidget[mode]->updateWidget();
  old_mode=mode;
  ODINLOG(odinlog,normalDebug) << "LDRwidget done" << STD_endl;

  for(STD_list<GeoEditLabel*>::iterator labelit=labels.begin(); labelit!=labels.end(); ++labelit) {
    (*labelit)->drawImagingArea(geometry_cache,projection->is_on(),crosssect->is_on());
  }
  ODINLOG(odinlog,normalDebug) << "labels->drawImagingArea done" << STD_endl;

}

void GeoEditView::emitDone() {
  emit donePressed();
}


void GeoEditView::sagSet() {
  geometry_cache.set_orientation(sagittal);
  geometryChanged();
}

void GeoEditView::corSet() {
  geometry_cache.set_orientation(coronal);
  geometryChanged();
}

void GeoEditView::axiSet() {
  geometry_cache.set_orientation(axial);
  geometryChanged();
}


void GeoEditView::magnify(int index) {
  Image& img=pilot_cache.get_image(index);

  STD_string tmpdir=STD_string(getenv_nonnull("HOME"))+SEPARATOR_STR+".odin"+SEPARATOR_STR+"tmp"+SEPARATOR_STR;
  createdir(tmpdir.c_str());
  STD_string tmpfname=tmpdir+"image4geo.jdx";
  img.write(tmpfname);
  system(("miview -blowup "+itos(coarse)+" "+tmpfname+" &").c_str());
}

