// Configuracion.cpp : implementation file
//

#include "stdafx.h"
#include "Proyecto.h"
#include "ProyectoDoc.h"
#include "ProyectoView.h"
#include "Configuracion.h"
#include <direct.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CConfiguracion dialog


CConfiguracion::CConfiguracion(CWnd* pParent /*=NULL*/)
	: CDialog(CConfiguracion::IDD, pParent)
{
	//{{AFX_DATA_INIT(CConfiguracion)
	m_TxtMargenC = _T("");
	m_TxtMargenD = _T("");
	m_TxtMrgMen = _T("");
	m_TxtMrgMay = _T("");
	m_TxtNumPtos = _T("");
	m_NumVecinos = _T("");
	m_ChkContorno = FALSE;
	m_ChkContraste = FALSE;
	m_ChkGrafica = FALSE;
	m_ChkUmbral = FALSE;
	m_TxtMrgUmbral = _T("");
	m_TxtUmbralInf = _T("");
	m_TxtUmbralSup = _T("");
	m_TxtPFactor = _T("");
	m_TxtDirectorio = _T("");
	//}}AFX_DATA_INIT

		// Realizamos un enlace a la BD
	m_pBd = ((CProyectoView *) pParent)->GetDocument()->m_db;
	// Realizamos un enlace a la configuración actual
	m_Opt = ((CProyectoView *) pParent)->GetDocument()->opt;
}


void CConfiguracion::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CConfiguracion)
	DDX_Text(pDX, IDC_EDIT_MARGENC, m_TxtMargenC);
	DDV_MaxChars(pDX, m_TxtMargenC, 3);
	DDX_Text(pDX, IDC_EDIT_MARGEND, m_TxtMargenD);
	DDV_MaxChars(pDX, m_TxtMargenD, 3);
	DDX_Text(pDX, IDC_EDIT_MARGEMMEN, m_TxtMrgMen);
	DDV_MaxChars(pDX, m_TxtMrgMen, 1);
	DDX_Text(pDX, IDC_EDIT_MARGENMAY, m_TxtMrgMay);
	DDV_MaxChars(pDX, m_TxtMrgMay, 1);
	DDX_Text(pDX, IDC_EDIT_MAXNPTOS, m_TxtNumPtos);
	DDV_MaxChars(pDX, m_TxtNumPtos, 2);
	DDX_Text(pDX, IDC_EDIT_NUMVECINOS, m_NumVecinos);
	DDV_MaxChars(pDX, m_NumVecinos, 1);
	DDX_Check(pDX, IDC_CHK_CONTORNO, m_ChkContorno);
	DDX_Check(pDX, IDC_CHK_CONTRASTE, m_ChkContraste);
	DDX_Check(pDX, IDC_CHK_GRAFICA, m_ChkGrafica);
	DDX_Check(pDX, IDC_CHK_UMBRALIZADA, m_ChkUmbral);
	DDX_Text(pDX, IDC_EDIT_MARGENUMBRAL, m_TxtMrgUmbral);
	DDV_MaxChars(pDX, m_TxtMrgUmbral, 3);
	DDX_Text(pDX, IDC_EDIT_UMBRALINF, m_TxtUmbralInf);
	DDV_MaxChars(pDX, m_TxtUmbralInf, 3);
	DDX_Text(pDX, IDC_EDIT_UMBRALSUP, m_TxtUmbralSup);
	DDV_MaxChars(pDX, m_TxtUmbralSup, 3);
	DDX_Text(pDX, IDC_EDIT_PFACTOR, m_TxtPFactor);
	DDV_MaxChars(pDX, m_TxtPFactor, 2);
	DDX_Text(pDX, IDC_EDIT_DIR, m_TxtDirectorio);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CConfiguracion, CDialog)
	//{{AFX_MSG_MAP(CConfiguracion)
	ON_BN_CLICKED(IDC_CANCELAR, OnCancelar)
	ON_BN_CLICKED(IDC_DEFECTO, OnDefecto)
	ON_BN_CLICKED(IDC_ACEPTAR, OnAceptar)
	ON_BN_CLICKED(IDC_AYUDA, OnAyuda)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConfiguracion message handlers

// ************* //
// ** EVENTOS ** //
// ************* //

// ** Inicio ejecución ventana ** //

// Se dispara al iniciar la ejecución de la ventana
BOOL CConfiguracion::OnInitDialog() 
{
	CDialog::OnInitDialog();

	ODynaset dyna;
	CString sSQL;

	CenterWindow();

	// Obtengo el 'object_id' de la tabla Punto
	sSQL = "SELECT object_id FROM user_objects WHERE object_name='PUNTO'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("object_id",&obj);
	dyna.Close();

	// Obtengo el 'column_id' del atributo 'Distancia' de la tabla Punto
	sSQL = "SELECT column_id FROM user_tab_columns WHERE ";
	sSQL = sSQL + "table_name = 'PUNTO' AND column_name= 'DISTANCIA'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("column_id",&coldist);
	dyna.Close();

	// Obtengo el 'column_id' del atributo 'Curvatura' de la tabla Punto
	sSQL = "SELECT column_id FROM user_tab_columns WHERE ";
	sSQL = sSQL + "table_name = 'PUNTO' AND column_name = 'CURVATURA'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("column_id",&colcurv);
	dyna.Close();	

	// Obtengo el 'object_id' de la tabla PuntoCons
	sSQL = "SELECT object_id FROM user_objects WHERE object_name='PUNTOCONS'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("object_id",&objf);
	dyna.Close();
	
	// Obtengo el 'column_id' del atributo 'Distancia' de la tabla PuntoCons
	sSQL = "SELECT column_id FROM user_tab_columns WHERE ";
	sSQL = sSQL + "table_name = 'PUNTOCONS' AND column_name= 'DISTANCIA'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("column_id",&coldistf);
	dyna.Close();

	// Obtengo el 'column_id' del atributo 'Curvatura' de la tabla PuntoCons
	sSQL = "SELECT column_id FROM user_tab_columns WHERE ";
	sSQL = sSQL + "table_name = 'PUNTOCONS' AND column_name = 'CURVATURA'";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("column_id",&colcurvf);
	dyna.Close();	
	
	// Cargamos los márgenes de los atributo Distancia y Curvatura
	CargarMargen();
	// Cargamos el resto de opciones
	CargarOpciones();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// ** Fin ejecución ventana ** //

// Se dispara cuando pulsamos el botón "Cerrar"
void CConfiguracion::OnCancelar() 
{
	CDialog::OnCancel();
}

// ** Botones ** //

// Se dispara cuando pulsamos el botón "Por defecto"
void CConfiguracion::OnDefecto() 
{
	// Inicializamos las variables por defecto
	m_TxtMargenC = "70";
	m_TxtMargenD = "70";
	m_TxtMrgMay = "5";
	m_TxtMrgMen = "5";
	m_TxtNumPtos = "25";	
	m_TxtMrgUmbral = "5";
	m_NumVecinos = "2";
	m_TxtUmbralInf = "10";
	m_TxtUmbralSup = "10";
	m_TxtPFactor = "5";
	m_ChkContraste = 0;
	m_ChkUmbral = 1;
	m_ChkContorno = 1;
	m_ChkGrafica = 1;
	
	// Y lo reflejamos en sus correspondiente cajas
	UpdateData(false);
}

// Se dispara cuando pulsamos el botón "Aceptar"
void CConfiguracion::OnAceptar() 
{
	CString sSQL, tmp;
	int err;
	char scoldist[10], scolcurv[10], sobj[10], scoldistf[10], scolcurvf[10], sobjf[10], smuch[10];
		
	itoa(obj,sobj,10);
	itoa(coldist,scoldist,10);
	itoa(colcurv,scolcurv,10);
	itoa(objf,sobjf,10);
	itoa(coldistf,scoldistf,10);
	itoa(colcurvf,scolcurvf,10);	
	
	tmp = m_TxtDirectorio;
	UpdateData(true);

	// Comprobaciones de errores
	if ((atoi(m_TxtMargenC) < 1) || (atoi(m_TxtMargenC) > 100))
	{
		AfxMessageBox("Margen de Curvatura incorrecto", MB_OK);
		return;		
	}
	if ((atoi(m_TxtMargenD) < 1) || (atoi(m_TxtMargenD) > 100))
	{
		AfxMessageBox("Margen de Distancia incorrecto", MB_OK);
		return;		
	}
	if ((atoi(m_TxtMrgMay) < 1) || (atoi(m_TxtMrgMay) > 5))
	{
		AfxMessageBox("Margen mayor incorrecto", MB_OK);
		return;		
	}
	if ((atoi(m_TxtMrgMen) < 1) || (atoi(m_TxtMrgMen) > 5))
	{
		AfxMessageBox("Margen menor incorrecto", MB_OK);
		return;		
	}
	if ((atoi(m_TxtPFactor) < 0) || (atoi(m_TxtPFactor) > 10))
	{
		AfxMessageBox("Penalización por curvatura incorrecta", MB_OK);
		return;			
	}
	if ((atoi(m_TxtNumPtos) < 2) || (atoi(m_TxtNumPtos) > 50))
	{
		AfxMessageBox("Número máximo de puntos incorrecto", MB_OK);
		return;	
	}
	if (ExisteImagenMayor(atoi(m_TxtNumPtos)))
	{
		AfxMessageBox("Existen imágenes con mayor número de puntos que el máximo introducido", MB_OK);
		return;		
	}
	if ((atoi(m_TxtMrgUmbral) < 0) || (atoi(m_TxtMrgUmbral) > 255))
	{
		AfxMessageBox("Margen de umbralización incorrecto", MB_OK);
		return;	
	}
	if ((atoi(m_NumVecinos) < 0) || (atoi(m_NumVecinos) > 3))
	{
		AfxMessageBox("Número de vecinos incorrecto", MB_OK);
		return;	
	}
	if ((atoi(m_TxtUmbralInf) < 0) || (atoi(m_TxtUmbralInf) > 100))
	{
		AfxMessageBox("Umbral inferior de curvatura incorrecto.", MB_OK);
		return;	
	}
	if ((atoi(m_TxtUmbralSup) < 0) || (atoi(m_TxtUmbralSup) > 100))
	{
		AfxMessageBox("Umbral superior de curvatura incorrecto.", MB_OK);
		return;	
	}
	if (m_TxtDirectorio.GetLength() == 0)
	{
		AfxMessageBox("Directorio de vistas incorrecto.", MB_OK);
		return;
	}
	err = chdir(m_TxtDirectorio);
	chdir(tmp);
	if (err != 0)
	{
		AfxMessageBox("El directorio de vistas introducido no existe.", MB_OK);
		return;	
	}

	// Actualizo los márgenes (el much es igual a margen + 1) //
	itoa(atoi(m_TxtMargenC) + 1,smuch,10);
	sSQL = "UPDATE FAM SET Margen = " + m_TxtMargenC + ", Much = ";
	sSQL = sSQL + CString(smuch) + " WHERE OBJ# = " + sobj;
	sSQL= sSQL + " AND COL#  = " + scolcurv;
	m_pBd->ExecuteSQL(sSQL);	

	itoa(atoi(m_TxtMargenD) + 1,smuch,10);
	sSQL = "UPDATE FAM SET Margen = " + m_TxtMargenD + ", Much = ";
	sSQL = sSQL + CString(smuch) + " WHERE OBJ# = " + sobj;
	sSQL= sSQL + " AND COL#  = " + scoldist;
	m_pBd->ExecuteSQL(sSQL);	

	itoa(atoi(m_TxtMargenC) + 1,smuch,10);
	sSQL = "UPDATE FAM SET Margen = " + m_TxtMargenC + ", Much = ";
	sSQL = sSQL + CString(smuch) + " WHERE OBJ# = " + sobjf;
	sSQL= sSQL + " AND COL#  = " + scolcurvf;
	m_pBd->ExecuteSQL(sSQL);	

	itoa(atoi(m_TxtMargenD) + 1,smuch,10);
	sSQL = "UPDATE FAM SET Margen = " + m_TxtMargenD + ", Much = ";
	sSQL = sSQL + CString(smuch) + " WHERE OBJ# = " + sobjf;
	sSQL= sSQL + " AND COL#  = " + scoldistf;
	m_pBd->ExecuteSQL(sSQL);	
	
	// Cargo los resultados en la estructura m_Opt, para que el resto de
	// ventanas puedan acceder a las opciones elegidas y vigentes
	m_Opt->margenmay = atoi(m_TxtMrgMay);
	m_Opt->margenmen = atoi(m_TxtMrgMen);
	m_Opt->maxptos = atoi(m_TxtNumPtos);
	m_Opt->margenumbral = atoi(m_TxtMrgUmbral);
	m_Opt->numvecinos = atoi(m_NumVecinos);
	m_Opt->umbral_inf = atoi(m_TxtUmbralInf);
	m_Opt->umbral_sup = atoi(m_TxtUmbralSup);
	m_Opt->factor_penal = atoi(m_TxtPFactor);
	m_Opt->contraste = m_ChkContraste;
	m_Opt->umbralizada = m_ChkUmbral;
	m_Opt->contorno = m_ChkContorno;
	m_Opt->grafica = m_ChkGrafica;
	m_Opt->dir = m_TxtDirectorio;
	
	CDialog::OnOK();
}

// Se dispara cuando pulsamos el botón "Ayuda"
void CConfiguracion::OnAyuda() 
{
	HtmlHelp(NULL, m_Opt->workdir + "\\Ayuda\\Ayuda.chm::/configuracion.htm", HH_DISPLAY_TOPIC, 0);
}

// ******************** //
// ** PROCEDIMIENTOS ** //
// ******************** //

void CConfiguracion::CargarMargen()
{
	ODynaset dyna;
	CString sSQL;
	int iMargenC, iMargenD;
	char scoldist[10], scolcurv[10], sobj[10], tmp[10];
	
	itoa(obj,sobj,10);
	itoa(coldist,scoldist,10);
	itoa(colcurv,scolcurv,10);
	
	// Consulto el márgen de distancia
	sSQL = "SELECT Margen FROM FAM ";
	sSQL = sSQL + "WHERE OBJ# = " + sobj + " AND COL# = " + scoldist;
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("Margen", &iMargenD);
	dyna.Close();

	// Consulto el márgen de curvatura
	sSQL = "SELECT Margen FROM FAM ";
	sSQL = sSQL + "WHERE OBJ# = " + sobj + " AND COL# = " + scolcurv;
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("Margen", &iMargenC);
	dyna.Close();

	itoa(iMargenC,tmp,10);
	m_TxtMargenC = CString(tmp);
	itoa(iMargenD,tmp,10);
	m_TxtMargenD = CString(tmp);

	UpdateData(false);
}

void CConfiguracion::CargarOpciones()
{
	char tmp[10];

	itoa(m_Opt->margenmay,tmp,10);
	m_TxtMrgMay = CString(tmp);
	itoa(m_Opt->margenmen,tmp,10);
	m_TxtMrgMen = CString(tmp);
	itoa(m_Opt->maxptos,tmp,10);
	m_TxtNumPtos = CString(tmp);
	itoa(m_Opt->margenumbral,tmp,10);
	m_TxtMrgUmbral = CString(tmp);
	itoa(m_Opt->numvecinos,tmp,10);
	m_NumVecinos = CString(tmp);
	itoa(m_Opt->umbral_inf,tmp,10);
	m_TxtUmbralInf = CString(tmp);
	itoa(m_Opt->umbral_sup,tmp,10);
	m_TxtUmbralSup = CString(tmp);
	itoa(m_Opt->factor_penal,tmp,10);
	m_TxtPFactor = CString(tmp);
	m_ChkContraste = m_Opt->contraste;
	m_ChkUmbral = m_Opt->umbralizada;
	m_ChkContorno = m_Opt->contorno;
	m_ChkGrafica = m_Opt->grafica;
	m_TxtDirectorio = m_Opt->dir;

	UpdateData(false);
}

bool CConfiguracion::ExisteImagenMayor(int lim)
{
	ODynaset dyna;
	CString sSQL;
	bool res;
	int maxi;

	sSQL = "SELECT Max(NumPuntos) AS Maximo FROM Imagen";
	dyna.Open(*m_pBd,sSQL);
	dyna.GetFieldValue("Maximo",&maxi);
	if (maxi > lim)
		res = true;
	else
		res = false;

	dyna.Close();
	
	return res;
}
