//==============================================================================
/*! \file
 * OpenMesh Toolkit for mesh analysis    \n
 * Copyright (c) 2010 by Rostislav Hulik     \n
 *
 * Author:  Rostislav Hulik, rosta.hulik@gmail.com  \n
 * Date:    2010/10/23                          \n
 *
 * This file is part of software developed for support of Rostislav Hulik's dissertation thesis at dcgm-robotics@FIT group.
 *
 * This file is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Description:
 * - Class derrived from OpenMesh OM reader
 * - Extends functionality for import from MDSTk Channel
 * - Most of code is modified OpenMesh
 */
#ifndef _OM_READER_EXT_H_
#define _OM_READER_EXT_H_

#include <OpenMesh\Core\IO\reader\OMReader.hh>
#include <OMToolkit/IO\OMFormatExt.h>
#include <strstream>

namespace OpenMesh {
namespace IO {

/**
 * Class extends functionality of OMReader for import from MDSTk Channel
 */
class OMReaderExt : public _OMReader_
{
	public:
		/**
		 * Destructor
		 */
		virtual ~OMReaderExt() { }

		/**
		 * Stream Reader for MDSTk input in binary format
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @return True, if reading was successful
		 */
		bool read(mds::mod::CChannel& _is, BaseImporter& _bi, Options& _opt );

	private:
		/**
		 * Read ascii representation of this format
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @return True, if reading was successful
		 * @todo Write this method - for now, as in OpenMesh, ascii method is not functional
		 */
		bool read_ascii(mds::mod::CChannel& _is, BaseImporter& _bi, Options& _opt) const;
		
		/**
		 * Read binary representation of this format
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @return True, if reading was successful
		 */
		bool read_binary(mds::mod::CChannel& _is, BaseImporter& _bi, Options& _opt) const;
		
		/**
		 * Header type in OM format
		 */
		typedef OMFormat::HeaderExt Header;
		
		/**
		 * Chunk header type in OM format
		 */
		typedef OMFormat::Chunk::Header ChunkHeader;
		
		/**
		 * Property name type in OM format
		 */
		typedef OMFormat::Chunk::PropertyName PropertyName;

		/**
		 * Auxiliary storage variable
		 */
		mutable size_t       bytes_;

		/**
		 * Auxiliary storage variable
		 */
		mutable Header       header_;

		/**
		 * Auxiliary storage variable
		 */
		mutable ChunkHeader  chunk_header_;

		/**
		 * Auxiliary storage variable
		 */
		mutable PropertyName property_name_;

		/**
		 * Method reads binary channel and extracts vertex information
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		bool read_binary_vertex_chunk(mds::mod::CChannel &_is, BaseImporter &_bi, Options &_opt, bool _swap) const;

		/**
		 * Method reads binary channel and extracts face information
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		bool read_binary_face_chunk(mds::mod::CChannel &_is, BaseImporter &_bi, Options &_opt, bool _swap) const;

		/**
		 * Method reads binary channel and extracts edge information
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		bool read_binary_edge_chunk(mds::mod::CChannel &_is, BaseImporter &_bi, Options &_opt, bool  _swap) const;

		/**
		 * Method reads binary channel and extracts half edge information
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		bool read_binary_halfedge_chunk(mds::mod::CChannel &_is, BaseImporter &_bi, Options &_opt, bool _swap) const;

		/**
		 * Method reads binary channel and extracts mesh information
		 * @param _is Input MDSTk channel
		 * @param _bi Base importer used for reading
		 * @param _opt Options for writing
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		bool read_binary_mesh_chunk(mds::mod::CChannel &_is, BaseImporter &_bi, Options &_opt, bool _swap) const;

		/**
		 * Method reads binary channel and extracts custom data
		 * @param _is Input MDSTk channel
		 * @param _bp Base property used for reading
		 * @param _n_elem Number of elements to read
		 * @param _swap Swap bytes flag
		 * @return True, if reading was successful
		 */
		size_t restore_binary_custom_data(mds::mod::CChannel& _is, BaseProperty* _bp, size_t _n_elem, bool _swap) const;
};

} // namespace IO
} // namespace OpenMesh

#endif