#include "StdAfx.h"
#include "ini_file.h"
#include "_error.h"
//*********************************************************************************
Cini_file::Cini_file(C_error* err)
{
	if (err)
	{
		borra_error=FALSE;
		er=err;
	} 
	else
	{
		er= new C_error();
		borra_error=TRUE;
	}
	grupos.z=sizeof(Ini_file_grupo);
}
//*********************************************************************************
Cini_file::~Cini_file(void)
{
	if (er && borra_error)
	{
		delete er;
	}
	borra();
}
//*********************************************************************************
void Cini_file::borra()
{
	Ini_file_grupo*g;
	for (int i=0; i<grupos.n; i++)
	{
		g=(Ini_file_grupo *)grupos.get(i);
		g->prop.borra();
	}
	grupos.borra();
	str.borra();
}
//*********************************************************************************
int Cini_file::get_grupo( char* gr )
{
	Ini_file_grupo *g;
	char*aux;
	//buscamos grupo------------------------------------------------
	for (int i=0; i<grupos.n; i++)
	{
		g=(Ini_file_grupo *) grupos.get(i);
		aux=str.get(g->n);
		if(!(g->flags & INI_FILE_FLAGS_VACIO)&& aux && (strcmp(gr,aux)==0))
			return i;
	}
	//no se encontro-------------------------------------------------
	return -1;
}
//*********************************************************************************
int Cini_file::geti_valor( int gr,char *pro )
{
	Ini_file_grupo *g;
	Ini_file_props *p;
	char* aux;
	g=(Ini_file_grupo *) grupos.get(gr);
	if (!g|| (g->flags & INI_FILE_FLAGS_VACIO))
		return -1;
	//buscamos entre las propiedades del grupo-----------------------
	for (int i=0; i<g->prop.n; i++)
	{
		p=g->get(i);
		aux=str.get(p->p);
		if((!(p->flags & INI_FILE_FLAGS_VACIO))&& aux && strcmp(pro,aux)==0)
			return p->v;
	}
	//no se encontro-------------------------------------------------
	return -1;
}
//*********************************************************************************
char* Cini_file::busca( char *str,char c )
{
	int i=0;
	while(str[i])
	{
		if (str[i]==c)
			return &str[i];
		i++;
	}
	//no encontrado-------------------------------------------
	return NULL;
}
//*********************************************************************************

BOOL Cini_file::lee( char *path )
{
	char *buf=NULL;
	char *ini;
	char *aux;
	Ini_file_grupo *g;
	Ini_file_props *p;
	char log_[128];

	HANDLE hfile=INVALID_HANDLE_VALUE;
	DWORD dw,nb;
	//abrimos archivo---------------------

	hfile = CreateFile(path, GENERIC_READ, 0, NULL, 
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

	if (hfile == INVALID_HANDLE_VALUE)
	{
		er->pon_win(MODULO_INI_FILE);
		return FALSE;
	} 

	nb=SetFilePointer(hfile,0,NULL,FILE_END);
	if(nb==INVALID_SET_FILE_POINTER)
	{
		er->pon_win(MODULO_INI_FILE);
		goto salgo;
	}
	buf=(char *)malloc(nb+2);

	dw=SetFilePointer(hfile,0,NULL,FILE_BEGIN);
	if(dw==INVALID_SET_FILE_POINTER)
	{
		er->pon_win(MODULO_INI_FILE);
		goto salgo;
	}
	if (!ReadFile(hfile, (LPSTR) buf ,nb,&dw,NULL))
	{
		er->pon_win(MODULO_INI_FILE);
		goto salgo;
	}
	CloseHandle(hfile);
	hfile=NULL;
	buf[nb]=0;
	buf[nb+1]=0;//aseguramos el final de la cadena;
	ini=buscamos_grupo(buf);
	//cargamos ini----------------------------
	while(*ini)//mientras no estemos en el final
	{
		//pillamos grupo---------------------
		
		aux=busca(ini,']');
		
		if (!aux)
		{
			break;//no mas grupos-----------
		}
		//añadimos grupo--------------------
		*aux=0;
		g=set_coun();
		g->n=str.size();
		g->flags=0;
		g->inicia();
		str.add(ini);
		ini=aux+2;

		if (*ini=='\r')
			ini=ini+1;
		//buscamos propiedades del grupo---
		while(*ini &&*ini!='[')
		{
			if (*ini=='\n'||*ini==13)
			{
				ini=ini+1;

				if (*ini=='\r')
					ini=ini+1;
			}
			ini=busca_prop(ini);
			if (*ini=='[')
			{
				ini=ini+1;
				break;
			}
			else if(!*ini)
				break;
			else
			{
				aux=ini+strlen(ini);
				//añadimos propiedad------
				p=g->set_coun();
				p->flags=0;
				p->p=str.size();
				str.add(ini);
				ini=aux+1;
				aux=busca(ini,'\n');
				if (!aux)
				{
					sprintf(log_,"lee: archivo ini defectuoso, no se encuentra valor de %s",str.get(p->p));
					er->pon(MODULO_INI_FILE,log_);
					goto salgo;
				}
				*aux=0;
				if (*(aux -1)==13)
				{
					*(aux-1)=0;
					
				}
				p->v=str.size();
				str.add(ini);
				ini=aux+1;
				//quitamos retorno de carro si hay
				if (*ini=='\r')
					ini=ini+1;
			}
		}
		//nos aseguramos que estamos al inicio del grupo----
		if(*ini=='[')
			ini=ini+1;

	}
	if (buf)
	{
		free(buf);
	}
	return TRUE;
	//error al leer-----------------------
salgo:
	borra();
	if(hfile!=INVALID_HANDLE_VALUE)
		CloseHandle(hfile);
	if (buf)
		free(buf);

	return FALSE;
}
//*********************************************************************************
char* Cini_file::buscamos_grupo( char *st )
{
	int i=0;
	char busco;
	busco='[';
	while(st[i])//mientras no sea 0 (fin de cadeba)
	{
		if (st[i]==busco)
		{
			if (busco!='[')
				busco='[';
			else
				return &st[i+1];//grupo encontrado
		}
		if (st[i]==';')//encontrado comentario
			busco='\n';
		i++;
	}
	return &st[i];

}
//*********************************************************************************
Ini_file_grupo* Cini_file::set_coun()
{
	grupos.reserva();
	grupos.n++;
	return (Ini_file_grupo*) &grupos.buf[grupos.z*(grupos.n-1)];
}
//*********************************************************************************
char* Cini_file::busca_prop( char* st )
{
	int i=0;
	char busco;
	busco='=';
	char*resul=st;
	while(st[i])//mientras no sea 0 (fin de cadeba)
	{
		if (st[i]==busco)
		{
			if (busco=='\n')
			{
				busco='=';
				if (st[i+1]=='\r')					
					i++;
				resul=&st[i+1];
			}
			else if (busco=='=')
			{
				st[i]=0;
				return resul;//propiedad encontrada
			}
			
		}
		if (st[i]==';')//encontrado comentario
			busco='\n';
		else if(st[i]=='[')//encontrado grupo nuevo
		{
			if (busco!=13)//si no esta en un comentario
				return &st[i];
		}
		i++;
	}
	return &st[i];
}
//*********************************************************************************
char* Cini_file::get( int gr,char *pro )
{
	int val=geti_valor(gr,pro);
	if (val<0)
		return NULL;
	return str.get(val);
}
//*********************************************************************************
char* Cini_file::get( int gr,char *pro, char *def)
{
	int val=geti_valor(gr,pro);
	if (val<0)
		return def;
	return str.get(val);
}
//*********************************************************************************
int Cini_file::get( int gr,char *pro, int def )
{
	int val=geti_valor(gr,pro);
	if (val<0)
		return def;
	return atoi(str.get(val));

}
//*********************************************************************************
double Cini_file::get( int gr,char *pro, double def )
{
	int val=geti_valor(gr,pro);
	if (val<0)
		return def;
	return atof(str.get(val));

}
//*********************************************************************************
BOOL Cini_file::guarda( char *path )
{
	HANDLE hfile=INVALID_HANDLE_VALUE;
	DWORD dw;
	int kk;
	char stra[512];
	Ini_file_grupo *g;
	Ini_file_props *p;
/*
	er->pon(MODULO_INI_FILE,"guarda: Función no implementada");
	return FALSE;*/
	//abrimos archivo-------------------------------
	hfile=CreateFile(path, 
		GENERIC_WRITE,
		0, // exclusive access
		NULL, // no security
		CREATE_ALWAYS,
		0, // no overlapped I/O
		NULL); // null template

	if (hfile == INVALID_HANDLE_VALUE)
	{
		er->pon_win(MODULO_INI_FILE);
		return FALSE;
	}
	//guardamos---------------------------------
	for (int i=0; i<grupos.n; i++)
	{
		//conseguimos grupo---------------------
		g=(Ini_file_grupo *) grupos.get(i);
		if (g->flags & INI_FILE_FLAGS_VACIO)
		{
			continue;
		}
		//grabamos nombre grupo-----------------
		sprintf(stra,"[%s]\r\n",str.get(g->n));
		kk=(int)strlen(stra);
		if(!WriteFile(hfile, stra, kk, &dw, NULL))
		{
			er->pon_win(MODULO_INI_FILE);
			goto salgo;
		}
		//guardamos propiedades---------------
		for(int j=0; j<(g->prop.n); j++)
		{
			//conseguimos propiedad-----------
			p=g->get(j);
			if (p->flags & INI_FILE_FLAGS_VACIO)
			{
				continue;
			}
			//grabamos propiedad--------------
			sprintf(stra,"%s=%s\r\n",str.get(p->p),str.get(p->v));
			kk=(int)strlen(stra);
			if(!WriteFile(hfile, stra, kk, &dw, NULL))
			{
				er->pon_win(MODULO_INI_FILE);
				goto salgo;
			}
		}
	}
	//cerramos----------------------------------
	if(hfile!=INVALID_HANDLE_VALUE)
	{
		CloseHandle(hfile);
	}
	return TRUE;

salgo:
	if(hfile!=INVALID_HANDLE_VALUE)
		CloseHandle(hfile);
	return FALSE;
}
//*********************************************************************************
int Cini_file::add_grupo( char *gr )
{
	int rs = grupos.n;
	Ini_file_grupo* g =set_coun();
	g->n=str.size();
	g->flags=0;
	g->inicia();
	str.add(gr);
	return rs;
}
//*********************************************************************************
int Cini_file::add( int gr,char *pro,char *val )
{
	//pillamos grupo-------------------------
	Ini_file_grupo *g=(Ini_file_grupo *) grupos.get(gr);
	if (!g|| (g->flags & INI_FILE_FLAGS_VACIO))
	{
		er->pon(MODULO_INI_FILE,"add: Indice del grupo erroneo");
		return -1;
	}
	//añadimos prop--------------------------
	int rs=g->prop.n;
	Ini_file_props*p=g->set_coun();
	p->flags=0;
	p->p=str.size();
	str.add(pro);
	p->v=str.size();
	str.add(val);
	return rs;
}
//*********************************************************************************
int Cini_file::add( int gr,char *pro,int val )
{
	char str[256];
	sprintf(str,"%ld",val);
	return add(gr,pro,str);
}
//*********************************************************************************
int Cini_file::add( int gr,char *pro,double val )
{
	char str[256];
	sprintf(str,"%.2f",val);
	return add(gr,pro,str);
}
//*********************************************************************************
void Cini_file::dame_valor( int gr,char *pro, char* dst,char *def )
{
	strcpy(dst, get(gr,pro,def));
}

//*********************************************************************************