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

  Program:   Visualization Toolkit
  Module:    cmbContourTest.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.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 "vtkCMBArc.h"
#include "vtkCMBArcManager.h"
#include "vtkCMBArcSplitOnPositionOperator.h"

#include "vtkSmartPointer.h"
#include "vtkTesting.h"

int ArcServerSplitTest3( int /*argc*/, char * /*argv*/[] )
{
  double en1[3]={-50,0,-20};
  double en2[3]={10,10,10};
  double midPos[3] = {-50.0,10.0,-20.0};

  vtkCMBArc *arc = vtkCMBArc::New();
  arc->SetEndNode(0,en1);
  arc->SetEndNode(1,en2);

  //attempt to split an arc with no internal points
  vtkSmartPointer<vtkCMBArcSplitOnPositionOperator> splitPosition =
      vtkSmartPointer<vtkCMBArcSplitOnPositionOperator>::New();

  //now add multiple internal point
  arc->InsertNextPoint(-50,2.5,-20);
  arc->InsertNextPoint(-50,5,-20);
  arc->InsertNextPoint(-50,7.5,-20);
  arc->InsertNextPoint(midPos); //Split Here
  arc->InsertNextPoint(-40,10,-20);
  arc->InsertNextPoint(-30,10,-20);
  arc->InsertNextPoint(-20,10,-20);
  arc->InsertNextPoint(-10,10,-20);
  arc->InsertNextPoint(0,10,0);
  arc->InsertNextPoint(10,10,10);

  //attempt a bad positional split
  splitPosition->SetPositionTolerance(0.0);
  splitPosition->SetSplitPosition(-50,9.9,-20);
  if (splitPosition->Operate(arc->GetId()))
    {
    cerr << "Split on -50,9.9,-20 with tol of 0.0 which is wrong" << endl;
    return 1;
    }

  //now lets split!
  splitPosition->SetPositionTolerance(0.5);

  if (!splitPosition->Operate(arc->GetId()))
    {
    cerr << "failed to split on -50,9.9,-20  with tol of 0.5 internal point" << endl;
    return 1;
    }
  vtkIdType newArcId = splitPosition->GetCreatedArcId();
  vtkCMBArc *newArc = vtkCMBArcManager::GetInstance()->GetArc(newArcId);
  if (!newArc)
    {
    cerr << "The arc Id returned by the split on index operation is an invalid id";
    return 1;
    }

  //validate that the new and old arc have no internal points
  if (arc->GetNumberOfInternalPoints() != 3 )
    {
    cerr << "After split the original arc can't have internal points" << endl;
    return 1;
    }
  if (newArc->GetNumberOfInternalPoints() != 6 )
    {
    cerr << "After split the new arc can't have internal points" << endl;
    return 1;
    }

  //lets make sure the arcs are properly connected
  if (arc->GetNumberOfConnectedArcs() != 1)
    {
    cerr << "Original arc should be connected only to the new arc" << endl;
    return 1;
    }
  if (newArc->GetNumberOfConnectedArcs() != 1)
    {
    cerr << "New arc should be connected only to the original arc" << endl;
    return 1;
    }

  vtkCMBArcEndNode* en = vtkCMBArcManager::GetInstance()->GetEndNodeAt(midPos);
  if (arc->GetEndNode(1) != en)
    {
    cerr << "Original Arc end node 1 is at wrong position" << endl;
    return 1;
    }
  if (newArc->GetEndNode(0) != en)
    {
    cerr << "new Arc end node 0 is at wrong position" << endl;
    return 1;
    }

  en = vtkCMBArcManager::GetInstance()->GetEndNodeAt(en2);
  if (newArc->GetEndNode(1) != en)
    {
    cerr << "new Arc end node 1 is at wrong position" << endl;
    return 1;
    }



  return 0;
}
