/*
 * Course:       CSCI 215
 * Title:        Lab 1
 * Description:  DrawPad
 * Author:       Yu Chong
 * Copyright (c)2001 Yu Chong.  All Rights Reserved.
 */

import java.awt.Graphics;
import java.awt.Color;

/**
 * CLASS:    Ellipse<BR>
 * PURPOSE:  This class represent one of the shapes that can be drawn -- Ellipse<BR>
 * IMPORT:   java.awt.Graphics, java.awt.Color, DrawableShape, Point<BR>
 * EXPORT:   New Class|Ellipse<BR>New Method| Ellipse,
 *           copyClone, hitTest, hitTestPointBox, paint<BR>
 */
public class Ellipse extends DrawableShape
{
  /** <BR>
   *  PRE:  None<BR>
   *  POST: Initialize all the variables needed for Ellipse shape<BR>
   */
  public Ellipse(Point startPoint, Point endPoint)
  {
    addPoint(startPoint);
    addPoint(endPoint);
  }

  /** <BR>
   *  PRE:  None<BR>
   *  POST: A new DrawableShape object is copy from the current instance and returned<BR>
   */
  public DrawableShape copyClone()
  {
    Point startPoint = (Point)pointList.firstElement();
    Point endPoint = (Point)pointList.lastElement();
    Ellipse newEllipse = new Ellipse(startPoint, endPoint);
    newEllipse.setColor(this.color);
    newEllipse.setFill(this.bFill);
    return newEllipse;
  }

  /** <BR>
   *  PRE:  A valid Point Object<BR>
   *  POST: Check to see if the point hit the shape<BR>
   */
  public boolean hitTest(Point p)
  {
    Point startPoint = (Point)pointList.firstElement();
    Point endPoint = (Point)pointList.lastElement();
    double term1 = Math.pow((double)p.x - (double)(startPoint.x + endPoint.x)/2.0,2.0) /
                   Math.pow((double)(Math.abs(startPoint.x - endPoint.x))/2.0,2.0);
    double term2 = Math.pow((double)p.y - (double)(startPoint.y + endPoint.y)/2.0,2.0) /
                   Math.pow((double)(Math.abs(startPoint.y - endPoint.y))/2.0,2.0);
    if((term1+term2) <= 1)
    {
      return true;
    }
    return false;
  }

  /** <BR>
   *  PRE:  A valid Graphics object to paint on<BR>
   *  POST: Current object will be draw using the Graphics object<BR>
   */
  public void paint(Graphics g)
  {
    Point startPoint = (Point)pointList.firstElement();
    Point endPoint = (Point)pointList.lastElement();
    int w = Math.abs(startPoint.x - endPoint.x);
    int h = Math.abs(startPoint.y - endPoint.y);
    int x = (startPoint.x < endPoint.x) ? startPoint.x : endPoint.x;
    int y = (startPoint.y < endPoint.y) ? startPoint.y : endPoint.y;
    g.setColor(this.color);
    if(bFill == true)
    {
      g.fillOval(x,y,w,h);
    }
    else
    {
      g.drawOval(x,y,w,h);
    }
    if(bSelected) //draw square boxes for corners
    {
      final int halfSquareSize = 3; // 6 pixels total;
      final int squareSize = halfSquareSize * 2;
      int x1 = startPoint.x - halfSquareSize;
      int x2 = endPoint.x - halfSquareSize;
      int y1 = startPoint.y - halfSquareSize;
      int y2 = endPoint.y - halfSquareSize;
      int halfX = (x1+x2)/2;
      int halfY = (y1+y2)/2;
      g.setColor(Color.white);
      g.fillRect(x1, halfY, squareSize, squareSize);
      g.fillRect(x2, halfY, squareSize, squareSize);
      g.fillRect(halfX, y1, squareSize, squareSize);
      g.fillRect(halfX, y2, squareSize, squareSize);

      g.setColor(Color.black);
      g.drawRect(x1, halfY, squareSize, squareSize);
      g.drawRect(x2, halfY, squareSize, squareSize);
      g.drawRect(halfX, y1, squareSize, squareSize);
      g.drawRect(halfX, y2, squareSize, squareSize);
    }
  }

  /** <BR>
   *  PRE:  A valid Point Object<BR>
   *  POST: Check to see if the point hit the shape's PointBox if it has been
   *        selected<BR>
   */
  public boolean hitTestPointBox(Point p)
  {
    xPointChange = null;
    yPointChange = null;
    if(bSelected)
    {
      Point startPoint = (Point)pointList.firstElement();
      Point endPoint = (Point)pointList.lastElement();
      final int halfSquareSize = 3; // 6 pixels total;
      final int squareSize = halfSquareSize * 2;
      int x1 = startPoint.x - halfSquareSize;
      int x2 = endPoint.x - halfSquareSize;
      int y1 = startPoint.y - halfSquareSize;
      int y2 = endPoint.y - halfSquareSize;
      int halfX = (x1+x2)/2;
      int halfY = (y1+y2)/2;

      if(p.x >= halfX && p.x <= (halfX+squareSize))
      {
        if(p.y >=y1 && p.y <=(y1+squareSize))
        {
          yPointChange = startPoint;
          return true;
        }
        else if(p.y >=y2 && p.y <=(y2+squareSize))
        {
          yPointChange = endPoint;
          return true;
        }
      }
      if(p.y >= halfY && p.y <= (halfY+squareSize))
      {
        if(p.x >=x1 && p.x <=(x1+squareSize))
        {
          xPointChange = startPoint;
          return true;
        }
        else if(p.x >=x2 && p.x <=(x2+squareSize))
        {
          xPointChange = endPoint;
          return true;
        }
      }
    }
    return false;
  }
}
