#include "itkImage.h"
#include "itkImageFileWriter.h"

int main (int argc, char *argv[])
{

  if (argc < 2) {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << "  outputImageFile" << std::endl;
    return 1;
  }

  const unsigned int Dimension = 3;

  //  typedef unsigned char   PixelType;
  //  typedef unsigned int    PixelType;
  //  typedef short          PixelType;
  typedef float PixelType;

  typedef itk::Image < PixelType, Dimension > ImageType;

  ImageType::Pointer image = ImageType::New ();

  // The image region should be initialized
  ImageType::IndexType start;
  ImageType::SizeType size;

  size[0] = 1340;               // size along X
  size[1] = 1300;               // size along Y
  size[2] = 720;                // size along Z

  start[0] = 0;                 // first index on X
  start[1] = 0;                 // first index on Y
  start[2] = 0;                 // first index on Z

  ImageType::RegionType region;
  region.SetSize (size);
  region.SetIndex (start);

  // Pixel data is allocated
  std::cout << "allocating " << std::endl;
  image->SetRegions (region);
  image->Allocate ();

  std::cout << "initializing " << std::endl;
  // The image buffer is initialized to a particular value
  ImageType::PixelType initialValue = 100;
  image->FillBuffer (initialValue);

  ImageType::IndexType pixelIndex;
  ImageType::IndexType initialPixelIndex;
  ImageType::PixelType pixelValue = 1000;

  initialPixelIndex[0] = 670;   // x position
  initialPixelIndex[1] = 650;   // y position
  initialPixelIndex[2] = 0;     // z position

  std::cout << std::endl;
  std::cout << "pixelIndex = " << pixelIndex << std::endl;
  std::cout << std::endl;

  // Lets draw two cubes 100x100x100 with intensity I=1000; // Before the critical boundary pixelIndex[2]=104 and after.

  std::cout << "drawing first cube " << std::endl;
  for (int i = 0; i < 100; i++) {
    pixelIndex[0] = initialPixelIndex[0] + i;
    for (int j = 0; j < 100; j++) {
      pixelIndex[1] = initialPixelIndex[1] + j;
      for (int k = 0; k < 100; k++) {
        pixelIndex[2] = initialPixelIndex[2] + k;
        image->SetPixel (pixelIndex, pixelValue);
        //              std::cout << "pixelIndex = " << pixelIndex << std::endl;
        //              std::cout << "pixelValue = " << image->GetPixel( pixelIndex) << std::endl;
      }
    }
  }

  initialPixelIndex[0] = 670;   // x position
  initialPixelIndex[1] = 650;   // y position
  initialPixelIndex[2] = 360;   // z position

  std::cout << "drawing second cube " << std::endl;
  for (int i = 0; i < 100; i++) {
    pixelIndex[0] = initialPixelIndex[0] + i;
    for (int j = 0; j < 100; j++) {
      pixelIndex[1] = initialPixelIndex[1] + j;
      for (int k = 0; k < 100; k++) {
        pixelIndex[2] = initialPixelIndex[2] + k;
        image->SetPixel (pixelIndex, pixelValue);
        //              std::cout << "pixelIndex = " << pixelIndex << std::endl;
        //              std::cout << "pixelValue = " << image->GetPixel( pixelIndex) << std::endl;
      }
    }
  }

  typedef itk::ImageFileWriter < ImageType > WriterType;

  WriterType::Pointer writer = WriterType::New ();

  writer->SetFileName (argv[1]);
  writer->SetInput (image);

  std::cout << "updating writer " << std::endl;
  try {
    writer->Update ();
  }
  catch (itk::ExceptionObject & exp) {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << exp << std::endl;
  }

  return EXIT_SUCCESS;
}
