/*
 * 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 {

    /** 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 = "";

    public double getX1() {
        return x1;
    }

    public double getY1() {
        return y1;
    }

    public double getX2() {
        return x2;
    }

    public double getY2() {
        return y2;
    }

    public double getPorosity() {
        return porosity;
    }

    public double getHgt() {
        return height;
    }

    public double getWid() {
        return width;
    }

    public String getName() {
        return name;
    }

    public String getType() {
        return barrierType;
    }

    public void setX1(double val) {
        x1 = val;
        addPoints();
    }

    public void setX2(double val) {
        x2 = val;
        addPoints();
    }

    public void setY1(double val) {
        y1 = val;
        addPoints();
    }

    public void setY2(double val) {
        y2 = val;
        addPoints();
    }

    public void setWid(double val) {
        width = val;
        addPoints();
    }

    public void setHgt(double val) {
        height = val;
    }

    public void setPorosity(double val) {
        porosity = val;
    }

    public void setName(String val) {
        name = val;
    }

    public void setType(String val) {
        barrierType = val;
    }

    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));



        }
    }

    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();
    }

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

    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;
    }

    @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;
    }

    @Override
    public int hashCode() {
        assert false : "hashCode not designed";
        return 42; // any arbitrary constant will do 
    }
}
