/** @(#) Ellipse.java 1.0 99/12/20 Larry Rodrigues
 **/

package com.vistech.shapes;
import java.awt.*;
import java.lang.Math;
import java.awt.geom.*;

/** Represents an interactively drawable ellipse.
  * @version 1.0  20 Dec 1999
  * @author Larry Rodrigues
  **/
public class Ellipse extends Shapes implements Fillable{
    /** Bounding box parameters.
      **/
    protected int wid=0, ht=0;
    protected boolean filled = false;
    /** Initializes the Ellipse parameters.
      * The arguments provide the starting point of the Ellipse
      * which may be the upper left hand corner(ULHC) or bottom righthand
      * corner coordinates(BRHC) of the bounding box sorrounding the ellipse.
      * @param  x  the x coordinate of the starting position.
      * @param  y  the y coordinate of the starting poistion.
      **/
    public void init(int x , int y){
       st.x = x; st.y = y;
       cur.x = x; cur.y =y;
       wid =0; ht =0;
    }

    /** Sets the current point.
      * @param  x  the x coordinate of the current position.
      * @param  y  the y coordinate of the current poistion.
      **/
    public void setCurrentPosition(int x , int y){
       cur.x = x; cur.y = y;
    }

    /** Draws interactively on a Graphics context g.
      * This API does not check whether the Ellipse overflows
      * the borders of the component.
      * This  method uses the XOR paint mode. It erases the
      * previously drawn shape and draws a new shape in its
      * place.
      * @param g the graphics object on which the shape is to be drawn.
      **/
    public void drawInteractive(Graphics2D g){
        basicStroke = g.getStroke();
        g.setColor(Color.black);
        g.setXORMode(drawingColor);
        drawEllipse(g);
        wid = Math.abs(st.x - cur.x);
        ht =  Math.abs(st.y - cur.y);
        drawEllipse(g);
     }

    /**
      * Draws on a Graphics context g.
      * This API does not check whether the Ellipse overflows
      * the borders of the component.
      * @param g the graphics object on which the shape is to be drawn.
      **/
    public void drawPermanent(Graphics2D g){
       Stroke savedStroke = g.getStroke();
       if(basicStroke != null) g.setStroke(basicStroke);
       g.setPaintMode();
       g.setColor(drawingColor);
       drawEllipse(g);
       wid = Math.abs(st.x - cur.x);
       ht =  Math.abs(st.y - cur.y);
       drawEllipse(g);
       g.setStroke(savedStroke);
     }

     public boolean contains(Graphics2D g, int x, int y) {
       if(!path.contains((double)x, (double)y)) return false;
       drawSmallRects(g);
       return true;
     }

     public void drawSmallRects(Graphics2D g) {
        smallRectsOn = !smallRectsOn;
        g.setColor(Color.black);
        g.setXORMode(drawingColor);
        wid = Math.abs(st.x - cur.x);
        ht =  Math.abs(st.y - cur.y);

        int xp[] = new int[4];
        int yp[] = new int[4];
        if(st.x > cur.x) {
           xp[0] = st.x + wid;
           xp[1] = st.x - wid;
           xp[2] = st.x - wid;
           xp[3] = st.x + wid;
        }
        else{
           xp[0] = st.x + wid;
           xp[1] = st.x - wid;
           xp[2] = st.x - wid;
           xp[3] = st.x + wid;
        }
        if(st.y > cur.y) {
           yp[0] = st.y + ht ;
           yp[1] = st.y + ht;
           yp[2] = st.y - ht;
           yp[3] = st.y - ht;
        }
        else{
           yp[0] = st.y -ht;
           yp[1] = st.y -ht;
           yp[2] = st.y + ht;
           yp[3] = st.y + ht;
        }
        for(int i=0; i< xp.length;i++) {
            g.drawRect(xp[i], yp[i], 5,5);
        }
     }

     public void draw(Graphics2D g){
        Stroke savedStroke = g.getStroke();
        if(basicStroke != null) g.setStroke(basicStroke);
        g.setColor(Color.black);
        g.setXORMode(drawingColor);
        drawEllipse(g);
        if(fillOn){
           g.setXORMode(fillColor);
           fillEllipse(g);
        }
        g.setStroke(savedStroke);
     }

     public void move(Graphics2D g, int diffx, int diffy){
        Stroke savedStroke = g.getStroke();
        if(basicStroke != null) g.setStroke(basicStroke);
        erase(g);
        st.x += diffx; st.y += diffy;
        cur.x += diffx; cur.y += diffy;
        wid = Math.abs(st.x - cur.x);
        ht =  Math.abs(st.y - cur.y);
        g.setXORMode(drawingColor);
        drawEllipse(g);
        drawSmallRects(g);
        if(fillOn){
           g.setXORMode(fillColor);
           fillEllipse(g);
        }

        g.setStroke(savedStroke);
    }

    public void erase(Graphics2D g){
       Stroke savedStroke = g.getStroke();
       if(basicStroke != null) g.setStroke(basicStroke);

       g.setColor(Color.black);
       g.setXORMode(drawingColor);
       drawEllipse(g);
       if(smallRectsOn) drawSmallRects(g);
       if(fillOn){
          g.setXORMode(fillColor);
          fillEllipse(g);
       }
       g.setStroke(savedStroke);
    }

    /** Fills with a given color.
      * @param g the graphics object on which the shape is to  be drawn
      * @color the filling color.
      **/
    public void fill(Graphics2D g, Color color){
       if(filled) return;
       filled = true;
       fillOn = true;
       fillColor = color;
       g.setXORMode(fillColor);
       fillEllipse(g);
    }

    /** Draws and returns itself.
      * shCount is set by the caller.
      * @param g the graphics object on which the shape is to be drawn.
      * @param shCnt the shape count.
      **/
    public Shapes saveCurShape(Graphics2D g, int shCnt){
           g.setColor(drawingColor);
           g.setPaintMode();
           wid = Math.abs(st.x - cur.x);
           ht =  Math.abs(st.y - cur.y);
           //g.drawOval((st.x-wid), (st.y-ht), 2*wid, 2*ht);
           drawEllipse(g);
           g.setFont(font);
           shapeCount = shCnt;
           return (Shapes)this;
     }

    public void drawEllipse(Graphics2D g){
       Ellipse2D.Float ellipse = new Ellipse2D.Float((float)(st.x-wid),
                                              (float)(st.y-ht),
                                            (float)2.0*wid, (float)2.0*ht);
       path = new GeneralPath(ellipse);
       g.draw(path);
    }

    public void fillEllipse(Graphics2D g){
       Ellipse2D.Float ellipse = new Ellipse2D.Float((float)(st.x-wid),
                                              (float)(st.y-ht),
                                              (float)2*wid, (float)2*ht);
       path = new GeneralPath(ellipse);
       g.fill(path);
    }
}






