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

  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.

=========================================================================*/
// Test functionality of the vtkCMBArc Creation.
// Will test adding arcs to the manager
// Will Test undo / redoing an arc
// Will test doing a merge on an end node that is part of a arc that
// is on the undo stack

#include "vtkCMBArc.h"
#include "vtkCMBArcEndNode.h"
#include "vtkCMBArcManager.h"

#include "vtkTesting.h"

int ArcServerUndoTest( int /*argc*/, char * /*argv*/[] )
{
  double en1[3]={0,0,0};
  double en2[3]={10,1,0};
  double en3[3]={2,2,0};


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

  arc->InsertNextPoint( 1, 0, 0 );
  arc->InsertNextPoint( 4, 0, 0 );
  arc->InsertNextPoint( 8, 0.5, 0 );
  arc->InsertNextPoint( 9, 1, 0 );

  vtkCMBArc *arc2 = vtkCMBArc::New();
  arc2->SetEndNode(0,en1);

  arc2->InsertNextPoint( -1, 0, 0 );
  arc2->InsertNextPoint( -4, 0, 0 );
  arc2->InsertNextPoint( -8, -0.5, 0 );
  arc2->InsertNextPoint( -9, -1, 0 );

  vtkCMBArc *loopArc = vtkCMBArc::New();
  loopArc->SetEndNode(0,en3);
  loopArc->SetEndNode(1,en3);
  loopArc->InsertNextPoint( 0, 2, 0 );
  loopArc->InsertNextPoint( -2, 0, 0 );


  vtkCMBArcManager *manager = vtkCMBArcManager::GetInstance();
  //make sure the manager info is all valid
  if ( 3 !=  manager->GetNumberOfArcs() )
    {
    //isn't tracking all the arcs
    return 1;
    }

  arc->MarkedForDeletion();
  if ( 2 != manager->GetNumberOfArcs() )
    {
    return 1;
    }

  //make sure the id of arc is an invalid id to get back from the manager
  if ( NULL != manager->GetArc( arc->GetId() ) )
    {
    return 1;
    }

  //undo the undo
  arc->UnMarkedForDeletion();
  if ( NULL == manager->GetArc( arc->GetId() ) )
    {
    return 1;
    }
  if ( 2 == manager->GetNumberOfArcs() )
    {
    return 1;
    }

  //next step is a byte more complicated. We remove arc1, than
  //we move arc3 endnode to be the same place as arc1 end node 2 was at.
  //when we undo the delete on arc1 we need to make sure it uses the same
  //endnode as arc3
  arc->MarkedForDeletion();
  loopArc->MoveEndNode(0,en2);
  arc->UnMarkedForDeletion();

  if ( arc->GetEndNode(1) != loopArc->GetEndNode(0) )
    {
    return 1;
    }
  if ( arc->GetEndNode(1) != loopArc->GetEndNode(1) )
    {
    return 1;
    }
  if ( arc->GetEndNode(0) != arc2->GetEndNode(0) )
    {
    return 1;
    }

  vtkCMBArcEndNode* en = loopArc->GetEndNode(0);
  if ( manager->GetConnectedArcs(en).size() != 2 )
    {
    return 1;
    }
  if ( manager->GetConnectedArcs( loopArc ).size() != 1 ||
       loopArc->GetNumberOfConnectedArcs() != 1)
    {
    return 1;
    }
  if ( manager->GetConnectedArcs( arc ).size() != 2 )
    {
    return 1;
    }

  en = arc->GetEndNode(0);
  if ( manager->GetConnectedArcs( en ).size() != 2 )
    {
    return 1;
    }

  en = arc->GetEndNode(1);
  if ( manager->GetConnectedArcs( en ).size() != 2 )
    {
    return 1;
    }

  loopArc->MarkedForDeletion();
  arc->MarkedForDeletion();
  arc2->MarkedForDeletion();

  return 0;
}
