bool Interactor2DNavigate::ProcessMouseDownEvent( QMouseEvent* event, RenderView* renderview )
{
  if (m_nCurrentLandmark < 0)
    return Interactor2D::ProcessMouseDownEvent(event, renderview);

  RenderView2D* view = ( RenderView2D* )renderview;

  if ( event->button() == Qt::LeftButton )
  {
    if ( event->modifiers() & CONTROL_MODIFIER && event->modifiers() & Qt::ShiftModifier )
    {
      return Interactor2D::ProcessMouseDownEvent( event, renderview );
    }

    LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer("Landmarks");
    if ( !landmarks )
    {
      emit Error( "Landmarks non-exist", landmarks );
    }
    else
    {
      m_bEditing = true;
      double pos[3];
      view->MousePositionToRAS( event->x(), event->y(), pos );
      landmarks->SetLandmarkPosition(m_nCurrentLandmark, pos);
    }

    return false;
  }
  else
  {
    return Interactor2D::ProcessMouseDownEvent( event, renderview );  // pass down the event
  }
}
void DialogTransformVolume::closeEvent(QCloseEvent *e)
{
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()
                              ->GetSupplementLayer("Landmarks");
  if (landmarks)
    landmarks->SetVisible(false);
  QDialog::closeEvent(e);
}
void DialogTransformVolume::OnActiveLayerChanged()
{
  if ( isVisible() )
  {
    UpdateUI();
  }
  LayerMRI* layer = (LayerMRI* )MainWindow::GetMainWindow()->GetActiveLayer( "MRI" );
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer( "Landmarks" );
  landmarks->SetMRIRef(layer);
  OnSampleMethodChanged();
}
void DialogTransformVolume::OnRestore()
{
  LayerMRI* layer = ( LayerMRI* )MainWindow::GetMainWindow()->GetActiveLayer( "MRI" );
  if ( layer )
  {
    layer->Restore();
    UpdateUI();
  }
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer("Landmarks");
  landmarks->Restore();
}
void DialogTransformVolume::OnRadioButtonLandmark(bool bChecked)
{
  if (!bChecked)
  {
    for (int i = 0; i < m_btnPickLandmark.size(); i++)
      this->m_btnPickLandmark[i]->setChecked(false);
  }
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()
                              ->GetSupplementLayer("Landmarks");
  if (landmarks)
    landmarks->SetVisible(bChecked);
}
void DialogTransformVolume::OnActiveLayerChanged()
{
  if ( isVisible() )
  {
    UpdateUI();
  }
  LayerMRI* layer = (LayerMRI* )MainWindow::GetMainWindow()->GetActiveLayer( "MRI" );
  if (!layer)
    return;
  connect(layer->GetProperty(), SIGNAL(ColorMapChanged()), this, SLOT(OnActiveLayerChanged()), Qt::UniqueConnection);
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer( "Landmarks" );
  landmarks->SetMRIRef(layer);
  if (layer->GetProperty()->GetColorMap() == LayerPropertyMRI::LUT)
    ui->radioButtonNearestNeighbor->setChecked(true);
  else
    ui->radioButtonCubic->setChecked(true);
  OnSampleMethodChanged();
}
bool Interactor2DNavigate::ProcessMouseMoveEvent( QMouseEvent* event, RenderView* renderview )
{
  RenderView2D* view = ( RenderView2D* )renderview;
  if ( m_bEditing && m_nCurrentLandmark >= 0 )
  {
    UpdateCursor( event, view );
    LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer("Landmarks");
    if ( landmarks )
    {
      double pos[3];
      view->MousePositionToRAS( event->x(), event->y(), pos );
      landmarks->SetLandmarkPosition(m_nCurrentLandmark, pos);
    }
    return false;
  }
  else
  {
    return Interactor2D::ProcessMouseMoveEvent( event, renderview );
  }
}
void DialogTransformVolume::UpdateLandmarkColors()
{
  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()
                              ->GetSupplementLayer("Landmarks");
  for (int i = 0; i < m_colorPickerLandmark.size(); i++)
  {
    if (qobject_cast<QtColorPicker*>(sender()) == m_colorPickerLandmark[i])
    {
      landmarks->SetLandmarkColor(i, m_colorPickerLandmark[i]->currentColor());
      break;
    }
  }
  QList<QColor> colors;
  for (int i = 0; i < m_colorPickerLandmark.size(); i++)
    colors << landmarks->GetLandmark(i).color;
  foreach (QComboBox* cbox, m_comboLandmark)
  {
    for (int i = 0; i < m_colorPickerLandmark.size(); i++)
      cbox->setItemIcon(i, MakeIcon(colors[i], 12));
  }
}
DialogTransformVolume::DialogTransformVolume(QWidget *parent) :
  QDialog(parent),
  UIUpdateHelper(),
  ui(new Ui::DialogTransformVolume)
{
  ui->setupUi(this);
  ui->groupBoxLandmarks->hide();
  ui->pushButtonApply->hide();

  QButtonGroup* bg = new QButtonGroup(this);
  bg->addButton(ui->radioButtonRotateLandmarks);
  bg->addButton(ui->radioButtonRotateManual);
  bg->setExclusive(true);

  m_checkRotate[0] = ui->checkBoxRotateX;
  m_checkRotate[1] = ui->checkBoxRotateY;
  m_checkRotate[2] = ui->checkBoxRotateZ;
  m_comboRotate[0] = ui->comboBoxRotateX;
  m_comboRotate[1] = ui->comboBoxRotateY;
  m_comboRotate[2] = ui->comboBoxRotateZ;
  m_sliderRotate[0] = ui->horizontalSliderRotateX;
  m_sliderRotate[1] = ui->horizontalSliderRotateY;
  m_sliderRotate[2] = ui->horizontalSliderRotateZ;
  m_textAngle[0] = ui->lineEditRotateX;
  m_textAngle[1] = ui->lineEditRotateY;
  m_textAngle[2] = ui->lineEditRotateZ;
  m_scrollTranslate[0] = ui->scrollBarTranslateX;
  m_scrollTranslate[1] = ui->scrollBarTranslateY;
  m_scrollTranslate[2] = ui->scrollBarTranslateZ;
  m_textTranslate[0] = ui->lineEditTranslateX;
  m_textTranslate[1] = ui->lineEditTranslateY;
  m_textTranslate[2] = ui->lineEditTranslateZ;
  m_scrollScale[0] = ui->scrollBarScaleX;
  m_scrollScale[1] = ui->scrollBarScaleY;
  m_scrollScale[2] = ui->scrollBarScaleZ;
  m_textScale[0] = ui->lineEditScaleX;
  m_textScale[1] = ui->lineEditScaleY;
  m_textScale[2] = ui->lineEditScaleZ;
  m_btnPickLandmark << ui->pushButtonLandmarkPick1
                    << ui->pushButtonLandmarkPick2
                    << ui->pushButtonLandmarkPick3
                    << ui->pushButtonLandmarkPick4;
  m_colorPickerLandmark << ui->colorPickerLandmark1
                        << ui->colorPickerLandmark2
                        << ui->colorPickerLandmark3
                        << ui->colorPickerLandmark4;
  m_comboLandmark << ui->comboBoxAxis11
                  << ui->comboBoxAxis12
                  << ui->comboBoxAxis21
                  << ui->comboBoxAxis22;

  for (int i = 0; i < 3; i++)
  {
    m_checkRotate[i]->hide();
    m_comboRotate[i]->hide();
  }

  connect(MainWindow::GetMainWindow()->GetLayerCollection("MRI"), SIGNAL(ActiveLayerChanged(Layer*)),
          this, SLOT(OnActiveLayerChanged()));
  connect(ui->pushButtonSaveVolumeAs, SIGNAL(clicked()),
          MainWindow::GetMainWindow(), SLOT(SaveVolumeAs()));

  LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()
                              ->GetSupplementLayer("Landmarks");
  landmarks->SetLandmarkColor(0, Qt::red);
  landmarks->SetLandmarkColor(1, Qt::green);
  landmarks->SetLandmarkColor(2, Qt::blue);
  landmarks->SetLandmarkColor(3, Qt::yellow);
  for (int i = 0; i < m_colorPickerLandmark.size(); i++)
    m_colorPickerLandmark[i]->setCurrentColor(landmarks->GetLandmark(i).color);
  UpdateLandmarkColors();
}
void DialogTransformVolume::DoRotate()
{
  LayerMRI* layer = ( LayerMRI* )MainWindow::GetMainWindow()->GetActiveLayer( "MRI" );
  if ( layer )
  {
    std::vector<RotationElement> rotations;
    RotationElement re;
    re.SampleMethod = SAMPLE_TRILINEAR;
    if ( ui->radioButtonNearestNeighbor->isChecked() )
    {
      re.SampleMethod = SAMPLE_NEAREST;
    }
    else if (ui->radioButtonCubic->isChecked())
    {
      re.SampleMethod = SAMPLE_CUBIC_BSPLINE;
    }
    if (ui->radioButtonRotateManual->isChecked())
    {
      if ( ui->radioButtonAroundCursor->isChecked() )
      {
        MainWindow::GetMainWindow()->GetLayerCollection( "MRI" )->
        GetSlicePosition( re.Point );
        layer->RemapPositionToRealRAS( re.Point, re.Point );
      }
      else
      {
        // use center of the volume to rotate
        layer->GetRASCenter( re.Point );
      }
  //    else if ( m_radioSinc->GetValue() )
  //      re.SampleMethod = SAMPLE_SINC;

      for ( int i = 0; i < 3; i++ )
      {
        if ( GetRotation( i, re.Plane, re.Angle ) )
        {
          rotations.push_back( re );
        }
      }
      MainWindow::GetMainWindow()->RotateVolume( rotations, false );
    }
    else
    {
      layer->GetRASCenter( re.Point );
      LayerLandmarks* landmarks = (LayerLandmarks*)MainWindow::GetMainWindow()->GetSupplementLayer("Landmarks");
      double* p[4];
      for (int i = 0; i < 4; i++)
        p[i] = landmarks->GetLandmark(i).pos;

      // first figure out landmark vectors
      double v[3][3], ax[3][3];
      int n0 = ui->comboBoxAxis11->currentIndex();
      int n1 = ui->comboBoxAxis12->currentIndex();
      for (int i = 0; i < 3; i++)
        v[0][i] = p[n1][i] - p[n0][i];
      vtkMath::Normalize(v[0]);

      n0 = ui->comboBoxAxis21->currentIndex();
      n1 = ui->comboBoxAxis22->currentIndex();
      for (int i = 0; i < 3; i++)
        v[1][i] = p[n1][i] - p[n0][i];
      vtkMath::Normalize(v[1]);
      vtkMath::Cross(v[0], v[1], v[2]);
      vtkMath::Normalize(v[2]);
      vtkMath::Cross(v[2], v[0], v[1]);

      int n[3];
      n[0] = ui->comboBoxAxisTarget1->currentIndex();
      n[1] = ui->comboBoxAxisTarget2->currentIndex();
      if (n[0] == 0)
        n[2] = (n[1] == 1 ? 2 : 1);
      else if (n[0] == 1)
        n[2] = (n[1] == 0 ? 2 : 0);
      else
        n[2] = (n[1] == 0 ? 1 : 0);

      for (int i = 0; i < 3; i++)
      {
        for (int j = 0; j < 3; j++)
          ax[n[i]][j] = v[i][j];
      }

      double m[16];
      memset(m, 0, sizeof(double)*16);
      for (int i = 0; i < 16; i++)
      {
        if (i/4 < 3 && i%4 < 3)
          m[i] = ax[i/4][i%4];
      }
      m[15] = 1;

      vtkSmartPointer<vtkTransform> tf = vtkSmartPointer<vtkTransform>::New();
      tf->Identity();
      double pt[3];
      layer->RASToTarget( re.Point, pt );
      tf->Translate(pt[0], pt[1], pt[2]);
      tf->Concatenate(m);
      tf->Translate(-pt[0], -pt[1], -pt[2]);
      vtkMatrix4x4::DeepCopy(m, tf->GetMatrix());
      MainWindow::GetMainWindow()->TransformVolume(m, re.SampleMethod);
    }
  }
}