/*
 * BarrierPolygon.java
 *
 * Created on January 24, 2007, 5:05 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package usda.weru.erosion.barriereditor;

import java.awt.Polygon;

/**
 *
 * @author wjr
 */
public final class BarrierPolygon extends Polygon implements Cloneable {
    private static final long serialVersionUID = 1L;

    /** Creates a new instance of BarrierPolygon */
    public BarrierPolygon() {
        super();
    }
    private double x1 = 0;
    private double y1 = 0;
    private double x2 = 10;
    private double y2 = 20;
    private double porosity = Math.random();
    private double height = 5.0;
    private double width = 2.0;
    private String name = "Barrier";
    private String barrierType = "";

	/**
	 *
	 * @return
	 */
	public double getX1() {
        return x1;
    }

	/**
	 *
	 * @return
	 */
	public double getY1() {
        return y1;
    }

	/**
	 *
	 * @return
	 */
	public double getX2() {
        return x2;
    }

	/**
	 *
	 * @return
	 */
	public double getY2() {
        return y2;
    }

	/**
	 *
	 * @return
	 */
	public double getPorosity() {
        return porosity;
    }

	/**
	 *
	 * @return
	 */
	public double getHgt() {
        return height;
    }

	/**
	 *
	 * @return
	 */
	public double getWid() {
        return width;
    }

	/**
	 *
	 * @return
	 */
	public String getName() {
        return name;
    }

	/**
	 *
	 * @return
	 */
	public String getType() {
        return barrierType;
    }

	/**
	 *
	 * @param val
	 */
	public void setX1(double val) {
        x1 = val;
        addPoints();
    }

	/**
	 *
	 * @param val
	 */
	public void setX2(double val) {
        x2 = val;
        addPoints();
    }

	/**
	 *
	 * @param val
	 */
	public void setY1(double val) {
        y1 = val;
        addPoints();
    }

	/**
	 *
	 * @param val
	 */
	public void setY2(double val) {
        y2 = val;
        addPoints();
    }

	/**
	 *
	 * @param val
	 */
	public void setWid(double val) {
        width = val;
        addPoints();
    }

	/**
	 *
	 * @param val
	 */
	public void setHgt(double val) {
        height = val;
    }

	/**
	 *
	 * @param val
	 */
	public void setPorosity(double val) {
        porosity = val;
    }

	/**
	 *
	 * @param val
	 */
	public void setName(String val) {
        name = val;
    }

	/**
	 *
	 * @param val
	 */
	public void setType(String val) {
        barrierType = val;
    }

	/**
	 *
	 * @param x1Str
	 * @param y1Str
	 * @param x2Str
	 * @param y2Str
	 * @param height
	 * @param porosity
	 * @param width
	 * @param name
	 * @param barType
	 */
	public BarrierPolygon(String x1Str, String y1Str, String x2Str, String y2Str, String height, String porosity, String width, String name, String barType) {
        this(Double.parseDouble(x1Str), Double.parseDouble(y1Str), Double.parseDouble(x2Str), Double.parseDouble(y2Str), Double.parseDouble(height), Double.parseDouble(porosity), Double.parseDouble(width), name, barType);
    }
    // currently uses very simple algorithm to determine bounding points.
    // should change to using atan, cos & sin to determine actual points

	/**
	 *
	 */
	    public void addPoints() {

        double tx1 = x1;
        double tx2 = x2;
        double ty1 = y1;
        double ty2 = y2;

        reset();

        double rise = (ty2 - ty1);
        double run = (tx2 - tx1);
        if (rise == 0 && run == 0) {
            //have a point
            addPoint((int) (tx1 - width / 4), (int) (ty1 - width / 4));
            addPoint((int) (tx1 + width / 4), (int) (ty1 - width / 4));
            addPoint((int) (tx1 + width / 4), (int) (ty1 + width / 4));
            addPoint((int) (tx1 - width / 4), (int) (ty1 + width / 4));
        } else if (run == 0) {
            //Have a vertical line
            addPoint((int) (tx1 - width / 2), (int) ty1);
            addPoint((int) (tx1 + width / 2), (int) ty1);
            addPoint((int) (tx2 + width / 2), (int) ty2);
            addPoint((int) (tx2 - width / 2), (int) ty2);
        } else if (rise == 0) {
            //Have a horizontal line
            addPoint((int) (tx1), (int) (ty1 - width / 2));
            addPoint((int) (tx1), (int) (ty1 + width / 2));
            addPoint((int) (tx2), (int) (ty2 + width / 2));
            addPoint((int) (tx2), (int) (ty2 - width / 2));
        } else {
            double slope = rise / run;
            double radians = Math.atan(slope);
            double sin = Math.sin(radians - Math.PI / 2);
            double cos = Math.cos(radians - Math.PI / 2);
            double halfWidth = width / 2;

            addPoint((int) (tx1 + cos * -halfWidth), (int) (ty1 + sin * -halfWidth));
            addPoint((int) (tx1 + cos * halfWidth), (int) (ty1 + sin * halfWidth));
            addPoint((int) (tx2 + cos * halfWidth), (int) (ty2 + sin * halfWidth));
            addPoint((int) (tx2 + cos * -halfWidth), (int) (ty2 + sin * -halfWidth));



        }
    }

	/**
	 *
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param height
	 * @param porosity
	 * @param width
	 * @param name
	 * @param barType
	 */
	public BarrierPolygon(double x1, double y1, double x2, double y2, double height,
            double porosity, double width, String name, String barType) {
        super();
        porosity = Math.round(porosity * 1000) / 1000.0;
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.porosity = porosity;
        this.height = height;
        this.width = width;
        this.name = name;
        this.barrierType = barType;
        addPoints();
    }

	/**
	 *
	 * @return
	 */
	@Override
    public String toString() {
//        return "Barrier " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + porosity + 
//                " " + height + " " + width;
        return name;
    }

	/**
	 *
	 * @param obj
	 * @return
	 */
	@Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if ((obj instanceof BarrierPolygon) == false) {
            return false;
        }
        BarrierPolygon temp = (BarrierPolygon) obj;
        if (!getName().equals(temp.getName())) {
            return false;
        }
        if (!getType().equals(temp.getType())) {
            return false;
        }
        if (getX1() != temp.getX1()) {
            return false;
        }
        if (getX2() != temp.getX2()) {
            return false;
        }
        if (getY1() != temp.getY1()) {
            return false;
        }
        if (getY2() != temp.getY2()) {
            return false;
        }
        if (getWid() != temp.getWid()) {
            return false;
        }
        if (getHgt() != temp.getHgt()) {
            return false;
        }
        if (getPorosity() != temp.getPorosity()) {
            return false;
        }
        return true;
    }

	/**
	 *
	 * @return
	 */
	@Override
    public Object clone() {
        BarrierPolygon bp = new BarrierPolygon();
        bp.x1 = x1;
        bp.y1 = y1;
        bp.x2 = x2;
        bp.y2 = y2;
        bp.porosity = porosity;
        bp.height = height;
        bp.width = width;
        bp.name = name;
        bp.barrierType = barrierType;
        addPoints();
        return bp;
    }

	/**
	 *
	 * @return
	 */
	@Override
    public int hashCode() {
/**
                 * Note:  Assertions are not enabled.  These will be useless items
                 * unless assertions are enabled.  Thus, they will be commented out unless
                 * the user wishes to enable specific assertions (feed the virtual machine 
                 * the -ea argument).
                 */
//        assert false : "hashCode not designed";
        return 42; // any arbitrary constant will do 
    }
}
