/* -*- mia-c++  -*-
 *
 * This file is part of MIA - a toolbox for medical image analysis 
 * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
 *
 * MIA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
 *
 */


#define VSTREAM_DOMAIN "vtkMeshIOtest"


#include <mia/internal/autotest.hh>
#include <mia/3d/imageio.hh>
#include <vtk/vtkmesh.hh>
#include <unistd.h>

using namespace vtkmia; 
using namespace mia; 
using namespace std; 

class  MeshVtkIOFixture {
protected: 
	MeshVtkIOFixture(); 
	
	
	void test_expected(const CTriangleMesh& changed, const CTriangleMesh& test) const;
	
	typedef CTriangleMesh::CTrianglefield::value_type Triangle;
	typedef CTriangleMesh::CColorfield::value_type Color;
	CTriangleMesh mesh; 
}; 


BOOST_FIXTURE_TEST_CASE(test_simple_store_and_load, MeshVtkIOFixture)
{
	CVtkMeshIO io; 
	BOOST_REQUIRE(io.save("testsavemesh.vtk", mesh));
	
	auto loaded_mesh = io.load("testsavemesh.vtk");
	BOOST_REQUIRE(loaded_mesh); 
	
	test_expected(*loaded_mesh, mesh);

}

BOOST_FIXTURE_TEST_CASE(test_store_and_load_with_all, MeshVtkIOFixture)
{
	CTriangleMesh::CNormalfield nfield({C3DFVector(2,3,1), C3DFVector(7,6,2), 
				C3DFVector(2,4,3), C3DFVector(5,6,4)}); 
	CTriangleMesh::CColorfield cfield({Color(2,3,1), Color(4,1,5), Color(1,6,7), Color(1,1,8)});
	CTriangleMesh::CScalefield sfield({1,2,3,4}); 
	
	copy(nfield.begin(), nfield.end(), mesh.normals_begin()); 
	copy(cfield.begin(), cfield.end(), mesh.color_begin()); 
	copy(sfield.begin(), sfield.end(), mesh.scale_begin()); 



	CVtkMeshIO io; 
	BOOST_REQUIRE(io.save("testsavemesh.vtk", mesh));
	
	auto loaded_mesh = io.load("testsavemesh.vtk");
	BOOST_REQUIRE(loaded_mesh); 
	
	test_expected(*loaded_mesh, mesh);
	
	unlink("testsavemesh.vtk"); 
}


MeshVtkIOFixture::MeshVtkIOFixture():mesh(4,4)
{
	
	CTriangleMesh::CVertexfield vertices{
		C3DFVector(1,5,8), C3DFVector(5,3,3), C3DFVector(3,4,1), C3DFVector(2,1,4)}; 
	
	typedef T3DVector<unsigned int> Triangle; 
	CTriangleMesh::CTrianglefield triangles{
		Triangle(0,1,2), Triangle(1,2,3), Triangle(0,2,3), Triangle(0,3,1)}; 
	copy(vertices.begin(), vertices.end(), mesh.vertices_begin()); 
	copy(triangles.begin(), triangles.end(), mesh.triangles_begin());
}

void MeshVtkIOFixture::test_expected(const CTriangleMesh& changed, const CTriangleMesh& test) const
{
	BOOST_CHECK_EQUAL(changed.vertices_size(), test.vertices_size()); 
	BOOST_CHECK_EQUAL(changed.triangle_size(), test.triangle_size()); 
	BOOST_CHECK_EQUAL(changed.get_available_data(), test.get_available_data()); 
	
	for(auto ic = changed.vertices_begin(), it = test.vertices_begin(); 
	    ic != changed.vertices_end(); ++ic, ++it) {
		BOOST_CHECK_EQUAL(*ic, *it); 
	}

	for(auto ic = changed.triangles_begin(), it = test.triangles_begin(); 
	    ic != changed.triangles_end(); ++ic, ++it) {
		BOOST_CHECK_EQUAL(*ic, *it); 
	}
	
	if (test.get_available_data() & CTriangleMesh::ed_normal) {
		for(auto ic = changed.normals_begin(), it = test.normals_begin(); 
		    ic != changed.normals_end(); ++ic, ++it) {
			BOOST_CHECK_EQUAL(*ic, *it); 
		}
	}

	if (test.get_available_data() & CTriangleMesh::ed_color){
		for(auto ic = changed.color_begin(), it = test.color_begin(); 
		    ic != changed.color_end(); ++ic, ++it) {
			BOOST_CHECK_EQUAL(*ic, *it); 
		}
	}
	
	if (test.get_available_data() & CTriangleMesh::ed_scale){
		for(auto ic = changed.scale_begin(), it = test.scale_begin(); 
		    ic != changed.scale_end(); ++ic, ++it) {
			BOOST_CHECK_EQUAL(*ic, *it); 
		}
	}
}




