//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt 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 "vtkAddMeshDataArrayFilter.h"

#include "vtkObjectFactory.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockWrapper.h"

#include "vtkCellData.h"
#include "vtkIdTypeArray.h"
#include "vtkIntArray.h"
#include "vtkDataSet.h"
#include "vtkPointData.h"

vtkStandardNewMacro(vtkAddMeshDataArrayFilter);

//----------------------------------------------------------------------------
vtkAddMeshDataArrayFilter::vtkAddMeshDataArrayFilter()
{
}

//----------------------------------------------------------------------------
vtkAddMeshDataArrayFilter::~vtkAddMeshDataArrayFilter()
{
}

//----------------------------------------------------------------------------
int vtkAddMeshDataArrayFilter::RequestData(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkDataSet *output = vtkDataSet::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  output->ShallowCopy(input);

  vtkCellData *cellData = output->GetCellData();
  vtkIntArray *regionIDs =
    vtkIntArray::SafeDownCast( cellData->GetArray(
       vtkMultiBlockWrapper::GetShellTagName()) );
  if (!regionIDs) // intialize to be a single region
    {
    regionIDs = vtkIntArray::New();
    regionIDs->SetNumberOfComponents(1);
    regionIDs->SetNumberOfTuples( input->GetNumberOfCells() );
    regionIDs->SetName( vtkMultiBlockWrapper::GetShellTagName() );
    for (vtkIdType i = 0; i < regionIDs->GetNumberOfTuples(); i++)
      {
      regionIDs->SetValue(i, 0);
      }
    cellData->AddArray( regionIDs );
    regionIDs->Delete();
    }

  // Get the original "Cell ID" array
  vtkIdTypeArray* meshCellIdArray =vtkIdTypeArray::SafeDownCast(
    input->GetCellData()->GetArray("Mesh Cell ID"));
  if (!meshCellIdArray)
    {
    meshCellIdArray = vtkIdTypeArray::New();
    meshCellIdArray->SetNumberOfComponents(1);
    meshCellIdArray->SetNumberOfTuples( input->GetNumberOfCells() );
    meshCellIdArray->SetName("Mesh Cell ID");
    for (vtkIdType i = 0; i < meshCellIdArray->GetNumberOfTuples(); i++)
      {
      meshCellIdArray->SetValue(i, i);
      }
    cellData->AddArray( meshCellIdArray );
    meshCellIdArray->Delete();
    }

  vtkIdTypeArray* meshNodeIdArray =vtkIdTypeArray::SafeDownCast(
    input->GetPointData()->GetArray("Mesh Node ID"));
  if (!meshNodeIdArray)
    {
    meshNodeIdArray = vtkIdTypeArray::New();
    meshNodeIdArray->SetNumberOfComponents(1);
    meshNodeIdArray->SetNumberOfTuples( input->GetNumberOfPoints() );
    meshNodeIdArray->SetName("Mesh Node ID");
    for (vtkIdType i = 0; i < meshNodeIdArray->GetNumberOfTuples(); i++)
      {
      meshNodeIdArray->SetValue(i, i);
      }
    output->GetPointData()->AddArray( meshNodeIdArray );
    meshNodeIdArray->Delete();
    }

  return 1;
}

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