//
// Test Suite for geos::geom::CoordinateList class.

// tut
#include <tut/tut.hpp>
// geos
#include <geos/geom/Coordinate.h>
#include <geos/geom/CoordinateList.h>
// std
#include <memory>
#include <string>
#include <vector>

namespace tut {
//
// Test Group
//

// Common data used by tests
struct test_coordinatelist_data {

    test_coordinatelist_data() {}
};

typedef test_group<test_coordinatelist_data> group;
typedef group::object object;

group test_coordinatelist_group("geos::geom::CoordinateList");

//
// Test Cases
//

// Test insert and erase
template<>
template<>
void object::test<1>
()
{
    using geos::geom::Coordinate;

    const Coordinate a(0, 0);
    const Coordinate b(10, 10);
    const Coordinate c(20, 20);
    const Coordinate d(5, 5);

    geos::geom::CoordinateList::iterator it, it2;

    std::unique_ptr< std::vector<Coordinate> > col(new std::vector<Coordinate>());
    col->push_back(a);
    col->push_back(b);
    col->push_back(c);

    // coordinates are copied
    geos::geom::CoordinateList clist(*col);

    ensure_equals(clist.size(), 3u);

    it = clist.begin();
    clist.insert(++it, d);

    ensure_equals(clist.size(), 4u);

    it = clist.begin();
    ensure_equals(*it, a);
    ++it;
    ensure_equals(*it, d);
    ++it;
    ensure_equals(*it, b);
    ++it;
    ensure_equals(*it, c);


    it = clist.begin();
    ++it;
    ++it;
    clist.erase(it);
    ensure_equals(clist.size(), 3u);

    it = clist.begin();
    ensure_equals(*it, a);
    ++it;
    ensure_equals(*it, d);
    ++it;
    ensure_equals(*it, c);

    clist.insert(clist.end(), b);

    ensure_equals(clist.size(), 4u);

    it = clist.begin();
    ++it;
    it2 = it;
    ++it2;
    ++it2;
    clist.erase(it, it2);

    ensure_equals(clist.size(), 2u);

    it = clist.begin();
    ensure_equals(*it, a);
    ++it;
    ensure_equals(*it, b);

}

// Test insert with and without duplicates
template<>
template<>
void object::test<2>
()
{
    using geos::geom::Coordinate;

    geos::geom::CoordinateList clist;
    ensure_equals(clist.size(), 0u);

    clist.insert(clist.end(), Coordinate(0, 0));
    ensure_equals(clist.size(), 1u);

    clist.insert(clist.end(), Coordinate(0, 0), false);
    ensure_equals(clist.size(), 1u);

    clist.insert(clist.end(), Coordinate(0, 0), true);
    ensure_equals(clist.size(), 2u);

    clist.insert(clist.end(), Coordinate(1, 1), true);
    ensure_equals(clist.size(), 3u);

    geos::geom::CoordinateList::iterator it = clist.end();
    --it;
    clist.insert(it, Coordinate(0, 0), false);
    ensure_equals(clist.size(), 3u);
}
//Test to check the functioning of closeRing() method.
template<>
template<>
void object::test<3>
()
{
    using geos::geom::Coordinate;

    const Coordinate a(0, 0);
    const Coordinate b(10, 10);
    const Coordinate c(45, 60);
    const Coordinate d(100, 0);

    std::unique_ptr< std::vector<Coordinate> > v(new std::vector<Coordinate>());
    v->push_back(a);
    v->push_back(b);
    v->push_back(c);
    v->push_back(d);
    geos::geom::CoordinateList coordlist(*v);

    coordlist.closeRing();

    geos::geom::CoordinateList::iterator it1, it2;
    it1 = coordlist.begin();
    it2 = --coordlist.end();
    ensure_equals(*it1, *it2);

    /* for(CoordinateList::iterator it=coordlist.begin() ; it!=coordlist.end() ; ++it)
       {
       cout << (*it).x << " " << (*it).y << endl;
       }*/


    //If the list is empty::
    coordlist.erase(coordlist.begin(), coordlist.end());
    coordlist.closeRing();
    ensure_equals(coordlist.empty(), true);

}
} // namespace tut
