//-*****************************************************************************
void WriteTestArchive( const std::string &iArchiveName )
{
    AbcA::MetaData md;
    md.setUnique( "name", "arkive" );

    Alembic::AbcCoreHDF5::WriteArchive aw;

    AbcA::ArchiveWriterPtr archive = aw( iArchiveName, md );
    // at this point, the archive has a single H5 Group under the root
    // group called "ABC".

    AbcA::ObjectWriterPtr top = archive->getTop();
    AbcA::ObjectWriterPtr finalChild;

    {
        // as things go out of scope, they automatically clean themselves up.
        // when the archive goes out of scope, it writes itself to disk.

        md.set( "name", "childObject0" );
        AbcA::ObjectWriterPtr archiveChild = top->createChild(
            AbcA::ObjectHeader( "archiveChild", md ) );

        md.set( "name", "childObject1" );
        AbcA::ObjectWriterPtr archiveChildChild = archiveChild->createChild(
            AbcA::ObjectHeader( "archiveChildChild", md ) );

        md.set( "name", "childObject2" );
        finalChild = archiveChildChild->createChild(
            AbcA::ObjectHeader( "archiveChildChildChild", md ) );
    }

    // OK, let's write some properties.  First, get a shared_ptr to the
    // CompoundPropertyWriter for the final object.
    AbcA::CompoundPropertyWriterPtr fcProps = finalChild->getProperties();

    const AbcA::TimeSamplingType tsampType( 2, 2.0 );

    // Now, make some sample data.  We'll just use some ints.
    const size_t numVals = 50;
    const Dimensions dims( numVals );
    const AbcA::DataType dtype( Alembic::Util::kInt32POD, 1 );

    AbcA::PropertyHeader ph( "firstInt32ArrayProp", AbcA::kArrayProperty,
                             AbcA::MetaData(), dtype, tsampType );

    AbcA::ArrayPropertyWriterPtr arrayPropWtrPtr =
        fcProps->createArrayProperty( ph );

    std::vector<Alembic::Util::int32_t> intData0;
    for ( size_t i = 0 ; i < numVals ; ++i )
    {
        intData0.push_back( i );
    }
    AbcA::ArraySample as0( (const void*)&(intData0.front() ), dtype, dims );
    arrayPropWtrPtr->setSample( 0, 0.0, as0 );


    std::vector<Alembic::Util::int32_t> intData1;
    for ( size_t i = 0 ; i < 30 ; ++i )
    {
        intData1.push_back( i + 1 );
    }
    AbcA::ArraySample as1( (const void*)&( intData1.front() ), dtype,
                           Dimensions( 30 ) );
    arrayPropWtrPtr->setSample( 1, 1.0, as1 );

    std::vector<Alembic::Util::int32_t> intData2;
    for ( size_t i = 0 ; i < numVals ; ++i )
    {
        intData2.push_back( i + 2 );
    }
    AbcA::ArraySample as2( (const void*)&( intData2.front() ), dtype, dims );
    arrayPropWtrPtr->setSample( 2, 2.0, as2 );

    std::vector<Alembic::Util::int32_t> intData3;
    for ( size_t i = 0 ; i < numVals ; ++i )
    {
        intData3.push_back( i + 3 );
    }
    AbcA::ArraySample as3( (const void*)&( intData3.front() ), dtype, dims );
    arrayPropWtrPtr->setSample( 3, 3.0, as3 );

    std::vector<int32_t> intData4;
    for ( size_t i = 0 ; i < numVals ; ++i )
    {
        intData4.push_back( i + 4 );
    }
    AbcA::ArraySample as4( (const void*)&( intData4.front() ), dtype, dims );
    arrayPropWtrPtr->setSample( 4, 4.0, as4 );

    std::vector<Alembic::Util::int32_t> intData5;
    for ( size_t i = 0 ; i < 2 ; ++i )
    {
        intData5.push_back( i + 5 );
    }
    AbcA::ArraySample as5( (const void*)&( intData5.front() ), dtype,
                           Dimensions( 2 ) );
    arrayPropWtrPtr->setSample( 5, 5.0, as5 );

    std::vector<Alembic::Util::int32_t> intData6;
    for ( size_t i = 0 ; i < 78 ; ++i )
    {
        intData6.push_back( i + 6 );
    }
    AbcA::ArraySample as6( (const void*)&( intData6.front() ), dtype,
                           Dimensions( 78 ) );
    arrayPropWtrPtr->setSample( 6, 6.0, as6 );

    // OK, let's try a second array property, Acyclic time sampling
    AbcA::PropertyHeader ph2( "secondInt32ArrayProp", AbcA::kArrayProperty,
                              AbcA::MetaData(), dtype,
                              AbcA::TimeSamplingType(
                                  AbcA::TimeSamplingType::kAcyclic ) );
    AbcA::ArrayPropertyWriterPtr secondArrayProp =
        fcProps->createArrayProperty( ph2 );

    std::vector<int32_t> secondPropDataVec0;
    for ( size_t i = 0 ; i < 2 ; ++i )
    {
        secondPropDataVec0.push_back( i );
    }
    AbcA::ArraySample as2nd0( (const void*)&( secondPropDataVec0.front() ),
                             dtype, Dimensions( 2 ) );
    secondArrayProp->setSample( 0, 0.0, as2nd0 );

    std::vector<int32_t> secondPropDataVec1;
    for ( size_t i = 0 ; i < 10 ; ++i )
    {
        secondPropDataVec1.push_back( i + 1 );
    }
    AbcA::ArraySample as2nd1( (const void*)&( secondPropDataVec1.front() ),
                              dtype, Dimensions( 10 ) );
    secondArrayProp->setSample( 1, 0.5, as2nd1 );


    std::vector<int32_t> secondPropDataVec2;
    for ( size_t i = 0 ; i < 23 ; ++i )
    {
        secondPropDataVec2.push_back( i + 2 );
    }
    AbcA::ArraySample as2nd2( (const void*)&( secondPropDataVec2.front() ),
                              dtype, Dimensions( 23 ) );
    secondArrayProp->setSample( 2, 2.3, as2nd2 );

    // OK, now a ScalarProperty.
    AbcA::PropertyHeader scalarPH( "scalarProp", AbcA::kScalarProperty,
                                  AbcA::MetaData(),
                                  AbcA::DataType( Alembic::Util::kFloat32POD, 1 ),
                                  tsampType );

    AbcA::ScalarPropertyWriterPtr scalarPropWtrPtr =
        fcProps->createScalarProperty( scalarPH );

    float32_t scalarVal = 42.0f;

    scalarPropWtrPtr->setSample( 0, 0.0, (const void*)&scalarVal );

}
//-*****************************************************************************
void testTimeSamplingScalar()
{
    std::string archiveName = "timeSamplingScalar.abc";
    {
        A5::WriteArchive w;
        AbcA::ArchiveWriterPtr a = w(archiveName, AbcA::MetaData());
        AbcA::ObjectWriterPtr archive = a->getTop();

        AbcA::CompoundPropertyWriterPtr parent = archive->getProperties();

        // illegal time value
        TESTING_ASSERT_THROW(parent->createScalarProperty("uniform",
            AbcA::MetaData(), AbcA::DataType(Alembic::Util::kInt32POD, 1), 42),
            Alembic::Util::Exception);

        std::vector < double > timeSamps(1,-4.0);
        AbcA::TimeSamplingType tst(3.0);
        AbcA::TimeSampling ts(tst, timeSamps);
        uint32_t tsid = a->addTimeSampling(ts);

        AbcA::ScalarPropertyWriterPtr swp =
            parent->createScalarProperty("uniform", AbcA::MetaData(),
                AbcA::DataType(Alembic::Util::kInt32POD, 1), tsid);

        Alembic::Util::int32_t i = 0;

        swp->setSample(&i);

        i+=3;
        swp->setSample(&i);

        i+=3;
        swp->setSample(&i);

        timeSamps.clear();
        timeSamps.push_back(4.0);
        timeSamps.push_back(4.25);
        timeSamps.push_back(4.5);
        tst = AbcA::TimeSamplingType(3, 2.0);
        ts = AbcA::TimeSampling(tst, timeSamps);
        tsid = a->addTimeSampling(ts);

        AbcA::ScalarPropertyWriterPtr swp2 =
            parent->createScalarProperty("cyclic", AbcA::MetaData(),
                AbcA::DataType(Alembic::Util::kUint32POD, 1), tsid);

        Alembic::Util::uint32_t ui = 0;

        swp2->setSample(&ui);

        ui++;
        swp2->setSample(&ui);

        ui++;
        swp2->setSample(&ui);

        ui++;
        swp2->setSample(&ui);

        ui++;
        swp2->setSample(&ui);

        ui++;
        swp2->setSample(&ui);

        timeSamps.clear();
        timeSamps.push_back(-17.0);
        timeSamps.push_back(32.0);
        timeSamps.push_back(50.0);
        timeSamps.push_back(60.2);
        timeSamps.push_back(101.1);
        timeSamps.push_back(700.0);
        timeSamps.push_back(747.0);

        tst = AbcA::TimeSamplingType(AbcA::TimeSamplingType::kAcyclic);
        ts = AbcA::TimeSampling(tst, timeSamps);
        tsid = a->addTimeSampling(ts);

        AbcA::ScalarPropertyWriterPtr swp3 =
            parent->createScalarProperty("acyclic", AbcA::MetaData(),
                AbcA::DataType(Alembic::Util::kUint16POD, 1), tsid);

        Alembic::Util::uint16_t s = 0;
        swp3->setSample(&s);

        s++;
        swp3->setSample(&s);

        s++;

        swp3->setSample(&s);


        s++;
        swp3->setSample(&s);

        s++;
        swp3->setSample(&s);

        s++;
        swp3->setSample(&s);

        s++;
        swp3->setSample(&s);

        // Setting more than what we have acyclic samples for
        TESTING_ASSERT_THROW(swp3->setSample(&s),
            Alembic::Util::Exception);

        AbcA::ScalarPropertyWriterPtr swp4 =
            parent->createScalarProperty("identity", AbcA::MetaData(),
                AbcA::DataType(Alembic::Util::kInt16POD, 1), 0);

        Alembic::Util::int16_t ss = 35;


        swp4->setSample(&ss);

        ss = 37;
        swp4->setSample(&ss);

        ss = 1000;
        swp4->setSample(&ss);

        timeSamps.clear();
        timeSamps.push_back(0.0);
        tst = AbcA::TimeSamplingType(1.0);
        ts = AbcA::TimeSampling(tst, timeSamps);
        tsid = a->addTimeSampling(ts);

        AbcA::ScalarPropertyWriterPtr swp5 =
            parent->createScalarProperty("defaultUniform", AbcA::MetaData(),
                AbcA::DataType(Alembic::Util::kFloat32POD, 1), tsid);

        Alembic::Util::float32_t f = 0;

        swp5->setSample(&f);

        f+=1.1;
        swp5->setSample(&f);

        f+=1.1;
        swp5->setSample(&f);

        f+=1.1;
        swp5->setSample(&f);
    }

    {
        A5::ReadArchive r;
        AbcA::ArchiveReaderPtr a = r( archiveName );
        AbcA::ObjectReaderPtr archive = a->getTop();
        AbcA::CompoundPropertyReaderPtr parent = archive->getProperties();
        TESTING_ASSERT(parent->getNumProperties() == 5);

        for ( size_t i = 0; i < parent->getNumProperties(); ++i)
        {
            AbcA::BasePropertyReaderPtr bp = parent->getProperty( i );
            AbcA::ScalarPropertyReaderPtr sp = bp->asScalarPtr();
            const AbcA::TimeSamplingPtr t = sp->getTimeSampling();

            switch (sp->getDataType().getPod())
            {
                case Alembic::Util::kInt16POD:
                {
                    // identity
                    TESTING_ASSERT( t->getTimeSamplingType().isUniform() );
                }
                break;

                case Alembic::Util::kUint16POD:
                {
                    // acylic
                    TESTING_ASSERT( t->getSampleTime(0) == -17.0 );
                    TESTING_ASSERT( sp->getNumSamples() == 7);
                    TESTING_ASSERT( t->getTimeSamplingType().isAcyclic() );
                    TESTING_ASSERT( t->getSampleTime(1) == 32.0 );
                    TESTING_ASSERT( t->getSampleTime(2) == 50.0 );
                    TESTING_ASSERT( t->getSampleTime(3) == 60.2 );
                    TESTING_ASSERT( t->getSampleTime(4) == 101.1 );
                    TESTING_ASSERT( t->getSampleTime(5) == 700.0 );
                    TESTING_ASSERT( t->getSampleTime(6) == 747.0 );
                    TESTING_ASSERT_THROW( t->getSampleTime(7),
                        Alembic::Util::Exception);
                }
                break;

                case Alembic::Util::kFloat32POD:
                {
                    TESTING_ASSERT( sp->getNumSamples() == 4);
                    TESTING_ASSERT( t->getTimeSamplingType().isUniform() );
                    TESTING_ASSERT( t->getSampleTime(0) == 0.0 );
                    TESTING_ASSERT( t->getSampleTime(1) == 1.0 );
                    TESTING_ASSERT( t->getSampleTime(2) == 2.0 );
                    TESTING_ASSERT( t->getSampleTime(3) == 3.0 );
                }
                break;

                case Alembic::Util::kInt32POD:
                {
                    // uniform
                    TESTING_ASSERT( sp->getNumSamples() == 3);
                    TESTING_ASSERT( t->getTimeSamplingType().isUniform() );
                    TESTING_ASSERT( t->getSampleTime(0) == -4.0 );
                    TESTING_ASSERT( t->getSampleTime(1) == -1.0 );
                    TESTING_ASSERT( t->getSampleTime(2) == 2.0 );
                }
                break;

                case Alembic::Util::kUint32POD:
                {
                    // cyclic
                    TESTING_ASSERT( sp->getNumSamples() == 6);
                    TESTING_ASSERT( t->getTimeSamplingType().isCyclic() );
                    TESTING_ASSERT( t->getSampleTime(0) == 4.0 );
                    TESTING_ASSERT( t->getSampleTime(1) == 4.25 );
                    TESTING_ASSERT( t->getSampleTime(2) == 4.5 );
                    TESTING_ASSERT( t->getSampleTime(3) == 6.0 );
                    TESTING_ASSERT( t->getSampleTime(4) == 6.25 );
                    TESTING_ASSERT( t->getSampleTime(5) == 6.5 );
                }
                break;

                default:
                    TESTING_ASSERT(false);
                break;
            }
        }  // for
    }
}