/*
 * $Id: objparser.h,v 1.16 2008-06-06 20:02:36 kybav1 Exp $
 *
 * Description  : One line description of file.
 * Author       : Antonin Misek <antonin.misek@skoda-auto.cz>
 *
 * Purpose      :
 *     Long description of what the file is for.
 */


#ifndef __OBJPARSER__H__
#define __OBJPARSER__H__

#include "scene.h"
#include "geometrytriangles.h"
#include "textparser.h"
#include <wx/hashset.h>


namespace VRUT
{
	class Module;

	///Class for parsing OBJ files
	class OBJParser
	{
	private:
		class IOObjJob : public ThreadPoolJob
		{
			smart_pointer_v2<Scene> scene;
			GeometryTriangles *geoTri;
		public:
			//IOObjJob() : ThreadPoolJob(), type(JOB_NONE), scene(NULL), geometryID(GEOMETRY_ID_NONE), cost(0), module(NULL) {}
			//IOObjJob(smart_pointer_v2<Scene> &scene, GeometryTriangles *geoTri, Module *module) : ThreadPoolJob(), scene(scene), geoTri(geoTri), module(module) {}
			IOObjJob(Scene *scene, GeometryTriangles *geoTri) : ThreadPoolJob(), scene(scene), geoTri(geoTri) {}
			virtual ~IOObjJob() {}
			virtual void Run()
			{
				if (scene && geoTri)
				{
					geoTri->UnifyVertices();
					scene->AddGeometry(geoTri);
				}
			}
		};
		///Input stream
		wxInputStream * inputStream;
		///Scene container ID to be built
		SCENE_ID sceneID;
		///Path to scene resources, can be archive filename
		wxString fileName;
		///Parent module's interface
		Module * module;

		///current material name
		wxString materialName;
		WX_DECLARE_HASH_SET( wxString, wxStringHash, wxStringEqual, MaterialSet );
		MaterialSet materialSet;

		///current node name
		wxString nodeName;
		///material library
		wxString materialLib;
		bool isMaterialLib;

		///Parse indices
		bool parseIndices(TextParser &textParser, GeometryTriangles *geoTri, GeometryTriangles::PRIMITIVE_TYPE primType, std::vector<Vector3> &v,
			std::vector<GeometryTriangles::TexCoord> &vt, std::vector<Vector3> &vn);

		///Create GeometryNode, Geometry and Material
		void createNodeGeometryMaterial(Scene *scene, GeometryTriangles *geoTri, NODE_ID rootID, const wxString &nodeName, const wxString &materialName, const bool optimize);

		///Parse file
		bool parseFile(Scene *scene, NODE_ID rootID, const bool optimize);

	public:
		///Class constructor
		///\param[in] _inputStream Stream to read data from
		///\param[in] _sceneID Scene ID
		///\param[in] _scenePath Path to scene resources (can be an archive filename)
		///\param[in] _module Parent module with messaging interface
		OBJParser(wxInputStream * _inputStream, SCENE_ID _sceneID, const wxString _scenePath, Module * _module);
		///Class destructor
		~OBJParser();

		///Parse OBJ stream and build scene graph
		///\param[in] rootID ID of node that will be root of imported scene
		///\return \c true if successful
		bool Parse(const NODE_ID &rootID, const bool optimize);

		bool isMatLib();
		wxString getMatLibName();
	};
}

#endif

