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

  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 "vtkDICOMReader.h"
#include "vtkImageData.h"
#include "vtkExecutive.h"
#include "vtkDICOMCollector.h"
#include "vtkDICOMCollectorOptions.h"
#include "vtkXMLImageDataWriter.h"
#include "vtkStructuredPointsWriter.h"

#include <vtksys/ios/sstream>

#include "vtkKWCommonProBuildConfigure.h" // for VolView_DATA_ROOT

static const char *vtkKWCommonProStrings[] = {
// "/Data/ComputedRadiography/CR0003",
 "/Data/CTTherapyAccess/ChestWContrast-GELightSpeed16/9999.9999.5.dcm",
 "/Data/IHE-PDI-DICOM/PHILIPS/070801A/20010807/9584406/00000004",
// "/Data/Mammography/MG01",
 "/Data/Osirix/Cardiac 1CTA_CORONARY_ARTERIES_TESTBOLUS (Adult)/Chest Topo  0.6  T20s/IM-0001-0001.dcm",
  NULL
};

static double vtkKWCommonProRange[][2] = {
//    {     1, 3949},
    {  -554,  553},
    {     1,  204},
//    {     0, 4095},
    { -1024,  320}
};

int TestOneDICOM(const char *filename, double refrange[2], bool debug)
{
  cerr << "Processing: " << filename << endl;
  vtkDICOMReader* reader = vtkDICOMReader::New();
  reader->SetFileName( filename );
  reader->GetDICOMCollector()->GetOptions()->ExploreDirectoryOff();
  //reader->Update();
  vtkExecutive *exe = reader->GetExecutive();
  int r = exe->Update();
  if( !r )
    {
    cerr << "Could not call Update() on: " << filename << endl;
    cerr << "Failure was: " << reader->GetDICOMCollector()->GetFailureStatus() << endl;
    return 1;
    }
  if( reader->GetNumberOfOutputPorts() != 1 )
    {
    cerr << "Wrong number of output ports" << endl;
    return 1;
    }

  int n = reader->GetDICOMCollector()->GetNumberOfCollectedSlices();
  if( n != 1 )
    {
    cerr << "Wrong number of collected slices: " << n << endl;
    return 1;
    }
  for(int i = 0; i < n; ++i)
    {
    const char *fn = reader->GetDICOMCollector()->GetSliceFileName(i);
    cerr << i << ":" << fn << endl;
    }

  if( debug )
    {
    reader->GetOutput()->Print( std::cout );
    }
  double *range = reader->GetOutput()->GetScalarRange();
  cout << "Range: " << range[0] << " " << range[1] << endl;
  if( refrange && (range[0] != refrange[0] || range[1] != refrange[1]) )
    {
    cerr << "Problem with range:" << refrange[0] << " " << refrange[1] << endl;
    return 1;
    }

  if( debug )
    {
    //vtkStructuredPointsWriter *writer = vtkStructuredPointsWriter::New();
    vtkXMLImageDataWriter *writer = vtkXMLImageDataWriter::New();
    writer->SetInput( reader->GetOutput() );
    writer->SetFileName( "/tmp/vol.vti" );
    writer->Write();

    std::cerr << "Numberofvolumes=" << reader->GetNumberOfOutputPorts() << std::endl;
    for(int v = 0; v < reader->GetNumberOfOutputPorts(); ++v)
      {
      writer->SetInput( reader->GetOutput(v) );
      std::stringstream ss;
      ss << "/tmp/output";
      ss << v;
      ss << ".vti";
      writer->SetFileName( ss.str().c_str() );
      writer->Write();
      }
    writer->Delete();
    }

  reader->Delete();
  return 0;
}

int main(int argc, char *argv[])
{
  // Special entry point for developers, you can pass in an argument:
  if (argc == 2 )
    {
    return TestOneDICOM( argv[1], NULL, true );
    }

  // else loop over all filenames:
  const unsigned int n = sizeof(vtkKWCommonProStrings)/sizeof(vtkKWCommonProStrings[0]) - 1;
  const unsigned int nrange = sizeof(vtkKWCommonProRange)/sizeof(vtkKWCommonProRange[0]);
  if( nrange != n )
    {
    cerr << "Test can not run" << endl;
    return 1;
    }
  int r = 0;
  for(unsigned int i=0; i<n; ++i)
    {
    std::string filename = VolView_DATA_ROOT;
    filename += vtkKWCommonProStrings[i];
    r += TestOneDICOM( filename.c_str(), vtkKWCommonProRange[i], false );
    }

  return r;
}

