#!/usr/bin/env ruby

require 'test/unit'
require 'geos'


class TestIo < Test::Unit::TestCase
  
  def check(wkt, ndr_hex_in, xdr_hex_in)
    geom1 = Geos::geom_from_wkt(wkt)
    geom2 = Geos::geom_from_hex(ndr_hex_in)
    geom3 = Geos::geom_from_hex(xdr_hex_in)
	
    assert(geom1.equals(geom2))	
    assert(geom1.equals(geom3))
    assert(geom2.equals(geom3))

    Geos::set_wkb_byte_order(Geos::GEOS_WKB_NDR)
    ndr_hex_out = Geos::geom_to_hex(geom1)
    assert_equal(ndr_hex_in, ndr_hex_out)

    Geos::set_wkb_byte_order(Geos::GEOS_WKB_XDR)
    xdr_hex_out = Geos::geom_to_hex(geom1)
    assert_equal(xdr_hex_in, xdr_hex_out)
    geom1
  end

  def test_output_dimensions
    assert_equal(2, Geos::get_wkb_output_dimensions)
    assert_equal(2, Geos::set_wkb_output_dimensions(3))
    
    assert_equal(3, Geos::get_wkb_output_dimensions)
    assert_equal(3, Geos::set_wkb_output_dimensions(2))
	end
	
  def test_byte_order
    original = Geos::get_wkb_byte_order
  	assert_equal(original, Geos::set_wkb_byte_order(Geos::GEOS_WKB_XDR))
  	assert_equal(Geos::GEOS_WKB_XDR, Geos::get_wkb_byte_order)

  	assert_equal(Geos::GEOS_WKB_XDR, Geos::set_wkb_byte_order(Geos::GEOS_WKB_NDR))
  	assert_equal(Geos::GEOS_WKB_NDR, Geos::get_wkb_byte_order)
  	
  	assert_equal(Geos::GEOS_WKB_NDR, Geos::set_wkb_byte_order(original))
  	assert_equal(original, Geos::get_wkb_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
    	geom = Geos::geom_from_wkt("invalid")
    end
  end
  
  def test_wkb_invalid
    assert_raise(RuntimeError) do
    	geom = Geos::geom_from_wkb("invalid")
    end
  end
  
  def test_hex_invalid
    assert_raise(RuntimeError) do
    	geom = Geos::geom_from_hex("invalid")
    end
  end
end