#include <locale.h>
#include <iostream>
#include <vector>
#include <sstream>

#include <pqxx/pqxx>

#include <geos/geom/MultiPolygon.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/Point.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/io/WKTReader.h>
#include <geos/io/WKTWriter.h>
#include <geos/io/WKBReader.h>
#include <geos/io/WKBWriter.h>
#include <geos/operation/valid/IsValidOp.h>

int main(int argc, char* argv[])
{
  geos::geom::PrecisionModel pm(100);
  geos::geom::GeometryFactory gf(&pm);
  geos::io::WKTReader wktr(&gf);
  geos::io::WKBReader wkbr(gf);
  geos::io::WKTWriter wktw;

  const char* geom1 = "[payload removed: 2342 characters]";
  const char* geom2 = "MULTIPOLYGON(((-1173157.38714209 503718.58802041,-1182770.30323651 489980.507800949,-1148031.58582448 444843.892578903,-1149036.11225491 444070.773911757,-1144433.7890075 439466.959805496,-1137891.42781446 415036.217740684,-1144440.57108564 390607.292872176,-1162326.48217671 372725.519127381,-1186756.92150622 366182.027552956,-1201466.42978257 370124.765790846,-1201962.69132653 368609.804044124,-1281774.47301029 394754.040418745,-1588922.01191489 323254.181234702,-1588922.01191489 323254.181234702,-1600000 320675.372974445,-1600000 421010.146952896,-1297965.38084634 491319.78646754,-1299913.37260395 498591.360753112,-1293366.48996943 523020.89156292,-1275482.23370201 540904.320361082,-1251052.4 547450.07265625,-1226614.73516819 540899.798250951,-1223574.47409719 537858.552329502,-1223039.78714209 538622.68802041,-1173157.38714209 503718.58802041)),((1588922.01191489 418431.338765298,1589293.6063302 416835.051608646,1589293.60661415 416835.051684727,1588922.01221097 418431.338834222,1600000 421010.146952896,1600000 320675.372974445,1467947.98808511 289935.421234702,1467576.36093153 291531.849027705,1456865.47849378 288663.027552956,1432436.25062847 295211.040512814,1418330.90999782 309318.339203511,1417440.79821091 308666.891773607,1361956.19568562 384478.839803665,1318088.41069946 387944.185591252,1307066.96005599 371901.054459258,1348246.7249344 350096.002797399,1348038.66725241 349703.077040639,1349819.66483181 349225.698250951,1367700.6109925 331338.959805496,1374242.97218554 306908.217740684,1367693.82891436 282479.292872176,1349807.91782329 264597.519127381,1325377.47849378 258054.027552956,1302724.7708698 264125.861829322,1302517.2750656 263733.997202601,1212883.2750656 311195.997202601,1213090.7708698 311587.861829322,1211314.25062847 312064.040512814,1193431.64933785 329949.1242112,1186887.02739605 354379.260753112,1193433.91003057 378808.79156292,1196182.97371428 381557.728052879,1195474.90041829 382044.166443213,1253524.90041829 466543.366443213,1254232.97371428 466056.928052879,1269368.16629799 481191.420361082,1293798 487737.17265625,1297577.75174938 486724.047576062,1297645.79686953 487585.430215285,1391995.79686953 480132.230215285,1391927.75174938 479270.847576062,1412585.66483181 473733.698250951,1426686.53828774 459628.257012431,1427577.20178909 460280.108226393,1477233.48988609 392431.736583838,1588922.01191489 418431.338765298)))";

  std::istringstream istr(geom1);
  geos::geom::Geometry* g1 = wkbr.readHEX(istr);

  std::string w1 = wktw.write(g1);

  geos::geom::Geometry* g2 = wktr.read(w1);

  std::string w2 = wktw.write(g2);

  std::cout << "g1->isValid : " << g1->isValid() << std::endl;
  std::cout << "g2->isValid : " << g2->isValid() << std::endl;

  if (w1 != w2)
  {
    std::cout << "w1 : " << w1 << std::endl
	      << "w2 : " << w2 << std::endl;
  }

  if (w1 != geom2)
  {
    std::cout << "w1 : " << w1 << std::endl
	      << "g2 : " << geom2 << std::endl;
  }

  // Checking validity in PostGIS via pqxx

  pqxx::connection db("host=localhost dbname=fag-test_tmp user=postgres");
  pqxx::work xaction(db, "gis");

  std::string query = std::string("SELECT ST_IsValid('") + geom1 + "');";
  const pqxx::result r = xaction.exec(query);
  xaction.commit();

  //assert(r.size() == 1)
  std::cout << "ST_IsValid(geom1) : " << r[0][0].c_str() << std::endl;
}
