/* -*- 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/>.
 *
 */

#include <mia/internal/autotest.hh>
#include <mia/3d/trackpoint.hh>
#include <mia/3d/transformfactory.hh>
#include <sstream>

using namespace std;
using namespace mia;

const char test_input[] =
       "1;12;10;5;12;some text\n"
       "2;13;7;5;2;other text\n"
       "3;14;1;2;3\n";


BOOST_AUTO_TEST_CASE ( test_read_points )
{
       istringstream is(test_input);
       std::vector<C3DTrackPoint> result;

       while (is.good()) {
              string line;
              getline( is, line);
              C3DTrackPoint tp;

              if (tp.read(line))
                     result.push_back(tp);
              else
                     is.setstate(ios_base::badbit);
       }

       BOOST_CHECK(is.eof());
       BOOST_REQUIRE(result.size() == 3u);
       const  C3DTrackPoint&  tp0 = result[0];
       BOOST_CHECK_EQUAL(tp0.get_id(), 1);
       BOOST_CHECK_EQUAL(tp0.get_pos(), C3DFVector(10, 5, 12));
       BOOST_CHECK_EQUAL(tp0.get_time(), 12);
       BOOST_CHECK_EQUAL(tp0.get_reserved(), "some text");
       const  C3DTrackPoint&  tp1 = result[1];
       BOOST_CHECK_EQUAL(tp1.get_id(), 2);
       BOOST_CHECK_EQUAL(tp1.get_pos(), C3DFVector(7, 5, 2));
       BOOST_CHECK_EQUAL(tp1.get_time(), 13);
       BOOST_CHECK_EQUAL(tp1.get_reserved(), "other text");
       const  C3DTrackPoint&  tp2 = result[2];
       BOOST_CHECK_EQUAL(tp2.get_id(), 3);
       BOOST_CHECK_EQUAL(tp2.get_pos(), C3DFVector(1, 2, 3));
       BOOST_CHECK_EQUAL(tp2.get_time(), 14);
       BOOST_CHECK(tp2.get_reserved().empty());
}

BOOST_AUTO_TEST_CASE ( test_write_points )
{
       C3DTrackPoint tp0(5, 10.0, C3DFVector(12, 3, 16.2), "a string");
       C3DTrackPoint tp1(6, 11.0, C3DFVector(1.1, 2, 1.2), "a bling");
       C3DTrackPoint tp2(7, 12.0, C3DFVector(2.1, 3, 4.2), "");
       ostringstream os;
       os << tp0 << "\n";
       os << tp1 << "\n";
       os << tp2 << "\n";
       BOOST_CHECK_EQUAL(os.str(), "5;10;12;3;16.2;a string\n"
                         "6;11;1.1;2;1.2;a bling\n"
                         "7;12;2.1;3;4.2\n"
                        );
}

BOOST_AUTO_TEST_CASE ( test_move )
{
       C3DTrackPoint tp0(5, 10.0, C3DFVector(1, 0, 0), "a string");
       auto tc = produce_3dtransform_factory("vf");
       auto t = tc->create(C3DBounds(2, 1, 1));
       auto params = t->get_parameters();
       BOOST_REQUIRE(params.size() == 6);
       params[0] = 2.0;
       params[1] = -1.0;
       params[2] = 4.0;
       params[3] = 1.0;
       t->set_parameters(params);
       tp0.move(1, *t);
       BOOST_CHECK_EQUAL(tp0.get_time(), 11.0);
       BOOST_CHECK_EQUAL(tp0.get_pos(), C3DFVector(0, 0, 0));
       tp0.move(0.4, *t);
       BOOST_CHECK_CLOSE(tp0.get_time(), 11.4, 0.1);
       const C3DFVector& p = tp0.get_pos();
       BOOST_CHECK_CLOSE(p.x, -0.8, 0.1);
       BOOST_CHECK_CLOSE(p.y,  0.4, 0.1);
       BOOST_CHECK_CLOSE(p.z, -1.6, 0.1);
}
