/*
* This file is part of robotreality
*
* Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
* http://opensource.cit-ec.de/projects/robotreality
*
* This file may be licensed under the terms of the
* GNU General Public License Version 3 (the ``GPL''),
* or (at your option) any later version.
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the GPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the GPL along with this
* program. If not, go to http://www.gnu.org/licenses/gpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The development of this software was supported by the
* Excellence Cluster EXC 277 Cognitive Interaction Technology.
* The Excellence Cluster EXC 277 is a grant of the Deutsche
* Forschungsgemeinschaft (DFG) in the context of the German
* Excellence Initiative.
*
*/

#ifndef MarkerModel_H
#define MarkerModel_H

#include <math.h>
#include <stdlib.h>
#include "BlobFinder.h"
#include "ConfigOptions.h"
//#include "hungarian_lib/munkres.h"
#include "munkres.h"
#include "Marker.h"



class MarkerModel{
public:
	MarkerModel(ConfigOptions *c);
	void update(blob_vector_t blobs);
	
	void initialise_face_model();
	
// 	blob_vector_t get_candidates();
	void overlay_blobs_on_image(Mat *image);
	void overlay_text_on_image(Mat *image);
	
	void remove_translation_and_rotation(Mat rt);
	
	marker_vector_t get_eye_marker_vector(){ return face_eye_marker_vector; }
	marker_vector_t get_mouth_marker_vector(){ return face_mouth_marker_vector; }
	marker_vector_t get_nose_marker_vector(){ marker_vector_t nv; nv.push_back(face_eye_marker_vector[EYE_NOSE_UPPER]);nv.push_back(face_eye_marker_vector[EYE_NOSE_LOWER]); return nv;}
	
	
	Marker get_eye_marker(int id){ if (id < face_eye_marker_vector.size()) return face_eye_marker_vector[id]; else return Marker(); }
	
	double get_mouth_displacement_x(int enum_index);
	
	enum FACEMODEL_MOUTH_ENUM {
		MOUTH_LEFT_UPPER,
		MOUTH_LEFT_LOWER,
		MOUTH_CENTER_UPPER,
		MOUTH_CENTER_LOWER,
		MOUTH_RIGHT_UPPER,
		MOUTH_RIGHT_LOWER
	};

	enum FACEMODEL_EYE_ENUM {
		EYE_LID_LEFT_UPPER,
		EYE_LID_LEFT_LOWER,
		EYE_LID_RIGHT_UPPER,
		EYE_LID_RIGHT_LOWER,
		EYE_BROW_LEFT_I,
		EYE_BROW_LEFT_O,
		EYE_BROW_RIGHT_I,
		EYE_BROW_RIGHT_O,
		EYE_NOSE_UPPER,
		EYE_NOSE_LOWER
		
	};
private:
// 	void detect_mouth_marker(blob_vector_t blobs);
// 	blob_vector_t input_blobs;
// 	double get_typical_blobsize();
	ConfigOptions *cfg;

	void render_line(Mat *image, marker_vector_t m , int index_a, int index_b, int r, int g, int b);
	void render_line_zero(Mat *image, marker_vector_t m, int index_a, int index_zero, int r, int g, int b);
	void render_circle(Mat *image, marker_vector_t m, int index_a, int r, int g, int b);
	void render_ellipse(Mat *image, marker_vector_t m, int index_a, int index_b, int r, int g, int b);
	
	void mouth_check_above_and_swap(int a, int b);
	void mouth_check_left_and_swap(int a, int b, int c);
	void mouth_model_process();
	void eye_model_process();
		
	
	void check_above_and_swap(marker_vector_t *vect, int a, int b);
	void check_left_and_swap(marker_vector_t *vect, int a, int b);
	void check_left_and_swap3(marker_vector_t *vect, int a, int b, int c);

	marker_vector_t face_eye_marker_vector;
	marker_vector_t face_mouth_marker_vector;
	
	marker_vector_t eyes_input_vector;
	marker_vector_t mouth_input_vector;
// 	blob_vector_t candidates;
	int boundingbox_size_min;
	int boundingbox_size_max;
	int pixelcount_min;
	bool model_uninitialised;
	
	Point2d mouth_center_pos_fixated[MOUTH_ENUM_SIZE];
	Point2d mouth_zero_pos[MOUTH_ENUM_SIZE];
	Point2d mouth_zero_pos_fixated[MOUTH_ENUM_SIZE];
	
	Munkres munk_resolver;
	int frame_number;
// 	FaceModel face_model;
};

#endif