#ifndef _StreamableGeometry_h__
#define _StreamableGeometry_h__

#include <Geometry/IFileSerialisable.h>
#include <Geometry/IGeometry.h>
#include <Geometry/SRS.h>
#include <boost/shared_ptr.hpp>
#include <buildspec.h>
#include <config.h>

namespace GST
{
namespace Geometry
{

/**
 * This interface is used by ClientUtils::NetworkInterface to serialize the
 * geometry, possibly back and send to the database.
 *
 * You can overload the methods producing the output direct form your geometry.
 *
 * If you want to stay away from generating output, it is recommenced to use the
 * GeometryBuilder and represent your geometry including properties there. It
 * will produce the output for you.
 *
 * @see GeometryBuilder
 */
class GST_API_EXPORT StreamableGeometry
{
public:
	typedef std::vector<std::pair<std::string, std::string>> KeyValueList;
	typedef boost::shared_ptr<KeyValueList> KeyValueListPtr;

	/**
	  * Writes the geometry the an output stream. It's allowed to produce any
	  output that can be read by GST Storage.
	  * The most easy format is WKT (well known text) of the Simple Feature
	  Standard from OGC (http://www.opengeospatial.org/standards/sfs)
	  *
	  * A Parser reading this format is included in include_wktGrammar.h.
	  * You can test your output against this Parser using the following code.
	  \code
	  std::stringstream output_geometry;
	  gb.serializeGeometry(output_geometry);
	  boost::shared_ptr<GeometryBuilder> constructed_Geometry =
	  boost::make_shared<GeometryBuilder>(); try{
		parseGeometry(constructed_Geometry,output_geometry.str());
		//good
	  }catch(const std::exception& e){
		//bad
	  }
	  \endcode
	  *
	  * If you want to stay away from generating output, it is recommenced to
	  use the GeometryBuilder and
	  * represent your geometry including properties there. It will produce the
	  output for you.
	  *
	  * @see GeometryBuilder
	  */
	virtual bool serializeGeometry(std::ostream &os) const = 0;

	/**
	 * If you want to stay away from generating output, it is recommenced to use
	 * the GeometryBuilder and represent your geometry including properties
	 * there. It will produce the output for you.
	 *
	 * @see GeometryBuilder
	 */
	virtual bool serializeSimplexPropertyValues(std::ostream &os) const = 0;

	/**
	 * If you want to stay away from generating output, it is recommenced to use
	 * the GeometryBuilder and represent your geometry including properties
	 * there. It will produce the output for you.
	 *
	 * @see GeometryBuilder
	 */
	virtual bool serializeSimplexPropertyDescription(std::ostream &os) const
		= 0;

	virtual std::string GetName() const = 0;
	virtual IGeometry::Color GetColor() const = 0;
	virtual IGeometry::TransparencyCode GetTransparency() const = 0;
	virtual Geometry::SRSPtr GetSRS() const = 0;
	virtual KeyValueListPtr GetVariousProperties() const = 0;

protected:
	virtual std::string constructSendHeader(IFileSerialisable::FileType ftype,
											const int &size) const
	{
		std::stringstream sendingheader;

		sendingheader << "{"; // json doc start
		sendingheader << "\"items\":["; // main array

		WriteJsonHeaderPart(sendingheader, ftype, size);

		sendingheader << "]"; // main array
		sendingheader << "}"; // json doc end

		return sendingheader.str();
	}
	virtual void WriteJsonHeaderPart(std::stringstream &sendingheader,
									 IFileSerialisable::FileType ftype,
									 const int &size) const
	{
		sendingheader << "{\"type\":\""
					  << IFileSerialisable::FileType2JsonSendingType(ftype)
					  << "\",";
		sendingheader << "\"size\":" << size << "}";
	}
};

} // namespace Geometry
} // namespace GST

#endif // _StreamableGeometry_h__
