/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkKW3DSplineCurvesWidget.h"

#include "vtkCommand.h"
#include "vtkSplineWidget.h"
#include "vtkKWEvent.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"

#include <vtkstd/algorithm>

vtkCxxRevisionMacro(vtkKW3DSplineCurvesWidget, "$Revision: 1.6 $");
vtkStandardNewMacro(vtkKW3DSplineCurvesWidget);

 
//----------------------------------------------------------------------------
vtkKW3DSplineCurvesWidget::vtkKW3DSplineCurvesWidget()
{
  
}

//----------------------------------------------------------------------------
vtkKW3DSplineCurvesWidget::~vtkKW3DSplineCurvesWidget()
{
  SplineCurvesContainer::iterator splineCurve = this->SplineCurves.begin();
  SplineCurvesContainer::iterator endSpline   = this->SplineCurves.end();
  while( splineCurve != endSpline )
    {
    (*splineCurve)->Delete();
    ++splineCurve;
    }

  this->SplineCurves.clear();
}


//----------------------------------------------------------------------------
int vtkKW3DSplineCurvesWidget::AddSplineCurve()
{

  vtkSplineWidget*   splineCurve = vtkSplineWidget::New();

  this->SplineCurves.push_back(splineCurve);

  if( this->Interactor )
    {
    splineCurve->SetInteractor(this->Interactor);  
    splineCurve->SetEnabled(this->Enabled);
    }

  // splineCurve->Delete() -- no delete because the vector has it

  return this->SplineCurves.size() - 1;
}

//----------------------------------------------------------------------------
int vtkKW3DSplineCurvesWidget::AddSplineCurve( double bounds[6] )
{

  vtkSplineWidget*   splineCurve = vtkSplineWidget::New();

  splineCurve->PlaceWidget( bounds[0],
                            bounds[1],
                            bounds[2],
                            bounds[3],
                            bounds[4],
                            bounds[5] );

  this->SplineCurves.push_back(splineCurve);

  if( this->Interactor )
    {
    splineCurve->SetInteractor(this->Interactor);  
    splineCurve->SetEnabled(this->Enabled);
    }

  // splineCurve->Delete() -- no delete because the vector has it

  return this->SplineCurves.size() - 1;
}


//----------------------------------------------------------------------------
void vtkKW3DSplineCurvesWidget::SetEnabled(int enabling)
{
  if ( ! this->Interactor )
    {
    vtkErrorMacro(<<"The interactor must be set prior to enabling/disabling widget");
    return;
    }
  
  if ( enabling ) 
    {
    vtkDebugMacro(<<"Enabling distance widget");
    if ( this->Enabled ) //already enabled, just return
      {
      return;
      }
    
    this->SetCurrentRenderer( 
      this->Interactor->FindPokedRenderer(
        this->Interactor->GetLastEventPosition()[0],
        this->Interactor->GetLastEventPosition()[1]));
    if (this->CurrentRenderer == NULL)
      {
      return;
      }
    
    this->Enabled = 1;

    this->InvokeEvent(vtkCommand::EnableEvent,NULL);
    }
  else //disabling------------------------------------------
    {
    vtkDebugMacro(<<"Disabling 3D Spline Curves widget");
    if ( ! this->Enabled ) //already disabled, just return
      {
      return;
      }
    this->Enabled = 0;

    this->InvokeEvent(vtkCommand::DisableEvent,NULL);
    }

  // Propagate Enabling/Disabling to all the existing spline curves
  SplineCurvesContainer::iterator splineCurve = this->SplineCurves.begin();
  SplineCurvesContainer::iterator endSpline   = this->SplineCurves.end();
  while( splineCurve != endSpline )
    {
    (*splineCurve)->SetEnabled(this->Enabled);
    ++splineCurve;
    }

  this->Interactor->Render();
}


//----------------------------------------------------------------------------
unsigned int vtkKW3DSplineCurvesWidget::GetNumberOfSplineCurves()
{
  return (unsigned int)this->SplineCurves.size();
}

//----------------------------------------------------------------------------
void vtkKW3DSplineCurvesWidget::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "Number of Spline Curves: " << this->GetNumberOfSplineCurves() << endl;
}
