import java.awt.*;
import java.awt.geom.*;
import java.lang.Math;
import java.util.*;
import java.lang.*;
import java.text.*;

/**
* <strong>Clase que Implementa la representacion de un triangulo en un 
* entorno bi-dimensional.<strong>
* @author Thomas Genet
*/
class Triangulo extends Forma
{
/**
*Contiene el primer punto del Triangulo.
*/
private Point a;
/**
*Contiene el segundo punto del Triangulo.
*/
private Point b;
/**
*Contiene el tercer punto del Triangulo.
*/
private Point c; 

private static final int NUMBER_OF_SIDE = 3;
private static final int NUMBER_OF_CORNER = 3;

/*
* Formato usado para visualizar las coordenadas de los puntos del triangulo
* en el metodo toString.
*/
private DecimalFormat miformato = new DecimalFormat("###.###");

/**
* Arreglo de Rectangle2D que contiene los cuadraditos verdes de selección del
* Triangulo.
*/
private Rectangle2D[] greenSquare;


/** Constructor
* Construye un triangulo a partir de 3 puntos dados en parametros.
* @param a1 Primer punto del Triangulo.
* @param b1 Segundo punto del Triangulo.
* @param c1 Tercer punto del Triangulo.
*/
public Triangulo (Point a1, Point b1, Point c1)
{
a = new Point(a1.X, a1.Y);
b = new Point(b1.X, b1.Y);
c = new Point(c1.X, c1.Y);
}

/**
* Metodo que permite acceder al punto A del Triangulo. 
* @return El punto A del Triangulo.
*/
public Point a()
{
return a;
}

/**
* Metodo que permite acceder al punto B del Triangulo. 
* @return El punto B del Triangulo.
*/
public Point b()
{
return b;
}

/**
* Metodo que permite acceder al punto C del Triangulo. 
* @return El punto C del Triangulo.
*/
public Point c()
{
return c;
}

/**
* Describe el Triangulo en una String.
* @return Una Sring que contiene las informaciones del Triangulo.
*/
public String toString()
{
String str = new String("Esto es un Triangulo: punto a"
+ a.toString() + " , punto b"
+ b.toString() + " , punto c"
+ c.toString());
return str;
}

/** Escala el triangulo respecto al punto centro en un factor dado.
* @param centro Punto respecto del cual se hace el escalamiento.
* @param factor Factor usado en el escalamiento. >1 corresponde a amplificación,
* <1 corresponde a reducción.
*/
public void escalar (Point centro, double factor)
{
a.escalar(centro, factor);
b.escalar(centro, factor);
c.escalar(centro, factor);
}


/**
*Traslada el triangulo desplazandolo en sentido X e Y.
* @param deltaX desplazamiento en sentido horizontal.
* @param deltaY desplazamiento en sentido vertical.
*/
public void trasladar(double deltaX, double deltaY)
{
a.X += deltaX;
b.X += deltaX;
c.X += deltaX;
a.Y += deltaY;
b.Y += deltaY;
c.Y += deltaY;
}


/** Rota el triangulo respecto al punto centro en un ángulo dado.
* @param centro Punto respecto del cual se hace la rotación.
* @param deltaAngulo Angulo de rotación en radianes.
*/
public void rotar(Point centro, double deltaAngulo)
{
a.rotar(centro, deltaAngulo);
b.rotar(centro, deltaAngulo);
c.rotar(centro, deltaAngulo);
}

/**
*Compara la forma dada en parametro con el Triangulo.
*@param f Forma comparada con el Triangulo.
*@return True si la forma es un triangulo identico al triangulo pendiente,
*False sino.
*/
public boolean equals (Forma f)
{
if (this == f) return true;

if (f == null) return false;

if (getClass() != f.getClass()) return false;

Triangulo otro = (Triangulo)f;

return (a.equals(otro.a()) && (b.equals(otro.b())) && (c.equals(otro.c())));
}


/**
*Duplica el Triangulo.
*@return Un Triangulo identico al Triangulo pendiente.
*/
public Forma clone()
{
Triangulo copia = new Triangulo(a, b, c);

return copia;
}

/**
* Metodo que dibuja el Triangulo en el Graphics2D dado en parametro.
* @param g2d Graphics2D donde el Triangulo se dibuja.
*/
public void paintComponent(Graphics2D g2d)
{
g2d.draw(new Line2D.Double(a.X, a.Y, b.X, b.Y));
g2d.draw(new Line2D.Double(b.X, b.Y, c.X, c.Y));
g2d.draw(new Line2D.Double(c.X, c.Y, a.X, a.Y));
}

/**
* Metodo que permite cambiar las coordenadas de la segunda esquina del
* Triangulo.
* @param s Segunda esquina del Triangulo.
*/
public void setSecondCorner (Point s)
{
b.X = s.X;
b.Y = s.Y;
}

/**
* Metodo que permite cambiar las coordenadas de la tercera esquina del
* Triangulo.
* @param t Tercera esquina del Triangulo.
*/
public void setThirdCorner (Point t)
{
c.X = t.X;
c.Y = t.Y;
}

/**
* Metodo que dibuja un cuadradito a cada esquina del Triangulo para mostrar
*  que este está seleccionado.
* @param g Graphics donde se dibujan los 3 cuadraditos.
*/
public void select (Graphics g)
{
g.setColor(Color.green);
greenSquare = new Rectangle2D[NUMBER_OF_CORNER];

greenSquare[0] = new Rectangle2D.Double(a.X - 2, a.Y - 2, SIZE_OF_SQUARE,
SIZE_OF_SQUARE);
greenSquare[1] = new Rectangle2D.Double(b.X - 2, b.Y - 2, SIZE_OF_SQUARE,
SIZE_OF_SQUARE);
greenSquare[2] = new Rectangle2D.Double(c.X - 2, c.Y - 2, SIZE_OF_SQUARE,
SIZE_OF_SQUARE);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < greenSquare.length; i++)
g2.draw(greenSquare[i]);
g.setColor(Color.black);
}


/**
* Metodo que permite saber si el punto dado en parametro pertenece a uno de los
* cuadraditos de seleccion del Triangulo. 
* @return True si el punto dado en parametro pertenece a uno de los cuadraditos
* de seleccion del Triangulo, False sino.
*/
public boolean isItInAGreenSquare(Point p)
{
Point2D p2 = new Point2D.Double(p.X, p.Y);
for (int i = 0; i < greenSquare.length; i++)
if (greenSquare[i].contains(p2))
return true;
return false;
}


/**
* Metodo que permite saber si el punto dado en parametro pertenece al
* Triangulo.
* @param punto Punto cuya coordenadas son revisadas para comprobar si 
* pertenecen o no al Triangulo.
* @return True si punto hace parte del Triangulo, False sino.
*/
public boolean isSelected(Point punto)
{
int i;

Linea[] linea;
linea = new Linea[NUMBER_OF_SIDE];
linea[0] = new Linea(a, b);
linea[1] = new Linea(b, c);
linea[2] = new Linea(c, a);

for (i = 0; i < NUMBER_OF_SIDE; i++)
if (linea[i].isSelected(punto)) return true;

return false;
}
 

}
