/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#ifndef SC_XERECORD_HXX
#define SC_XERECORD_HXX

#include "xlconst.hxx"
#include "xestream.hxx"

// Base classes to export Excel records =======================================

/** Base class for all Excel records.

    Derive from this class to implement any functionality performed during
    saving the records - except really writing a record (i.e. write a list of
    records contained in the class). Derive from XclExpRecord (instead from
    this class) to write common records.
 */
class XclExpRecordBase
{
public:
    virtual             ~XclExpRecordBase();

    /** Overwrite this method to do any operation while saving the record. */
    virtual void        Save( XclExpStream& rStrm );
    virtual void        SaveXml( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

class XclExpDelegatingRecord : public XclExpRecordBase
{
public:
                        XclExpDelegatingRecord( XclExpRecordBase* pRecord );
                        ~XclExpDelegatingRecord();

    virtual void        SaveXml( XclExpXmlStream& rStrm );
private:
    XclExpRecordBase*   mpRecord;
};

// ----------------------------------------------------------------------------

class XclExpXmlElementRecord : public XclExpRecordBase
{
public:
                        XclExpXmlElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
    virtual             ~XclExpXmlElementRecord();

protected:
    sal_Int32           mnElement;
    void                (*mpAttributes)( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

class XclExpXmlStartElementRecord : public XclExpXmlElementRecord
{
public:
                        XclExpXmlStartElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
    virtual             ~XclExpXmlStartElementRecord();

    /** Starts the element nElement */
    virtual void        SaveXml( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

class XclExpXmlEndElementRecord : public XclExpXmlElementRecord
{
public:
                        XclExpXmlEndElementRecord( sal_Int32 nElement );
    virtual             ~XclExpXmlEndElementRecord();

    /** Ends the element nElement */
    virtual void        SaveXml( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

class XclExpXmlStartSingleElementRecord : public XclExpXmlElementRecord
{
public:
                        XclExpXmlStartSingleElementRecord( sal_Int32 nElement, void (*pAttributes)( XclExpXmlStream& rStrm) = NULL );
    virtual             ~XclExpXmlStartSingleElementRecord();

    /** Starts the single element nElement */
    virtual void        SaveXml( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

class XclExpXmlEndSingleElementRecord : public XclExpRecordBase
{
public:
                        XclExpXmlEndSingleElementRecord();
    virtual             ~XclExpXmlEndSingleElementRecord();

    /** Ends the single element nElement */
    virtual void        SaveXml( XclExpXmlStream& rStrm );
};

// ----------------------------------------------------------------------------

/** Base class for single records with any content.

    This class handles writing the record header. Derived classes only have to
    write the record body. Calculating the record size before saving optimizes
    the write process (the stream does not have to seek back and update the
    written record size). But it is not required to calculate a valid size
    (maybe it would be too complex or just impossible until the record is
    really written).
 */
class XclExpRecord : public XclExpRecordBase
{
public:
    /** @param nRecId  The record ID of this record. May be set later with SetRecId().
        @param nRecSize  The predicted record size. May be set later with SetRecSize(). */
    explicit            XclExpRecord(
                            sal_uInt16 nRecId = EXC_ID_UNKNOWN,
                            sal_Size nRecSize = 0 );

    virtual             ~XclExpRecord();

    /** Returns the current record ID. */
    inline sal_uInt16   GetRecId() const { return mnRecId; }
    /** Returns the current record size prediction. */
    inline sal_Size     GetRecSize() const { return mnRecSize; }

    /** Sets a new record ID. */
    inline void         SetRecId( sal_uInt16 nRecId ) { mnRecId = nRecId; }
    /** Sets a new record size prediction. */
    inline void         SetRecSize( sal_Size nRecSize ) { mnRecSize = nRecSize; }
    /** Adds a size value to the record size prediction. */
    inline void         AddRecSize( sal_Size nRecSize ) { mnRecSize += nRecSize; }
    /** Sets record ID and size with one call. */
    void                SetRecHeader( sal_uInt16 nRecId, sal_Size nRecSize );

    /** Writes the record header and calls WriteBody(). */
    virtual void        Save( XclExpStream& rStrm );

protected:
    /** Writes the body of the record (without record header).
        @descr  Usually this method will be overwritten by derived classes. */
    virtual void        WriteBody( XclExpStream& rStrm );

private:
    sal_Size            mnRecSize;      /// The predicted record size.
    sal_uInt16          mnRecId;        /// The record ID.
};

// ----------------------------------------------------------------------------

/** A record without body. Only the record ID and the size 0 will be written. */
class XclExpEmptyRecord : public XclExpRecord
{
public:
    /** @param nRecId  The record ID of this record. */
    inline explicit     XclExpEmptyRecord( sal_uInt16 nRecId );
};

inline XclExpEmptyRecord::XclExpEmptyRecord( sal_uInt16 nRecId ) :
    XclExpRecord( nRecId, 0 )
{
}

// ============================================================================

/** A record with a single value of type Type.
    @descr  Requires operator<<( XclExpStream&, const Type& ). */
template< typename Type >
class XclExpValueRecord : public XclExpRecord
{
public:
    /** @param nRecId  The record ID of this record.
        @param rValue  The value for the record body.
        @param nSize  Record size. Uses sizeof( Type ), if this parameter is omitted. */
    inline explicit     XclExpValueRecord( sal_uInt16 nRecId, const Type& rValue, sal_Size nSize = sizeof( Type ) ) :
                            XclExpRecord( nRecId, nSize ), maValue( rValue ), mnAttribute( -1 ) {}

    /** Returns the value of the record. */
    inline const Type&  GetValue() const { return maValue; }
    /** Sets a new record value. */
    inline void         SetValue( const Type& rValue ) { maValue = rValue; }

    /** Sets the OOXML attribute this record corresponds to */
    XclExpValueRecord*  SetAttribute( sal_Int32 nId );

    /** Write the OOXML attribute and its value */
    void                SaveXml( XclExpXmlStream& rStrm );

private:
    /** Writes the body of the record. */
    inline virtual void WriteBody( XclExpStream& rStrm ) { rStrm << maValue; }
    // inlining prevents warning in wntmsci10

private:
    Type                maValue;        /// The record data.
    sal_Int32           mnAttribute;    /// The OOXML attribute Id
};

template< typename Type >
void XclExpValueRecord< Type >::SaveXml( XclExpXmlStream& rStrm )
{
    if( mnAttribute == -1 )
        return;
    rStrm.WriteAttributes(
        mnAttribute,    rtl::OString::valueOf( (sal_Int32) maValue ).getStr(),
        FSEND );
}

template<>
void XclExpValueRecord<double>::SaveXml( XclExpXmlStream& rStrm );

template< typename Type >
XclExpValueRecord< Type >* XclExpValueRecord< Type >::SetAttribute( sal_Int32 nId )
{
    mnAttribute = nId;
    return this;
}

// ----------------------------------------------------------------------------

/** A record containing an unsigned 16-bit value. */
typedef XclExpValueRecord< sal_uInt16 >     XclExpUInt16Record;

/** A record containing an unsigned 32-bit value. */
typedef XclExpValueRecord< sal_uInt32 >     XclExpUInt32Record;

/** A record containing a double value. */
typedef XclExpValueRecord< double >         XclExpDoubleRecord;

// ----------------------------------------------------------------------------

/** Record which contains a Boolean value.
    @descr  The value is stored as 16-bit value: 0x0000 = sal_False, 0x0001 = TRUE. */
class XclExpBoolRecord : public XclExpRecord
{
public:
    /** @param nRecId  The record ID of this record.
        @param nValue  The value for the record body. */
    inline explicit     XclExpBoolRecord( sal_uInt16 nRecId, bool bValue, sal_Int32 nAttribute = -1 ) :
                            XclExpRecord( nRecId, 2 ), mbValue( bValue ), mnAttribute( nAttribute ) {}

    /** Returns the Boolean value of the record. */
    inline bool         GetBool() const { return mbValue; }
    /** Sets a new Boolean record value. */
    inline void         SetBool( bool bValue ) { mbValue = bValue; }

    virtual void        SaveXml( XclExpXmlStream& rStrm );

private:
    /** Writes the body of the record. */
    virtual void        WriteBody( XclExpStream& rStrm );

private:
    bool                mbValue;        /// The record data.
    sal_Int32           mnAttribute;    /// The attribute to generate within SaveXml()
};

// ----------------------------------------------------------------------------

/** Record which exports a memory data array. */
class XclExpDummyRecord : public XclExpRecord
{
public:
    /** @param nRecId  The record ID of this record.
        @param pRecData  Pointer to the data array representing the record body.
        @param nRecSize  Size of the data array. */
    explicit            XclExpDummyRecord(
                            sal_uInt16 nRecId, const void* pRecData, sal_Size nRecSize );

    /** Sets a data array. */
    void                SetData( const void* pRecData, sal_Size nRecSize );

private:
    /** Writes the body of the record. */
    virtual void        WriteBody( XclExpStream& rStrm );

private:
    const void*         mpData;         /// The record data.
};

// Future records =============================================================

class XclExpFutureRecord : public XclExpRecord
{
public:
    explicit            XclExpFutureRecord( XclFutureRecType eRecType,
                            sal_uInt16 nRecId, sal_Size nRecSize = 0 );

    /** Writes the extended record header and calls WriteBody(). */
    virtual void        Save( XclExpStream& rStrm );

private:
    XclFutureRecType    meRecType;
};

// List of records ============================================================

/** A list of Excel record objects.

    Provides saving the compete list. This class is derived from
    XclExpRecordBase, so it can be used as record in another record list.
    Requires RecType::Save( XclExpStream& ).
 */
template< typename RecType = XclExpRecordBase >
class XclExpRecordList : public XclExpRecordBase
{
public:
    typedef ScfRef< RecType > RecordRefType;

    /** Returns pointer to an existing record or 0 on error. */
    inline bool         IsEmpty() const { return maRecs.empty(); }
    /** Returns pointer to an existing record or 0 on error. */
    inline size_t       GetSize() const { return maRecs.size(); }

    /** Returns true, if the passed index points to an exiting record. */
    inline bool         HasRecord( size_t nPos ) const
                            { return nPos < maRecs.size(); }
    /** Returns reference to an existing record or empty reference on error. */
    inline RecordRefType GetRecord( size_t nPos ) const
                            { return (nPos < maRecs.size()) ? maRecs[ nPos ] : RecordRefType(); }
    /** Returns reference to the first existing record or empty reference, if list is empty. */
    inline RecordRefType GetFirstRecord() const
                            { return maRecs.empty() ? RecordRefType() : maRecs.front(); }
    /** Returns reference to the last existing record or empty reference, if list is empty. */
    inline RecordRefType GetLastRecord() const
                            { return maRecs.empty() ? RecordRefType() : maRecs.back(); }

    /** Inserts a record at the specified position into the list. */
    inline void         InsertRecord( RecordRefType xRec, size_t nPos )
                            { if( xRec.get() ) maRecs.insert( maRecs.begin() + ::std::min( nPos, maRecs.size() ), xRec ); }
    /** Appends a record to the list. */
    inline void         AppendRecord( RecordRefType xRec )
                            { if( xRec.get() ) maRecs.push_back( xRec ); }
    /** Replaces the record at the specified position from the list with the passed record. */
    inline void         ReplaceRecord( RecordRefType xRec, size_t nPos )
                            { RemoveRecord( nPos ); InsertRecord( xRec, nPos ); }

    /** Inserts a newly created record at the specified position into the list. */
    inline void         InsertNewRecord( RecType* pRec, size_t nPos )
                            { if( pRec ) InsertRecord( RecordRefType( pRec ), nPos ); }
    /** Appends a newly created record to the list. */
    inline void         AppendNewRecord( RecType* pRec )
                            { if( pRec ) AppendRecord( RecordRefType( pRec ) ); }
    /** Replaces the record at the specified position from the list with the passed newly created record. */
    inline void         ReplaceNewRecord( RecType* pRec, size_t nPos )
                            { RemoveRecord( nPos ); InsertNewRecord( pRec, nPos ); }

    /** Removes the record at the specified position from the list. */
    inline void         RemoveRecord( size_t nPos )
                            { if( nPos < maRecs.size() ) maRecs.erase( maRecs.begin() + nPos ); }
    /** Removes all records from the list. */
    inline void         RemoveAllRecords() { maRecs.clear(); }

    /** Writes the complete record list. */
    inline virtual void Save( XclExpStream& rStrm )
    {
        // inlining prevents warning in wntmsci10
        for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
            (*aIt)->Save( rStrm );
    }

    inline virtual void SaveXml( XclExpXmlStream& rStrm )
    {
        // inlining prevents warning in wntmsci10
        for( typename RecordVec::iterator aIt = maRecs.begin(), aEnd = maRecs.end(); aIt != aEnd; ++aIt )
            (*aIt)->SaveXml( rStrm );
    }

private:
    typedef ::std::vector< RecordRefType > RecordVec;
    RecordVec           maRecs;
};

// ============================================================================

/** Represents a complete substream of records enclosed into a pair of BOF/EOF records. */
class XclExpSubStream : public XclExpRecordList<>
{
public:
    explicit            XclExpSubStream( sal_uInt16 nSubStrmType );

    /** Writes the complete substream, including leading BOF and trailing EOF. */
    virtual void        Save( XclExpStream& rStrm );

private:
    sal_uInt16          mnSubStrmType;  /// Substream type, stored in leading BOF record.
};

// ============================================================================

#endif

