// Create a Spatial Context and add it to an XML document
void FdoImportExportTest::AddSC( FdoXmlWriter* writer, FdoString* name, FdoString* description, FdoString* coordSys, FdoString* wkt, FdoInt32 idx  )
{
    FdoXmlSpatialContextWriterP SCWriter = 
        FdoXmlSpatialContextWriter::Create( writer );

    SCWriter->SetName( name );
    SCWriter->SetDescription( description );
    SCWriter->SetCoordinateSystem( coordSys );

    if ( wcslen(wkt) > 0 ) 
        SCWriter->SetCoordinateSystemWkt( wkt );

    SCWriter->SetExtentType( 
        idx % 2 ?
            FdoSpatialContextExtentType_Dynamic :
            FdoSpatialContextExtentType_Static
    );

    FdoPtr<FdoByteArray> extent = SerializeExtent( 0, 0, 150 * idx, 100 * idx );
    SCWriter->SetExtent( extent );
    SCWriter->SetXYTolerance( 0.001 );
    SCWriter->SetZTolerance( 0.01 );

    SCWriter->WriteSpatialContext();
}
void SpatialContextTest::testXmlDotColon()
{
    try {
        FdoInt32 pass;

        // pass 0 writes SC without WKT, pass1 writes it with WKT.
        for ( pass = 0; pass < 2; pass++ ) {
            FdoIoMemoryStreamP stream = FdoIoMemoryStream::Create();
            FdoIoMemoryStreamP stream2 = FdoIoMemoryStream::Create();
            FdoXmlWriterP xmlWriter = FdoXmlWriter::Create(stream);

            FdoXmlSpatialContextWriterP writer = FdoXmlSpatialContextWriter::Create( 
                xmlWriter
            );

            writer->SetName( L"EPSG:123.4" );
            writer->SetDescription( L". and : test" );
            writer->SetCoordinateSystem( L"EPSG:1234" );
            if ( pass == 1 ) 
                writer->SetCoordinateSystemWkt( L"LOCAL_CS [ \"Non-Earth (Meter)\", LOCAL_DATUM [\"Local Datum\", 0], UNIT [\"Meter\", 1.0], AXIS [\"X\", EAST], AXIS[\"Y\", NORTH]]" );
            FdoPtr<FdoByteArray> extent = SerializeExtent( 0, 0, 15000, 10000 );
            writer->SetExtent( extent );
            writer->SetExtentType( FdoSpatialContextExtentType_Dynamic );
            writer->SetXYTolerance( 0.1 );
            writer->SetZTolerance( 0.01 );

            writer->WriteSpatialContext();

            writer = NULL;
            xmlWriter = NULL;
            stream->Reset();

            FdoXmlSpatialContextReaderP reader =
                FdoXmlSpatialContextReader::Create(
                    FdoXmlReaderP( FdoXmlReader::Create(stream) ),
                    FdoXmlSpatialContextFlagsP(
                        FdoXmlSpatialContextFlags::Create( NULL, FdoXmlFlags::ErrorLevel_High ) 
                    )
                );

            FDO_CPPUNIT_ASSERT( reader->ReadNext() );
            FDO_CPPUNIT_ASSERT( wcscmp(reader->GetName(), L"EPSG:123.4") == 0 );
            FDO_CPPUNIT_ASSERT( wcscmp(reader->GetCoordinateSystem(), L"EPSG:1234") == 0 );
            FDO_CPPUNIT_ASSERT( wcscmp(reader->GetDescription(), L". and : test") == 0 );
         
            FDO_CPPUNIT_ASSERT( !reader->ReadNext() );
        }
    }
    catch ( FdoException* e ) {
		UnitTestUtil::FailOnException( e );
    }
}
void CMyAxCtrl::Serialize(CArchive& ar)
{
    SerializeVersion(ar, MAKELONG(_wVerMinor, _wVerMajor));
    SerializeExtent(ar);
    SerializeStockProps(ar);

    if (ar.IsStoring())
    {   // storing code
    }
    else
    {   // loading code
    }
}
void SpatialContextTest::testXml()
{
    try {  
        FdoIoMemoryStreamP stream = FdoIoMemoryStream::Create();
        FdoIoMemoryStreamP stream2 = FdoIoMemoryStream::Create();
        FdoXmlWriterP xmlWriter = FdoXmlWriter::Create(stream);

        FdoXmlSpatialContextWriterP writer = FdoXmlSpatialContextWriter::Create( 
            xmlWriter
        );

        // Try to write nameless spatial context (should fail)
        FdoBoolean bFailed = false;
        try {
           writer->WriteSpatialContext();
        }
        catch ( FdoException* e ) {
//Todo: get this working for Linux (likely need to set up message catalogue
#ifdef _WIN32
// The exception message has no file information in release mode.That means there is no ')' in release mode . 
#ifdef _DEBUG
            FdoString* pMessage = wcschr( e->GetExceptionMessage(), ')' ) + 2;
            FDO_CPPUNIT_ASSERT( wcscmp(pMessage, L"Current spatial context has no name; cannot write to XML. ") == 0 );
#else
			FdoString* pMessage = e->GetExceptionMessage();
            FDO_CPPUNIT_ASSERT( wcscmp(pMessage, L"Current spatial context has no name; cannot write to XML. ") == 0 );
#endif
#endif
            e->Release ();
            bFailed = true;
        }
        if ( !bFailed ) 
            CPPUNIT_FAIL( "Writing nameless spatial context should have failed." );

        writer->SetName( L"SC_0" );


        writer->SetCoordinateSystem( L"Quebec MTM Zone 8 (NAD83)" );

        // Try to write extentless spatial context (should fail)
        bFailed = false;
        try {
           writer->WriteSpatialContext();
        }
        catch ( FdoException* e ) {
//Todo: get this working for Linux (likely need to set up message catalogue
#ifdef _WIN32
// The exception message has no file information in release mode.That means there is no ')' in release mode . 
#ifdef _DEBUG
            FdoString* pMessage = wcschr( e->GetExceptionMessage(), ')' ) + 2;
            FDO_CPPUNIT_ASSERT( wcscmp(pMessage, L"Current spatial context 'SC_0' has no extents; cannot write to XML. ") == 0 );
#else
			FdoString* pMessage = e->GetExceptionMessage();
            FDO_CPPUNIT_ASSERT( wcscmp(pMessage, L"Current spatial context 'SC_0' has no extents; cannot write to XML. ") == 0 );
#endif
#endif
            e->Release ();
            bFailed = true;
        }
        if ( !bFailed ) 
            CPPUNIT_FAIL( "Writing extentless spatial context should have failed." );

        // now for the happy tests.

        FdoByteArray* extent = SerializeExtent( 100000, 1000000, 200000, 1100000 );
        writer->SetExtent( extent );
        extent->Release();

        // write spatial context with no optional attributes set.
        writer->WriteSpatialContext();

        // write spatial contexts with optional attributes set.
        writer->SetName( L"Subway Map" );
        writer->SetDescription( L"Diagram of subway stops" );
        writer->SetCoordinateSystem( L"Non-Earth (Meter)" );
        writer->SetCoordinateSystemWkt( L"LOCAL_CS [ \"Non-Earth (Meter)\", LOCAL_DATUM [\"Local Datum\", 0], UNIT [\"Meter\", 1.0], AXIS [\"X\", EAST], AXIS[\"Y\", NORTH]]" );
        extent = SerializeExtent( 0, 0, 15000, 10000 );
        writer->SetExtent( extent );
        extent->Release();
        writer->SetExtentType( FdoSpatialContextExtentType_Dynamic );
        writer->SetXYTolerance( 0.1 );
        writer->SetZTolerance( 0.01 );

        writer->WriteSpatialContext();
        
        writer = FdoXmlSpatialContextWriter::Create( 
            xmlWriter
        );
        // write spatial context with no coordinate system set.
        writer->SetName( L"Default Rectangular" );
        extent = SerializeExtent( 0, 0, 1000, 1000 );
        writer->SetExtent( extent );
        extent->Release();

        writer->WriteSpatialContext();
        
        writer = NULL;
        xmlWriter = NULL;

        stream->Reset();
        stream2->Reset();

        // Round trip the spatial contexts that were written to a 2nd XML document.
        // This tests whether we lose anything when deserializing and serializing.
        XmlCopy( stream, stream2 );

        // Format output files for comparison. Adds carriage returns.
        stream->Reset();
        FdoIoFileStreamP fileStream = FdoIoFileStream::Create( L"sc1a.xml", L"wt+");
        XmlFormatter formatter1a(stream, fileStream);
        formatter1a.Format();

        stream2->Reset();
        fileStream = FdoIoFileStream::Create( L"sc2a.xml", L"wt+");
        XmlFormatter formatter2a(stream2, fileStream);
        formatter2a.Format();

        stream->SetLength(0);
        stream2->SetLength(0);

        // This next test writes an XML document with a single spatial context.

        writer = FdoXmlSpatialContextWriter::Create( 
            FdoXmlWriterP( FdoXmlWriter::Create(stream) ),
            FdoXmlSpatialContextFlagsP( FdoXmlSpatialContextFlags::Create( L"www.ttc.ca" ) )
        );

        writer->SetName( L"Subway Map" );
        writer->SetDescription( L"Diagram of subway stops" );
        writer->SetCoordinateSystem( L"Non-Earth (Meter)" );
        extent = SerializeExtent( 0, 0, 15000, 10000 );
        writer->SetExtent( extent );
        extent->Release();
        writer->SetExtentType( FdoSpatialContextExtentType_Dynamic );
        writer->SetXYTolerance( 0.1 );
        writer->SetZTolerance( 0.01 );

        writer->WriteSpatialContext();

        writer = NULL;

        stream->Reset();
        stream2->Reset();

        // Test round tripping for second document
        XmlCopy( stream, stream2 );

        // Format output files for comparison. Adds carriage returns.
        stream->Reset();
        fileStream = FdoIoFileStream::Create( L"sc1b.xml", L"wt+");
        XmlFormatter formatter1b(stream, fileStream);
        formatter1b.Format();

        stream2->Reset();
        fileStream = FdoIoFileStream::Create( L"sc2b.xml", L"wt+");
        XmlFormatter formatter2b(stream2, fileStream);
        formatter2b.Format();

//Todo: get this working on linux
#ifdef _WIN32
        // Compare output and expected results.
        UnitTestUtil::CheckOutput( "sc1a_master.txt", "sc1a.xml" );
        UnitTestUtil::CheckOutput( "sc1b_master.txt", "sc1b.xml" );
        UnitTestUtil::CheckOutput( "sc2a_master.txt", "sc2a.xml" );
        UnitTestUtil::CheckOutput( "sc2b_master.txt", "sc2b.xml" );
#endif

    }
    catch ( FdoException* e ) {
		UnitTestUtil::FailOnException( e );
    }
}
void SpatialContextTest::testXmlNesting()
{
    try {
        // Create an XML document with Spatial Contexts nested 2 levels down from
        // root element.

        FdoIoMemoryStreamP stream = FdoIoMemoryStream::Create();
        FdoXmlWriterP writer = FdoXmlWriter::Create( stream );

        // Create 2 Level1 elements under the root element.

        writer->WriteStartElement( L"Level1" );
        writer->WriteStartElement( L"Level2" );
        writer->WriteEndElement();
        writer->WriteStartElement( L"Level2" );
        writer->WriteEndElement();
        writer->WriteEndElement();

        // The Spatial Contexts are under the second Level1 element.

        writer->WriteStartElement( L"Level1" );

        // Mix them up with some other elements that should be skipped.
        writer->WriteStartElement( L"Level2" );
        writer->WriteEndElement();

        FdoXmlSpatialContextWriterP SCWriter =
            FdoXmlSpatialContextWriter::Create( writer );
        SCWriter->SetName( L"Embedded1" );
        FdoByteArray* extent = SerializeExtent( 0, 0, 15000, 10000 );
        SCWriter->SetExtent( extent );
        extent->Release();
        SCWriter->WriteSpatialContext();
        SCWriter = NULL;

        writer->WriteStartElement( L"Level2" );
        writer->WriteEndElement();

        SCWriter =
            FdoXmlSpatialContextWriter::Create( writer );
        SCWriter->SetName( L"Embedded2" );
        extent = SerializeExtent( 0, 0, 15000, 10000 );
        SCWriter->SetExtent( extent );
        extent->Release();
        SCWriter->WriteSpatialContext();
        SCWriter = NULL;

        writer->WriteStartElement( L"Level2" );
        writer->WriteEndElement();
        writer = NULL;

        stream->Reset();

        FdoIoFileStreamP fileStream = FdoIoFileStream::Create( L"sc_nested.xml", L"w+");
        XmlFormatter formatter1(stream, fileStream);
        formatter1.Format();
        stream->Reset();

        FdoPtr<NestedReader> reader = NestedReader::Create(stream);

        // Read the spatial contexts. Should get both of them
        reader->ReadNext();
        FDO_CPPUNIT_ASSERT( wcscmp(reader->GetName(), L"Embedded1") == 0 );

        reader->ReadNext();
        FDO_CPPUNIT_ASSERT( wcscmp(reader->GetName(), L"Embedded2") == 0 );

        // Shouldn't be any more spatial contexts at this point.
        FDO_CPPUNIT_ASSERT( reader->ReadNext() == false );
    }
    catch ( FdoException* e ) {
		UnitTestUtil::FailOnException( e );
    }
}