//-------------------------------------------------------------------------
//
// File:		SaveC.h
// Desc:		Output stream class.
// Author:		memon <memon@inside.org>
//
//-------------------------------------------------------------------------
//	Copyright (c) 2000-2004 Moppi Productions. All Rights Reserved.
//  This file is part of Moppi Demopaja SDK. For conditions of 
//  distribution and use, see the accompanying license.txt file.
//  http://www.demopaja.org
//-------------------------------------------------------------------------

#ifndef __DEMOPAJA_SAVEC_H__
#define __DEMOPAJA_SAVEC_H__

#define FILEIO_DONT_INCLUDE_STREAMS
#include "PajaTypes.h"
#include "FileIO.h"
#include <stdio.h>
#include <vector>

namespace FileIO {

	//! Demopaja output stream.
	/*!	SaveC is used to save the information in Demopaja into a chunk based file format.
		The data in the output stream is serialized in chunk based format.
		Each begin_chunk() call should be closed with a call to the end_chunk()
		method.

		This class is implemented by the system.

		Example of save() method of an effect class:
		\code
		uint32
		TestEffectC::save( SaveC* pSave )
		{
			uint32	ui32Error = IO_OK;

			// EffectI stuff
			pSave->begin_chunk( CHUNK_TESTEFFECT_BASE, TESTEFFECT_VERSION );
				ui32Error = EffectI::save( pSave );
			pSave->end_chunk();

			// Save transform gizmo
			pSave->begin_chunk( CHUNK_TESTEFFECT_TRANSGIZMO, TESTEFFECT_VERSION );
				ui32Error = m_pTransGizmo->save( pSave );
			pSave->end_chunk();

			// Save attribute gizmo
			pSave->begin_chunk( CHUNK_TESTEFFECT_ATTRIBGIZMO, TESTEFFECT_VERSION );
				ui32Error = m_pAttribGizmo->save( pSave );
			pSave->end_chunk();

			return ui32Error;
		}
		\endcode

		\see LoadC
	*/
	class SaveC
	{
	public:
		//! Default constructor.
		SaveC();
		//! Default destructor.
		virtual ~SaveC();

		//! Opens output stream.
		/*!	See FileIOErrorsE for more information on the error codes.

			\param szName NULL terminated name of the output file.
			\param pSignature pointer to array of bytes describing the signature of the file.
			\param length of the signature in bytes.

			\return IO_OK if everything went ok, error otherwise.
		*/
		virtual	PajaTypes::uint32	open( const char* szName, const PajaTypes::int8* pSignature, PajaTypes::int32 i32SignatureSize );

		//! Flushes all buffers and closes output stream.
		virtual	PajaTypes::uint32	close();

		//! Begins a chunk a data.
		/*!	\param ui32ID ID of the chunk.
			\param ui32Version Version of the chunk.
			\return IO_OK if everything went ok, error otherwise.

			The versionin of chunks enables to easy modification to the format of the stored data
			in the file. The ID and Version info are available when the chunk is read back from the file.

			Example:
			\code
			...
			// Begin new chunk of data.
			pSave->begin_chunk( CHUNK_TGAIMPORT_NAME, TGAIMPORT_VERSION );
				// Write data to a chunk.
				sStr = m_sFileName;
				if( sStr.size() > 255 )
					sStr.resize( 255 );
				ui32Error = pSave->write_str( sStr.c_str() );
			// Close data chunk.
			pSave->end_chunk();
			...
			\endcode
		*/
		virtual	PajaTypes::uint32	begin_chunk( PajaTypes::uint32 ui32ID, PajaTypes::uint32 ui32Version );

		//! Closes a chunk.
		/*!	Calls to this method are hierarchial. There can be many chunks open at the
			same time. The chunk opened by the last call to begin_chunck() is closed.
			\return IO_OK if everything went ok, error otherwise. */
		virtual	PajaTypes::uint32	end_chunk();

		//! Writes a buffer to the stream.
		/*!	\param pBuffer pointer to the buffer containing all the data.
			\param ui32Len length of the buffer in bytes.
			\return IO_OK if everything went ok, error otherwise.
		*/
		virtual	PajaTypes::uint32	write( const void* pBuffer, PajaTypes::uint32 ui32Len );

		//! Writes string to the stream.
		/*!	\return IO_OK if everything went ok, error otherwise. */
		virtual	PajaTypes::uint32	write_str( const char* szStr );

		//! Returns current error code.
		virtual	PajaTypes::uint32	get_error();

	private:

		FILE*							m_pStream;

		PajaTypes::uint32				m_ui32Error;
		PajaTypes::int32				m_i32StartPos;
		PajaTypes::int32				m_i32CurrPos;

		std::vector<PajaTypes::int32>	m_rStartPosList;
		PajaTypes::uint32				m_i32Indent;

	};

};	// namespace

#endif
