//
// LDASTools frameCPP - A library implementing the LIGO/Virgo frame
// specification
//
// Copyright (C) 2019 California Institute of Technology
//
// LDASTools frameCPP is free software; you may redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 (GPLv2) of the
// License or at your discretion, any later version.
//
// LDASTools frameCPP is distributed in the hope that it will be useful, but
// without any warranty or even the implied warranty of merchantability
// or fitness for a particular purpose. See the GNU General Public
// License (GPLv2) for more details.
//
// Neither the names of the California Institute of Technology (Caltech),
// The Massachusetts Institute of Technology (M.I.T), The Laser
// Interferometer Gravitational-Wave Observatory (LIGO), nor the names
// of its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// You should have received a copy of the licensing terms for this
// software included in the file LICENSE located in the top-level
// directory of this package. If you did not, you can view a copy at
// http://dcc.ligo.org/M1500244/LICENSE
//

#ifndef FrameCPP_UNIVERSAL__IMPL__FrTOCDataClassicIO_HH
#define FrameCPP_UNIVERSAL__IMPL__FrTOCDataClassicIO_HH

#if defined( __cplusplus )
#if !defined( SWIG )

#include "framecpp/Common/Description.hh"
#include "framecpp/Common/FrameSpec.hh"
#include "framecpp/Common/FrameSpec.tcc"
#include "framecpp/Common/TOCInfo.hh"

#include "framecpp/Universal/impl/FrTOCDataData.hh"
#include "framecpp/Universal/impl/STRING.hh"

namespace FrameCPP
{
    namespace Universal
    {
        namespace FrTOCImpl
        {
            class FrTOCDataClassicIO : public virtual FrTOCDataData
            {
            public:
                FrTOCDataClassicIO( ) = default;

                Common::FrameSpec::size_type
                Bytes( const Common::StreamBase& Stream ) const;

                inline FrTOCDataClassicIO&
                operator=( FrTOCDataClassicIO&& TOC )
                {
                    static_cast< FrTOCDataData& >( *this ) =
                        static_cast< FrTOCDataData&& >( TOC );
                    return *this;
                }

                //-----------------------------------------------------------------
                /// \brief The description of structure
                ///
                /// \param[in] frame_stream_version
                ///     The frame specification version
                ///
                /// \param[out] Desc
                ///     Storage for the description of the structure.
                ///
                /// \return
                ///     A Description object which describes this structure as
                ///     specified by the frame specification.
                //-----------------------------------------------------------------
                void GetDescription( unsigned int         frame_stream_version,
                                     Common::Description& Desc ) const;

                //-----------------------------------------------------------------
                /// \brief Read contents from stream
                ///
                /// \param[in] Stream
                ///     The stream from which the object is being read.
                /// \param[in,out] nframe
                ///     The number of frames. This will be updated after reading.
                ///
                /// \return
                ///    A new instance of this object.
                //-----------------------------------------------------------------
                void Load( istream_type& Stream, INT_4U& nframe );

            protected:
                //-----------------------------------------------------------------
                /// \brief Iterate over contents.
                ///
                /// \param[in] Info
                ///     Specifies the type of information to be searched.
                ///
                /// \param[in] Action
                ///     Action to be taken for each piece of information found.
                //-----------------------------------------------------------------
                void forEach( Common::FrTOC::query_info_type Info,
                              Common::FrTOC::FunctionBase&   Action ) const;

                //-----------------------------------------------------------------
                /// \brief Write the structure to the stream
                ///
                /// \param[in] Stream
                ///     The output stream where the object is to be written.
                //-----------------------------------------------------------------
                void write( Common::OStream& Stream ) const;

            private:
                typedef STRING io_namedetector_type;
                typedef STRING io_shname_type;
            };

        }; // namespace FrTOCImpl

    } // namespace Universal
} // namespace FrameCPP

#endif /* ! defined(SWIG) */
#endif /* defined( __cplusplus ) */

#endif /* FrameCPP_UNIVERSAL__IMPL__FrTOCDataClassicIO_HH */
