/** @(#) utilpos/coordinatepos.cpp */

// #include "coordinatepos.h"
/** @(#) coordinatepos.h */
#ifndef COORDINATEPOS_H
#define COORDINATEPOS_H
//----------------------------------------------------------------------------
#include <algorithm>	// swap
#include <stdexcept>	// runtime_exception
using namespace std;

/** 
* Convierte coordenadas logicas(double) a graficas(int).
* @author Omar Posada Villarreal
* @version 1.0, 22/05/2002 
*/
class CoordinatePos {
private:
	/** Coordenadas logicas. */
	double	xMin, xMax, yMin, yMax;

	/** Rango logico. */
	double	logicX, logicY;
	
	/** Coordenadas graficas. */
	int	xMinG, xMaxG, yMinG, yMaxG;

	/** Rango grafico. */
	double	graphX, graphY;	//no int para ahorrar conversion de datos

	/** Evita conversiones de tipo. */
	double	xMinGD, yMinGD;	//no int para ahorrar conversion de datos
	
public:
// constructor, ~, friend-----------------------------------------------------

/** Construye. Valida rangos. */
CoordinatePos :: CoordinatePos(double theXMin, double theXMax, 
		double theYMin, double theYMax, 
		int theXMinG, int theXMaxG, int theYMinG, int theYMaxG) {
	xMin = theXMin;
	xMax = theXMax;
	yMin = theYMin;
	yMax = theYMax;
			
	xMinG = theXMinG;
	xMaxG = theXMaxG;
	yMinG = theYMinG;
	yMaxG = theYMaxG;
			
	// Si rango invertido, revertirlo
	if (xMin > xMax) {
		swap(xMin, xMax);
	}
	if (yMin > yMax) {
		swap(yMin, yMax);
	}
	
	if (xMinG > xMaxG) {
		swap(xMinG, xMaxG);
	}
	if (yMinG > yMaxG) {
		swap(yMinG, yMaxG);
	}

	logicX = xMax - xMin;
	logicY = yMax - yMin;
	graphX = static_cast<double>(xMaxG - xMinG + 1);
	graphY = static_cast<double>(yMaxG - yMinG + 1);
	xMinGD = static_cast<double>(xMinG);
	yMinGD = static_cast<double>(yMinG);
}

/* Destructor predeterminado. */
/** Libera recursos. */

// operator-------------------------------------------------------------------

//----------------------------------------------------------------------------
/** Convierte una coordenada logica a una grafica. Trunca el resultado. */
inline int toGraphX(double x) {
	return static_cast<int>
		(xMinGD + graphX * (x - xMin) / logicX);
}

/** Convierte una coordenada logica a una grafica. Trunca el resultado. 
* Recordar que Y logica "sube", mientras que Y grafica "baja".*/
inline int toGraphY(double y) {
	return static_cast<int>
		(  yMinGD + graphY * ( 1.0 - ((y - yMin) / logicY) )  );
}

}; // class
//----------------------------------------------------------------------------
#endif
// Fin------------------------------------------------------------------------