#pragma once
#ifdef OLIVIA_COMPILA
#include "olv_thr.h"
#include "olv_limp_def.h"
//utiles
#include "OlvAsync_cola.h"
#include "CartoBaseElements.h"
#include "CartoBase.h"
#include "Fdbf.h"
#include "b_file.h"
#include "ManagerDbfGdataTable.h"

/**
*	@file olv_limp_thr.h
*	Archivo de definiciones del thread de control de la utilidad de limpieza viaria del programa Olivia.
*/

class Colv_limp;
class Colv_csv;
class Colv_limp_thr;
class Colv_tasks;
struct Info_inw_dmin;
struct Info_conjs;
struct Info_sec;
struct Info_amb_sec;
struct Info_amb_arbol;
struct Info_rut;
struct Info_est_amb;
struct Djkt_nodo;
struct Secu_amb;
struct Info_planif;
struct th_param_planif;
struct Djkt_ang_ady;
struct HeadCostConj;
struct HeadCostAng;
/**
 * Estructura de parámetros de comunicación con el thread de cálculo de limpieza
 */
typedef struct Param_olv_limp_thr
{
	int		id_e;
}Param_olv_limp_thr;
//*******************************************
/**
 * Clase extendida para rellenar los datos del dbf
 */
class AddColsDbf : public IAddColDbf
{
public:
	char *info;
	
	AddColsDbf(char *info)
	{
		this->info=info;		
	}
	virtual void setData(int i, void *data)
	{		
		if(data)
		{			
			memcpy(data,(void*)&info[i* size], size);
		}

	};
};
//*******************************************
/**
*	Clase del thread de control de la utilidad de limpieza viaria del programa Olivia.\n
*	Contiene el grueso de cálculos, tanto de la parte de limpieza como de recogida de residuos, todos los algoritmos de\n
*	sectorización y planificación, cálculo de costes, etc.
*/
//******************************************************************************************************
class Colv_limp_thr : public Colv_thr, public OlvAsync_cola<Param_olv_limp_thr>
{
public:
	//*************************************************************************************
    //Variables
	enum Ev_olv_limp_thr ///<Tipos de eventos de la cola de ejecución del proceso
	{
		OLV_LIMP_EV_ABRE_DAT,
		OLV_LIMP_EV_RELL_DAT,
		OLV_LIMP_EV_UNE_AMB_NW,
		OLV_LIMP_EV_TOPO_NW,
		OLV_LIMP_EV_COST_CONJ,
		OLV_LIMP_EV_ANG_CONJ,
		OLV_LIMP_EV_COST_AMB,
		OLV_LIMP_EV_CALC_NSEC,
		OLV_LIMP_EV_CALC_NSEC_FIN,
		OLV_LIMP_EV_SECTORIZA,
		OLV_LIMP_EV_PLANIFICA,
		OLV_LIMP_EV_LEE_SECTO,
		OLV_LIMP_EV_COST_CONJ_SUB,
		OLV_LIMP_EV_COST_CONJ_FIN,
		OLV_LIMP_EV_ANG_CONJ_SUB,
		OLV_LIMP_EV_ANG_CONJ_FIN,
		OLV_LIMP_EV_COST_AMB_SUB,
		OLV_LIMP_EV_COST_AMB_FIN,
		OLV_LIMP_EV_PLANIFICA_SUB,
		OLV_LIMP_EV_PLANIFICA_FIN,
		OLV_LIMP_EV_SUBTHR_PROG,
		OLV_LIMP_EV_GUARD_MATS,
		OLV_LIMP_EV_GUARD_MATS_SUB,
		OLV_LIMP_EV_GUARD_MATS_FIN,
		OLV_LIMP_EV_TASK_ESCUCHA,
		OLV_LIMP_EV_TASK_FIN,
		OLV_LIMP_EV_BARRMIX,
		OLV_LIMP_EV_BARRMIX_SUB,
		OLV_LIMP_EV_BARRMIX_FIN,
		OLV_LIMP_EV_COMPCORT,
		OLV_LIMP_EV_COMPCORT_SUB,
		OLV_LIMP_EV_COMPCORT_FIN,

		OLV_LIMP_EV_N
	}Ev_olv_limp_thr;

	BYTE						*visto_ang;		
	int							n_subthr_fin;
	int							n_subthr;
	int							n_subthr_mal;
	double						prog_subthr;
	BOOL						pirate;
	BOOL						fin_permu;
	char						err_str[OLV_MAX_ERR];	
	CartoBase					carto_rut, carto_ctrl,carto_flech, carto_inst;
	Fdbf						dbf_cols;
	Cb_file						f_cols;	
	Colv_limp					*olv_limp;	
	Colv_limp_thr				*thr_padre;
	Colv_limp_thr				**subthrs;				///<Array de threads
	
	//*************************************************************************************
    //Funciones
	Colv_limp_thr(Colv_limp *olv_limp);
	virtual ~Colv_limp_thr(void);
	/////////////////////
	void inicia_th();
	void termina_th();
	static void cola_proc(int evento,OlvAsync_cola<Param_olv_limp_thr> *clase,Param_olv_limp_thr *e);

	//Apertura de los datos de partida
	BOOL abre_datos();

	//Rellena la info de los datos de partida
	virtual BOOL rellena_datos();
	BOOL rellena_info_nw();
	BOOL rellena_info_amb();
	BOOL replica_peat();
	void mejora_barr_mix();
	void mejora_barr_mix_sub(int ithr);
	BOOL mejora_barr_mix_fin();
	BOOL barr_mix_paralelas(CartoBaseInfoEntity ient1, CartoBaseInfoEntity ient2);
	void copia_info_barr_mix();
	//Unión de ámbitos a la red navegable
	BOOL une_amb_nw(int soloi=-1);
	int is_dmin(double daux, Info_inw_dmin *inww);	
	BOOL busca_inw_dmin(int i_amb);
	BOOL busca_inw_dmin_ejes(int i_amb);
	void add_uniones_obj(int i_amb);
	void comprueba_amb_lejos(int i_amb );
	void comprueba_aislados(Info_inw_dmin *inww);
	BOOL comprueba_latelaridad();
	void compr_cortes_amb();
	void compr_cortes_amb_sub(int ithr);
	BOOL compr_cortes_amb_sub_fin();
	//Generación de topología
	BOOL replica_doble_sent(Info_inw_dmin *inww_ord);
	BOOL topo_nw();
	static int compara_inww_amb (const void * a, const void * b);
	void borra_rep();

	//Métodos para multithread
	virtual void lanza_subthrs(int tar, int nthr_def=-1);
	void para_subthrs();
	
	//Cálculo del coste entre conjunciones
	BOOL calcula_cost_conj();
	BOOL add_conj(Info_conjs *conjs, double coor[3]);
	BOOL cuida_memo_conj(Info_conjs *conjs);
	BOOL busca_conjs();
	void calcula_cost_conj_sub(int ithr);
	BOOL calcula_cost_conj_fin();
	void calcula_cost(int refent, float *cost, float *cost2);
	//Cálculo de ángulos entre conjunciones
	BOOL calcula_ang_conj();
	void calcula_ang_conj_sub(int ithr);
	double dame_ang_conj(int ic, int i, int j);
	BOOL calcula_ang_conj_fin();
	void revisa_calles_cortadas();
	
	//Cálculo del coste entre ámbitos
	void invierte_nodos(int nn, int KK,Secu_amb * ord_sec, BOOL *pirate);
	BOOL calcula_cost_amb();
	BOOL inicia_cost_amb();
	BOOL calcula_cost_amb_fin();
	void calcula_cost_amb_sub(int ithr);
	BOOL avisa_aislados();
	void prueba_costs();
	
	//Sectorización
	BOOL sectoriza();
	BOOL pide_memo_secto();
	
	//Métodos auxiliares para sectorización
	BOOL add_amb_sec(int i_amb, int namb, int i_sec, Info_sec *ss, Info_amb_sec *aa,  Matrix2d<float> &cost_amb, double cost_tot, int i_amb_p=-1);
	void quita_amb_sec(int i_amb, int namb, int i_sec, Info_sec *ss, Info_amb_sec *aa,  Matrix2d<float> &cost_amb, int i_amb_p=-1);
	BOOL sectoriza_1();
	double dame_desv_sec(int nsec, Info_sec *ss, BOOL porc =FALSE, double *absol=NULL);
	BOOL sectoriza_2(double *cost_ac_);
	double iguala_sectores3(int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa, Secu_amb * ord_sec=NULL, th_param_planif *thp=NULL);
	double iguala_sectores4(int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa);
	double iguala_sectores5(int iamb, int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa);
	BOOL calcula_coste_sectores(Secu_amb * ord_sec,Info_sec *ss,int n_sec, th_param_planif *thp=NULL, BOOL loguear=FALSE );
	BOOL calcula_coste_1sec( Secu_amb * ord_sec, Info_sec *ss, th_param_planif *thp, BOOL loguear );
	int asigna_padres(int amb_central, int namb,  Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa, int *buf, int nhijos_fron);
	int busca_sec_cerca_amb(Info_amb_sec *aa,int iamb, int id_sec, int modo=0);
	BOOL genera_sectores3(int iamb_extr, int n_amb, int n_sec,  Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa);
	BOOL genera_sectores(int iamb_extr, int n_amb, int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa);
	double dame_dmed_amb_sec(int iamb, int isec);
	double dame_dmed_amb(int iamb1, int iamb2);
	BOOL genera_sectores_pro(int n_sec, Matrix2d<float> &cost_amb, Info_sec *ss, Info_amb_sec *aa);
	BOOL add_amb_sec_cost(int i_amb, int namb, int i_sec, Info_sec *ss, Info_amb_sec *aa, Matrix2d<float> &cost_amb);
	BYTE* guarda_estado(int namb,int  n_sec, Info_amb_sec *aa, Info_sec *ss,BYTE *buf );
	BOOL pon_estado(int namb,int  n_sec, Info_amb_sec *aa, Info_sec *ss,  Matrix2d<float> &cost_amb, BYTE *st );
	int* ordena_sec(int  n_sec, Info_sec *ss, int *buf);//ordena sectores de mayor a menor coste
	int  recorre_hijos(int  iamb, int namb, Info_amb_sec *aa, int *iamb_r, int namb_r,  Matrix2d<float> &cost_amb, double *cost, BOOL inicia=TRUE);
	BOOL actualiza_costes(int namb,int  n_sec, Info_amb_sec *aa, Info_sec *ss,  Matrix2d<float> &cost_amb);
	static int compara_dist_cerc (const void * a, const void * b);

	//Lee secto
	BOOL lee_secto();

	//Calcula el número de sectores
	BOOL calcula_n_sec();
	virtual double dame_cost_jornada();
	double calcula_cost_1sec_total(int n_amb, Info_sec *ss, Djkt_ang_ady *ang_conj);

	//Planificación
	BOOL planifica();
	virtual void planifica_sub_1(int ithr,  Matrix2d<float> &cost_amb);
	BOOL planifica_fin();

	//Métodos para guardado post-planificación
	BOOL genera_planif(int is, double cost_sec, int nsecu, int *secu, int tip_plan);
	BOOL genera_planif_aux(int is, Info_sec *ss, Info_planif *pp, int nsecu, int *secu, int tip_plan);
	BOOL genera_planif_instala(int is, int nvaciados, int ini, int fin, int *secu, int tip_viaje);
	BOOL guarda_shp_rut_ctrl();
	BOOL genera_list_rut_ctrl();
	virtual void quita_t_ult_desc(int s, double *t);
	virtual BOOL genera_list_fila_vaci(Colv_csv *cc, char *fila0,int ielem, int s, int ii, double tt, double *t0,BOOL is_fin);
	BOOL guarda_dbf_sector(int modo);	
	virtual BOOL gen_guard_subtramos();
	BOOL genera_rut_aux(Info_planif *pp, int is, BOOL is_insta, int ie_ini, int ie_fin);
	BOOL genera_rut_ctrl(int ns, Info_planif *planif, BOOL tramos);
		
	//Métodos auxiliares para Planificación
	short dame_planif_iamb_ini(Info_sec *s,Matrix2d<float> &cost_amb, short *ent=NULL);
	Secu_amb * planifica_sect(Info_sec *s, Djkt_ang_ady *ang_conj, int npermu);
	BOOL busca_cercano(Info_sec *s, Secu_amb *sec, int isec, BOOL ind_abs=FALSE);
	virtual double dame_coste(Secu_amb * sec, int ini, int fin, Info_sec	*s, BOOL ind_abs=FALSE);
	BOOL permuta(Secu_amb * sec, int ini, int fin, int p, Secu_amb * sec_out);
	double dame_coste_ex( Secu_amb * sec ,  int ini, int fin, Info_sec *s, int pos_old, int pos_new, int entr );
	void cambia_elem(Secu_amb * sec,int pos_old, int pos_new, int entr);
	BOOL esta_repe( Secu_amb *sec, int nsec, BOOL log=FALSE );
	void pon_info_resul();
	double dame_mima(int nsec, Info_sec *ss, double *mini=NULL);
	double dame_dif_mima(int nsec, Info_sec *ss);
	BOOL rellena_amb_cercanos_por_carretera(int namb,  Info_amb_sec *aa, Secu_amb * ord_sec);
	double dis_min_amb(int ids[2], int id_nod_ini, Secu_amb * ord_sec, BOOL res_nod, int iamb);
	virtual void pon_ptos_ctrl(Info_planif *pp, int npt_ctrl, double cost_ctrl);
	
	/////////////////////////////	
	virtual BOOL pon_nodos_planta(double pt[3]);
	virtual BOOL busca_conjs_planta(double pt[3], int *nod);
	virtual BOOL calcula_cost_plant();
	void dame_h_m_s(double tt, int *h, int *m, int *s);
	virtual BOOL guarda_cols_ruta(char *path_shp);
	BOOL guarda_cols_ctrl(char *path_shp);
	virtual BOOL guarda_cols_insta(char *path_shp);
	virtual void pon_t_desp(Info_sec *s, Secu_amb *sec);
	virtual BOOL comprueba_descarg(int iamb);
	virtual void dame_observ_cont(int iamb,char *observ);
	BOOL quita_islas(int namb, Info_amb_sec *aa, Secu_amb * ord_sec);

	//Guardado de matrices
	BOOL guarda_mats();
	void guarda_mats_sub(int ithr);
	BOOL guarda_mats_fin();
	BOOL guarda_iaso();

	//Cálculo en tasks de costes entre ámbitos
	BOOL lanza_tasks(int nthr_def=-1);
	BOOL task_dj_escucha();
	BOOL task_dj_fin();
	void borra_temp_files(BOOL todo=TRUE);

	//Para los viajes
	void cuenta_tramos();
	virtual void rellena_tramos();
	BOOL combina_rut_insta();
	virtual int rellena_insta_tramos();
	virtual BOOL guarda_cols_ruta_tram(char *path_shp);
	void ini_infotask(int ntasks);
};
#endif