#include "vtkJHTDBReader.h"

#include <vtkActor2D.h>
#include <vtkImageData.h>
#include <vtkImageMapper.h>
#include <vtkInteractorStyleImage.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkSimplePointsReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkXMLImageDataWriter.h>
#include <vtkXMLImageDataReader.h>
#include <vtkImageDataGeometryFilter.h>

#using <System.dll>
#using <System.Data.dll>

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Text;
using namespace System::Data;
using namespace System::Data::SqlClient;
using namespace System::Collections;

void PrintImage(vtkImageData* image);

int main(int argc, char* argv[])
{
  // Verify input arguments
	if ( argc != 2 )
	{
		std::cout << "Usage: " << argv[0] 
			<< " Filename(.xyz)" << std::endl;
			return EXIT_FAILURE;
	}

	// Read the file
	vtkSmartPointer<vtkJHTDBReader> reader =
		vtkSmartPointer<vtkJHTDBReader>::New();
	reader->SetFileName ( argv[1] );
	reader->Update();
	
	//TODO: Figure out how to set the extent. 

	vtkImageData* output = reader->GetOutput();
	
	PrintImage(output);
 
	vtkSmartPointer<vtkXMLImageDataWriter> writer =
	vtkSmartPointer<vtkXMLImageDataWriter>::New();
	writer->SetFileName("C:\\Documents and Settings\\Kalin Kanov\\My Documents\\Research\\JHTDBReader\\test.vti");
	writer->SetInputData(output);
	//writer->SetInputConnection(reader->GetOutputPort());
	writer->Write();

	//// Read the file (to test that it was written correctly)
	//vtkSmartPointer<vtkXMLImageDataReader> image_reader =
	//vtkSmartPointer<vtkXMLImageDataReader>::New();
	//image_reader->SetFileName("C:\\Users\\kalin\\Documents\\JHTDBReader\\build\\Debug\\test.vti");
	//image_reader->Update();
 
	// Convert the image to a polydata
	vtkSmartPointer<vtkImageDataGeometryFilter> imageDataGeometryFilter =
	vtkSmartPointer<vtkImageDataGeometryFilter>::New();
	imageDataGeometryFilter->SetInputConnection(reader->GetOutputPort());
	imageDataGeometryFilter->Update();
 
	vtkSmartPointer<vtkPolyDataMapper> mapper =
	vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(imageDataGeometryFilter->GetOutputPort());
 
	vtkSmartPointer<vtkActor> actor =
	vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);
	actor->GetProperty()->SetPointSize(3);
 
	// Setup rendering
	vtkSmartPointer<vtkRenderer> renderer =
	vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(actor);
	renderer->SetBackground(1,1,1);
	renderer->ResetCamera();
 
	vtkSmartPointer<vtkRenderWindow> renderWindow =
	vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
 
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
	vtkSmartPointer<vtkRenderWindowInteractor>::New();
 
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	//// Visualize
	//vtkSmartPointer<vtkImageMapper> imageMapper = vtkSmartPointer<vtkImageMapper>::New();
	//imageMapper->SetInputData(output);
	//imageMapper->SetColorWindow(255);
	//imageMapper->SetColorLevel(127.5);

	//vtkSmartPointer<vtkActor2D> imageActor = vtkSmartPointer<vtkActor2D>::New();
	//imageActor->SetMapper(imageMapper);
	//imageActor->SetPosition(20, 20);

	//// Setup renderers
	//vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
 //
	//// Setup render window
	//vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
 //
	//renderWindow->AddRenderer(renderer);
 //
	//// Setup render window interactor
	//vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
 //
	//vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
 //
	//renderWindowInteractor->SetInteractorStyle(style);
 //
	//// Render and start interaction
	//renderWindowInteractor->SetRenderWindow(renderWindow);
 //
	////renderer->AddViewProp(imageActor);
	//renderer->AddActor2D(imageActor);
 //
	//renderWindow->Render();
	//renderWindowInteractor->Start();

	//// Visualize
	//vtkSmartPointer<vtkPolyDataMapper> mapper =
	//	vtkSmartPointer<vtkPolyDataMapper>::New();
	//mapper->SetInputConnection(reader->GetOutputPort());

	//vtkSmartPointer<vtkActor> actor =
	//	vtkSmartPointer<vtkActor>::New();
	//actor->SetMapper(mapper);
	//actor->GetProperty()->SetPointSize(4);

	//vtkSmartPointer<vtkRenderer> renderer =
	//	vtkSmartPointer<vtkRenderer>::New();
	//vtkSmartPointer<vtkRenderWindow> renderWindow =
	//	vtkSmartPointer<vtkRenderWindow>::New();
	//renderWindow->AddRenderer(renderer);
	//vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
	//	vtkSmartPointer<vtkRenderWindowInteractor>::New();
	//renderWindowInteractor->SetRenderWindow(renderWindow);

	//renderer->AddActor(actor);
	//renderer->SetBackground(.3, .6, .3); // Background color green

	//renderWindow->Render();
	//renderWindowInteractor->Start();
  
 //   SqlConnection ^ sqlcon = gcnew SqlConnection("Server=localhost;Database=turbdev;Integrated Security=True;");
 //   sqlcon->Open();
	//if (sqlcon->State == ConnectionState::Open)
	//	cerr << "SQLServerClient: connected to database" << endl;
	//else
	//	cerr << "SQLServerClient: error connecting to database " << endl;

  return EXIT_SUCCESS;
}

void PrintImage(vtkImageData* image)
{
	int* dims = image->GetDimensions();
 
	for (int z = 0; z < dims[2]; z++)
	{ 
		for (int y = 0; y < dims[1]; y++)
		{
			for (int x = 0; x < dims[0]; x++)
			{
				double v = image->GetScalarComponentAsDouble(x, y, z, 0);
				std::cout << v << " ";
			}
			std::cout << std::endl;
		}
	} 
}