//
// Test Suite for geos::util::UniqueCoordinateArrayFilter class.

// tut
#include <tut/tut.hpp>
// geos
#include <geos/util/UniqueCoordinateArrayFilter.h>
#include <geos/geom/Coordinate.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/io/WKTReader.h>
// std
#include <memory>
#include <string>

namespace tut {
//
// Test Group
//

// Common data used in test cases.
struct test_uniquecoordinatearrayfilter_data {
    typedef std::unique_ptr<geos::geom::Geometry> GeometryPtr;
    typedef geos::geom::GeometryFactory GeometryFactory;

    geos::geom::PrecisionModel pm_;
    GeometryFactory::Ptr factory_;
    geos::io::WKTReader reader_;

    test_uniquecoordinatearrayfilter_data()
        : pm_(1)
        , factory_(GeometryFactory::create(&pm_, 0))
        , reader_(factory_.get())
    {}
};

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

group test_uniquecoordinatearrayfilter_group("geos::util::UniqueCoordinateArrayFilter");

//
// Test Cases
//

// Test of apply_ro() on MULTIPOINT
template<>
template<>
void object::test<1>
()
{
    using geos::geom::Coordinate;

    // Create geometry from WKT
    const Coordinate::ConstVect::size_type size5 = 5;
    const std::string wkt("MULTIPOINT(10 10, 20 20, 30 30, 20 20, 10 10)");
    GeometryPtr geo(reader_.read(wkt));

    ensure_equals(geo->getGeometryTypeId(), geos::geom::GEOS_MULTIPOINT);
    std::unique_ptr<geos::geom::CoordinateSequence> cs;
    cs = geo->getCoordinates();
    ensure_equals(cs->getSize(), size5);

    // Create collection buffer for filtered coordinates
    const Coordinate::ConstVect::size_type size0 = 0;
    Coordinate::ConstVect coords;

    // Create filtering object
    geos::util::UniqueCoordinateArrayFilter filter(coords);

    ensure_equals(coords.size(), size0);

    // Apply filter
    const Coordinate::ConstVect::size_type size3 = 3;
    geo->apply_ro(&filter);

    cs = geo->getCoordinates();
    ensure_equals(cs->getSize(), size5);
    ensure_equals(coords.size(), size3);
    ensure_equals(coords.at(0)->x, 10);
    ensure_equals(coords.at(0)->y, 10);
    ensure_equals(coords.at(1)->x, 20);
    ensure_equals(coords.at(1)->y, 20);
    ensure_equals(coords.at(2)->x, 30);
    ensure_equals(coords.at(2)->y, 30);
}

} // namespace tut

