/*
 *	osgART/GenericTracker
 *	osgART: AR ToolKit for OpenSceneGraph
 *
 *	Copyright (c) 2005-2007 ARToolworks, Inc. All rights reserved.
 *	
 *	Rev		Date		Who		Changes
 *  1.0   	2006-12-08  ---     Version 1.0 release.
 *
 */
/*
 * This file is part of osgART - AR Toolkit for OpenSceneGraph
 *
 * Copyright (c) 2005-2007 ARToolworks, Inc. All rights reserved.
 *
 * (See the AUTHORS file in the root of this distribution.)
 *
 *
 * OSGART is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * OSGART 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OSGART; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */



#ifndef OSGART_GENERICTRACKER
#define OSGART_GENERICTRACKER 1


// std include
#include <map>
#include <iostream>

#include <osg/Geometry>
#include <osg/Projection>

// local include
#include "osgART/Export"
#include "osgART/GenericVideo"
#include "osgART/Marker"
#include "osgART/Field"


namespace osgART {

	/* Forward declaration */
	class VideoLayer;

	/**
	 * \class GenericTracker.
	 * 
	 * Base class for a tracker which in the context of AR is an entity 
	 * that connects video streams, markers and their representation in
	 * the virtual environment.
	 */
	class OSGART_EXPORT GenericTracker : public osg::Referenced, 
		public FieldContainer<GenericTracker>
	{
	public:        
		/**
		 * \brief Constructor.
		 *
		 */
		GenericTracker();


		/** 
		 * \brief update the tracking.
		 * 
		 * This core function apply the Generic algorithm on the last 
		 * image defined by setImage.
		 */
		virtual void update() = 0;

	
		/**
		 *
		 */
		virtual bool init(int xsize, int ysize, 
			const std::string& pattlist_name="Data/markers_list.dat",
			const std::string& camera_name="Data/camera_para.dat") = 0;
	  

		/**
		* \brief get GenericVideo id.
		* \return a GenericVideo identifier.
		*/
		int getId();

		/** 
		* \brief Set the image to analyzed.
		* 
		* \param image the new image for the tracking 
		*/
		virtual 
		void setImageRaw(unsigned char* image, 
			PixelFormatType format = VIDEOFORMAT_GREY8);
	    
		/** 
		* \brief set the image to analyzed.
		* 
		* @param video the video object to use
		*/
		virtual void setImage(GenericVideo* video);
	    
		/** 
		* \brief XXX.
		* 
		* XXX.
		*/
		virtual Marker* getMarker(int markerId);
		
		unsigned int getMarkerCount() const;
		
		/** 
		* \brief get the openGL projection matrix.
		* 
		* delivers a usable matrix with openGL code (glLoadMatrixf(proj) with GL_MODELVIEW).
		* @param proj the openGL projection matrix computed
		*/
		virtual const double* getProjectionMatrix() const;
		
			
	    
	protected:		
	
	
		/**
		 * Creates an undistorted mesh, according to the 
		 * parameters know to the tracker
		 * \param width width of the actual video
		 * \param height height of the actual video
		 * \param maxU texture coordinate maximum in u direction
		 * \param maxV texture coordinate maximum in u direction
		 * \param geometry geometry to be filled with an
		 * undistorted mesh
		 */
		virtual void 
		createUndistortedMesh(int width, int height,
			float maxU, float maxV,
			osg::Geometry &geometry);
		
		/* only videolayer and the container needs to access protected methods */	
		friend class VideoLayer;
		friend class TrackerContainer;
	
		/** 
		 * \brief destructor.
		 *
		 */
		virtual ~GenericTracker();
	
		/**
		 * type for a vector of reference counted markers.
		 */
		typedef std::vector< osg::ref_ptr<Marker> > MarkerList;
		
		
		/**
		 * A list of markers associated with this tracker.
		 */ 
		MarkerList m_markerlist;

		
		unsigned char		*m_imageptr;
		PixelFormatType		 m_imageptr_format;
		
		
		double m_projectionMatrix[16];
	  
	private:

		int trackerId;
		static int trackerNum;
	};


	class OSGART_EXPORT TrackerContainer : public GenericTracker {
	public:

		TrackerContainer(GenericTracker* tracker);

		void update();

		
		virtual bool init(GenericVideo* video, 
			const std::string& pattlist_name="Data/markers_list.dat",
			const std::string& camera_name="Data/camera_para.dat");
		
		
		virtual osg::Projection* createProjection() const;
		

	protected:
	
		virtual bool init(int xsize, int ysize, 
			const std::string& pattlist_name="Data/markers_list.dat",
			const std::string& camera_name="Data/camera_para.dat");
	

		void createUndistortedMesh(int,int,
			float,float,osg::Geometry&);

		virtual ~TrackerContainer();

		osg::ref_ptr<GenericTracker> m_tracker;		
		osg::ref_ptr<GenericVideo> m_video;

	};


};

#endif
