// CContorno.h. Declaración de la clase CContorno

//** Es la clase que representa el contorno que se obtiene de la imagen.
//** Utiliza la clase CCamino que contendrá los puntos del contorno final.
//** Además, posee otros atributos y funciones necesarios para el correcto
//** funcionamiento de la clase.

#ifndef __CContorno_H__
#define __CContorno_H__

#include "CCamino.h"

class CContorno : public CObject
{
public:	
	int dimensx;		  // Anchura de la imagen (en pixels)
	int dimensy;		  // Altura de la imagen  (en pixels)
	int num_puntos_forma; // Nº de ptos de la forma (área)
	int min_contorno;	  // Longitud mínima que debe tener el contorno
						  // para que sea válido
	int num_vecinos;	  // Numero de vecinos para el filtro anti-ruido
	CCamino contorno;	  // Sucesión de puntos que representa el contorno
public:
	// Constructores
	CContorno();
	CContorno(unsigned char *s, int dimx, int dimy, int numv); // s = imagen
	
	// Destructor
	~CContorno();
public:
	// Función que es llamada desde CImagen para obtener el contorno de la
	// imagen, que se pasa por parámetro como sucesión de 'unsigned chars'
	int ObtenerContornos(unsigned char *s);
private:
	// Busca el primer punto del objeto (blanco) de la imagen que
	// no haya sido utilizado con anterioridad para buscar el contorno
	CPoint CalcularInicio(unsigned char *s);
	// Calcula un contorno a partir de un punto de inicio y termina cuando encuentra
	// el mismo punto de partida (exito) o no consigue cerrar un contorno (no exito)
	void CalcularContorno(unsigned char *s, CPoint actual, CCamino camino, int tiporecta);
	// Calcula el siguiente punto al actual que permita continuar el contorno correctamte.
	void SiguienteVecino(unsigned char *s, CPoint actual, CCamino *camino, CPoint *vecino, int *dir, int tiporecta);
	// Devuelve el siguiente vecino en función del tipo de recta y de la dirección que corresponda
	CPoint CalcularVecino(int dir, CPoint actual,CCamino *camino,int tiporecta);
	// Devuelve false si el punto 'punto' se haya rodeado con puntos del objeto
	// (blanco) por sus 4 vecinos (arriba, abajo, izquierda y derecha). Devuelve true en otro caso
	bool Salida4Vecinos(unsigned char *s, CPoint punto);
	// Devuelve true si existe al menos un punto del fondo (negro) que tenga
	// una distancia = 1 con el primero y una distancia = 1 con el segundo
	bool SalidaComun(unsigned char *s, CPoint primero, CPoint segundo);
	// Devolvemos true si el punto calculado en SiguienteVecino es válido. false en otro caso
	bool EsValido(unsigned char *s, CPoint vecino, CCamino *camino);
	// Nos dice si hemos cerrado el contorno, viendo si son iguales el pto.inicial y el final del camino
	bool FinContorno(CCamino *camino);
	// Devuelve true si el punto indicado por i y j es del objeto (blanco) en s
	bool ExistePunto(unsigned char *s, int i, int j);
	// Elimina de s todos los puntos que se hallen en 'contorno'
	void EliminarPuntos(unsigned char *s, CCamino *camino);
	// Devuelve el tipo de recta que forman los puntos 'actual' y 'vecino' (4 tipos)
	int TipoRecta(CPoint actual,CPoint vecino);
	// Devuelve la distancia de Manhattan que existe entre dos puntos
	int Distancia(CPoint a, CPoint b);
	// Aplica el filtro anti-ruido para evitar que la eliminación del contorno provoque fallos
	void AntiRuido(unsigned char *s, CCamino *camino);
	// Calcula el número de vecinos que tiene un punto de la imagen
	int NumVecinos(int i, int j, unsigned char *s);
};

#endif // __CContorno_H__