#pragma once
#ifdef OLIVIA_COMPILA
#include <float.h>
#include <math.h>
#include "mapmatrix.h"
#include <map>

#ifndef EXT_ARCH_DIJ_DEFAULT
#define EXT_ARCH_DIJ_DEFAULT	"ndj"
#define NOMB_ARCH_DIJ_DEF		"snodos_dj"
#endif

/**
*	@file olv_geom.h
*	Archivo de declaraciones de clase de varias utilidades geométricas del programa Olivia.
*/
#define OLV_PI				4.0*atan(1.0)
//**************************************************************************************************************************
/**
 * Estructura de nodo para el cálculo de caminos óptimos por Dijkstra
 */
struct Djkt_nodo_0
{
       int		id_padre;		//<Indice al nodo padre, o nodo hijo en el cálculo del dijsktra invertido
       float	dis;			//<Distancia
       BOOL		visto;			//<Indica si se ha pasado ya por el nodo
};

/**
 * Estructura de elemento de la cola para el cálculo de caminos óptimos por Dijkstra
 */
struct Djkt_elem_cola
{
       int				id;				//<Id de elemento
	   int				id_inci;		//<Id del elemento desde el que se ha llegado a id
       Djkt_elem_cola	*sig;			//<Puntero al siguiente elemento
};
struct Djkt_nodo;
/**
 * Estructura de cola con prioridad para el cálculo de caminos óptimos por Dijkstra
 */
struct Djkt_cola
{
	   int				nn;
       Djkt_nodo		*nodos;		//<Puntero a matriz de nodos
       Djkt_elem_cola	*elem;		//<Puntero a elementos almacenados
       //Funciones
       void inicia(Djkt_nodo *n);
       BOOL pon(int i);
	   BOOL pon(int i,int i_inci);
	   int dame();
	   int dame(int *id_inci);
};
/*
 * Estructura de ángulos entre conjunciones adyacentes para añadir al Dijkstra el ángulo de giro
 */
typedef struct Djkt_ids_pdr
{
	int				id;		//id padre al que tienes que ir
	float			dis;	//distancia que vas a recorrer
}Djkt_ids_pdr;
struct HeadCostAng;
/*
 * Estructura de ángulos entre conjunciones adyacentes para añadir al Dijkstra el ángulo de giro
 */
typedef struct Djkt_ang_ady
{
	int					nady;
	Djkt_ids_pdr		*ids_padre;
	int					bas1;
	int					*i_conjs;
	int					bas2;
	BYTE				**angs;
	int					bas3;
	//*******************************************
	Djkt_ang_ady();
	void libera();
	BOOL inicia(int n, BOOL no_angs=FALSE);		
	BOOL dame_ii_jj(int i, int j, int *ii_,int *jj_);
	BOOL pon_ang_i_j(int i,int j, BYTE ang);
	BOOL dame_ang_i_j(int i,int j, BYTE *ang, BOOL inds_abs);
	BOOL pon_padre(int i_orig,int j_padre, double dis, BOOL inds_abs);
	BOOL dame_padre(int i_orig,int *j_padre, double *dis, BOOL inds_abs);
	BOOL inicia_ids();
	void libera_ex();
	BOOL guarda(HeadCostAng hd, int ic, char *path , char *ext);
	BOOL lee(int ic, char *path , char *ext);
}Djkt_ang_ady;
//*************************************************************************************
struct Djkt_nodo: public Djkt_nodo_0
{
	Djkt_ang_ady	ids_ady;
	//Funciones
	void inicia();
	BOOL inicia_ex(Djkt_ang_ady *ang);
	void libera( );
};
//*************************************************************************************
/**
*	Clase de varias utilidades geométricas del programa Olivia.
*/
class Colv_geom
{
public:
	//*************************************************************************************
	//Variables

	//*************************************************************************************
    //Funciones
	Colv_geom(void);
	~Colv_geom(void);
	static double ang_vect(double v1[2], double v2[2]);
	static BOOL pto_equals(double pt1[3], double pt2[3], BOOL d3 =FALSE);
	static BOOL haz_paralela(double (*ptos_orig)[3],int np,double dis,double (**ptos_par)[3]);
	static int dame_ind_per(int i, int iold, int inew);
	static int dame_n_nucleos();
	static int fact(int i);

	static BOOL dijkstra_ang_inv_ok(CmapMatFloat &costes, Djkt_ang_ady *angs, int n, int fin, Djkt_nodo **nodos, BYTE **visto_ang_);
	static double ruta_dj_inv(int id_ini, int *secu, Djkt_nodo *nodos, int nmax, int *n);
	static double ruta_dj_inv_ok(int id_ini, int *secu, Djkt_nodo *nodos, int nmax, int *n);	
};

//*************************************************************************************
/**
*	Clase de manejo de archivos de nodos djtra
*	cada archivo tiene un numero de bloques o array de nodos de longitud fija "nnod"
*/
//estructura cabecera de archivo
typedef struct Head_dj_arch
{
	int version;	//version del archivo
	int nn;			//numero de nodos por bloque
	int nb;			//numero de bloques del dj
	int max_conex;	//maximo de conexiones por nodo
	
}Head_dj_arch;
#define VERSION_DJ_ARCHI	100
#define MAX_CONEX_DJ_ARCHI	16
struct Info_aso2;
class Cdijkstra_arch
{
public:
	char path[MAX_PATH];//nombre sin extension
	Head_dj_arch hd;//cabecera de archivo
	int sizn;//tamaño en BYTES de cada nodo
	BOOL salta_ids_padres;
	//int flags;//0x1-->modo escritura 0x2-->modo lectura
	//info de distancias ambitos
	float *dis;//distancia de un nodo a otro (matriz de nnod*nnod)
	int nod_amb;//nodos por ambito
	int nambi;//numero de ambitos
	int nnod;//numero de nodos por fila
	int id_instal;//fila planta
	int id_plan;//fila instal
	int nod_instal;//nodo instalacion
	int nod_plan;//nodo planta
	int tip_ambitos;

	std::map<int,Info_aso2> *ia;//puntero a info asoc
	
	//funciones--------------------------------------------------------------------------
	Cdijkstra_arch();
	~Cdijkstra_arch();

	BOOL inicia(char* path_arch, BOOL nuevo=FALSE, int n_nod=0, int max_conex=MAX_CONEX_DJ_ARCHI);//si nuevo -> crea vacio
	BOOL add_b(Djkt_nodo* blq, int iref, int inod, BOOL pon_inf=FALSE);//añade un bloque a el archivo
	BOOL inicia_inf_amb(std::map<int,Info_aso2>* ina, int namb,int tip_amb, int id_instal=-1, int id_plan=-1);
	void pon_info_amb(Djkt_nodo* nodos, int iref,int  ib);
	Djkt_nodo* get_b(int iref, int ibloq, Djkt_nodo* buf=NULL);//develve el bloque ibloq-esimo
	float dame_dis(int aorig,int norig, int ades, int n_des);

	Djkt_nodo* dame_buf_nodos(BOOL angulos=FALSE );
	void libera_buf(Djkt_nodo* buf );
	BOOL lee_dis();
	BOOL graba_dis(int id);
};
#endif



