#!/usr/bin/env ruby

require 'test/unit'
require 'geos'


class TestIo < Test::Unit::TestCase
  
  def check(wkt, ndr_hex_in, xdr_hex_in)
    wkt_reader = Geos::WktReader.new
    geom1 = wkt_reader.read(wkt)
    
    wkb_reader = Geos::WkbReader.new
    geom2 = wkb_reader.read_hex(ndr_hex_in)
    geom3 = wkb_reader.read_hex(xdr_hex_in)
  
    assert(geom1.eql?(geom2)) 
    assert(geom1.eql?(geom3))
    assert(geom2.eql?(geom3))

    wkb_writer = Geos::WkbWriter.new
    wkb_writer.byte_order = Geos::GEOS_WKB_NDR
    ndr_hex_out = wkb_writer.write_hex(geom1)
    assert_equal(ndr_hex_in, ndr_hex_out)

    wkb_writer.byte_order = Geos::GEOS_WKB_XDR
    xdr_hex_out = wkb_writer.write_hex(geom1)
    assert_equal(xdr_hex_in, xdr_hex_out)
    geom1
  end

  def test_output_dimensions
    writer = Geos::WkbWriter.new
    assert_equal(2, writer.output_dimensions)
    
    writer.output_dimensions = 3
    assert_equal(3, writer.output_dimensions)
  end
  
  def test_byte_order
    writer = Geos::WkbWriter.new
    assert_equal(Geos::GEOS_WKB_NDR, writer.byte_order)
    
    writer.byte_order = Geos::GEOS_WKB_XDR
    assert_equal(Geos::GEOS_WKB_XDR, writer.byte_order)

    writer.byte_order = Geos::GEOS_WKB_NDR
    assert_equal(Geos::GEOS_WKB_NDR, writer.byte_order)
  end
  
  def test_point
    wkt = "POINT(0 0)"
    ndr = "010100000000000000000000000000000000000000"
    xdr = "000000000100000000000000000000000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::Point, geom)
    assert_equal('Point', geom.geom_type)
    assert_equal(Geos::GEOS_POINT, geom.type_id)
  end

  def test_line_string
    wkt = "LINESTRING(1 2, 3 4)"
    ndr = "010200000002000000000000000000F03F000000000000004000000000000008400000000000001040"
    xdr = "0000000002000000023FF0000000000000400000000000000040080000000000004010000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::LineString, geom)
    assert_equal('LineString', geom.geom_type)
    assert_equal(Geos::GEOS_LINESTRING, geom.type_id)
  end

  def test_polygon
    wkt = "POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(2 2, 2 6, 6 4, 2 2))"
    ndr = "0103000000020000000500000000000000000000000000000000000000000000000000244000000000000000000000000000002440000000000000244000000000000000000000000000002440000000000000000000000000000000000400000000000000000000400000000000000040000000000000004000000000000018400000000000001840000000000000104000000000000000400000000000000040"
    xdr = "0000000003000000020000000500000000000000000000000000000000402400000000000000000000000000004024000000000000402400000000000000000000000000004024000000000000000000000000000000000000000000000000000440000000000000004000000000000000400000000000000040180000000000004018000000000000401000000000000040000000000000004000000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::Polygon, geom)
    assert_equal('Polygon', geom.geom_type)
    assert_equal(Geos::GEOS_POLYGON, geom.type_id)
  end

  def test_multipoint
    wkt = "MULTIPOINT(0 0, 10 0, 10 10, 0 10, 0 0)"
    ndr = "010400000005000000010100000000000000000000000000000000000000010100000000000000000024400000000000000000010100000000000000000024400000000000002440010100000000000000000000000000000000002440010100000000000000000000000000000000000000"
    xdr = "000000000400000005000000000100000000000000000000000000000000000000000140240000000000000000000000000000000000000140240000000000004024000000000000000000000100000000000000004024000000000000000000000100000000000000000000000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::MultiPoint, geom)
    assert_equal('MultiPoint', geom.geom_type)
    assert_equal(Geos::GEOS_MULTIPOINT, geom.type_id)
  end

  def test_multipoint
    wkt = "MULTILINESTRING((0 0, 10 0, 10 10, 0 10, 10 20),(2 2, 2 6, 6 4, 20 2))"
    ndr = "010500000002000000010200000005000000000000000000000000000000000000000000000000002440000000000000000000000000000024400000000000002440000000000000000000000000000024400000000000002440000000000000344001020000000400000000000000000000400000000000000040000000000000004000000000000018400000000000001840000000000000104000000000000034400000000000000040"
    xdr = "000000000500000002000000000200000005000000000000000000000000000000004024000000000000000000000000000040240000000000004024000000000000000000000000000040240000000000004024000000000000403400000000000000000000020000000440000000000000004000000000000000400000000000000040180000000000004018000000000000401000000000000040340000000000004000000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::MultiPoint, geom)
    assert_equal('MultiLineString', geom.geom_type)
    assert_equal(Geos::GEOS_MULTILINESTRING, geom.type_id)
  end

  def test_multipoint
    wkt = "MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0),(2 2, 2 6, 6 4, 2 2)),((60 60, 60 50, 70 40, 60 60)))"
    ndr = "0106000000020000000103000000020000000500000000000000000000000000000000000000000000000000244000000000000000000000000000002440000000000000244000000000000000000000000000002440000000000000000000000000000000000400000000000000000000400000000000000040000000000000004000000000000018400000000000001840000000000000104000000000000000400000000000000040010300000001000000040000000000000000004E400000000000004E400000000000004E400000000000004940000000000080514000000000000044400000000000004E400000000000004E40"
    xdr = "000000000600000002000000000300000002000000050000000000000000000000000000000040240000000000000000000000000000402400000000000040240000000000000000000000000000402400000000000000000000000000000000000000000000000000044000000000000000400000000000000040000000000000004018000000000000401800000000000040100000000000004000000000000000400000000000000000000000030000000100000004404E000000000000404E000000000000404E000000000000404900000000000040518000000000004044000000000000404E000000000000404E000000000000"
    
    geom = check(wkt, ndr, xdr)
    assert_instance_of(Geos::MultiPolygon, geom)
    assert_equal('MultiPolygon', geom.geom_type)
    assert_equal(Geos::GEOS_MULTIPOLYGON, geom.type_id)
  end

  def test_collection
    wkt = "GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(1 2,3 4),POLYGON((0 0,10 0,10 10,0 10,0 0),(2 2,2 6,6 4,2 2)),MULTIPOINT(0 0,10 0,10 10,0 10,0 0),MULTILINESTRING((0 0,10 0,10 10,0 10,10 20),(2 2,2 6,6 4,20 2)),MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(2 2,2 6,6 4,2 2)),((60 60,60 50,70 40,60 60))))"
    ndr = "010700000006000000010100000000000000000000000000000000000000010200000002000000000000000000F03F00000000000000400000000000000840000000000000104001030000000200000005000000000000000000000000000000000000000000000000002440000000000000000000000000000024400000000000002440000000000000000000000000000024400000000000000000000000000000000004000000000000000000004000000000000000400000000000000040000000000000184000000000000018400000000000001040000000000000004000000000000000400104000000050000000101000000000000000000000000000000000000000101000000000000000000244000000000000000000101000000000000000000244000000000000024400101000000000000000000000000000000000024400101000000000000000000000000000000000000000105000000020000000102000000050000000000000000000000000000000000000000000000000024400000000000000000000000000000244000000000000024400000000000000000000000000000244000000000000024400000000000003440010200000004000000000000000000004000000000000000400000000000000040000000000000184000000000000018400000000000001040000000000000344000000000000000400106000000020000000103000000020000000500000000000000000000000000000000000000000000000000244000000000000000000000000000002440000000000000244000000000000000000000000000002440000000000000000000000000000000000400000000000000000000400000000000000040000000000000004000000000000018400000000000001840000000000000104000000000000000400000000000000040010300000001000000040000000000000000004E400000000000004E400000000000004E400000000000004940000000000080514000000000000044400000000000004E400000000000004E40"
    xdr = "0000000007000000060000000001000000000000000000000000000000000000000002000000023FF00000000000004000000000000000400800000000000040100000000000000000000003000000020000000500000000000000000000000000000000402400000000000000000000000000004024000000000000402400000000000000000000000000004024000000000000000000000000000000000000000000000000000440000000000000004000000000000000400000000000000040180000000000004018000000000000401000000000000040000000000000004000000000000000000000000400000005000000000100000000000000000000000000000000000000000140240000000000000000000000000000000000000140240000000000004024000000000000000000000100000000000000004024000000000000000000000100000000000000000000000000000000000000000500000002000000000200000005000000000000000000000000000000004024000000000000000000000000000040240000000000004024000000000000000000000000000040240000000000004024000000000000403400000000000000000000020000000440000000000000004000000000000000400000000000000040180000000000004018000000000000401000000000000040340000000000004000000000000000000000000600000002000000000300000002000000050000000000000000000000000000000040240000000000000000000000000000402400000000000040240000000000000000000000000000402400000000000000000000000000000000000000000000000000044000000000000000400000000000000040000000000000004018000000000000401800000000000040100000000000004000000000000000400000000000000000000000030000000100000004404E000000000000404E000000000000404E000000000000404900000000000040518000000000004044000000000000404E000000000000404E000000000000"
    
    assert_raise(RuntimeError) do
      geom = check(wkt, ndr, xdr)
      assert_instance_of(Geos::MultiPolygon, geom)
      assert_equal('Collection', geom.geom_type)
      assert_equal(Geos::GEOS_COLLECTION, geom.type_id)
    end
  end
  
  def test_wkt_invalid
    assert_raise(RuntimeError) do
      reader = Geos::WktReader.new
      geom = reader.read("invalid")
    end
  end
  
  def test_wkb_invalid
    assert_raise(RuntimeError) do
      reader = Geos::WkbReader.new
      geom = reader.read("invalid")
    end
  end
  
  def test_hex_invalid
    assert_raise(RuntimeError) do
      reader = Geos::WkbReader.new
      geom = reader.read_hex("invalid")
    end
  end
end