/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : PlotShapesAndLines.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */
package ciss.phase_viewer.graph.plotattributes;

import java.awt.BasicStroke;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

public class PlotShapesAndLines {

    private int shapetype;

    private int linetype;

    private double shapesize;

    private float width;

    public PlotShapesAndLines() {
    }

    /**
     * 点オブジェクトを返す.
     * 
     * @param shapetype
     *            0から9までの整数値. それ以外の場合正方形を返す(0と同じ).
     * @param shapesize
     *            点の大きさを指定するdouble値.
     * @return 点を表すShapeオブジェクト.
     */
    public Shape getShape(int shapetype, double shapesize) {
        this.shapetype = shapetype;
        this.shapesize = shapesize;
        return createShape(0.d, 0.d);
    }

    /**
     * 点オブジェクトを返す. 中心の座標を指定できる.
     * 
     * @param shapetype
     *            0から9までの整数値. それ以外の場合正方形を返す(0と同じ).
     * @param shapesize
     *            点の大きさを指定するdouble値.
     * @param x
     *            中心のx座標
     * @param y
     *            中心のy座標
     * @return 点を表すShapeオブジェクト.
     */
    public Shape getShape(int shapetype, double x, double y, double shapesize) {
        this.shapetype = shapetype;
        this.shapesize = shapesize;
        return createShape(x, y);
    }

    /**
     * 線オブジェクトを返す.
     * 
     * @param linetype
     *            0から5までの整数値. それ以外の場合ただの直線を返す(0と同じ)
     * @param width
     *            線幅を指定するfloat値.
     * @return 線を表すBasicStrokeオブジェクト.
     */
    public BasicStroke getLine(int linetype, float width) {
        this.linetype = linetype;
        this.width = width;
        if (width <= 0) {
            this.linetype = -1;
            this.width = 0.0f;
        }
        return createLine();
    }

    private Shape createShape(double x, double y) {

        Shape shape;

        double size = shapesize;
        double delta = size / 2.0;
        int[] xpoints = null;
        int[] ypoints = null;

        if (shapetype == 0) {
            // square
            shape = new Rectangle2D.Double(x - delta, y - delta, size, size);
        }

        else if (shapetype == 1) {
            // circle
            shape = new Ellipse2D.Double(x - delta, y - delta, size, size);
        }

        else if (shapetype == 2) {
            // triangle, up
            xpoints = intArray(x, x + delta, x - delta);
            ypoints = intArray(y - delta, y + delta, y + delta);
            shape = new Polygon(xpoints, ypoints, 3);
        }

        else if (shapetype == 3) {
            // diamond
            xpoints = intArray(x, x + delta, x, x - delta);
            ypoints = intArray(y - delta, y, y + delta, y);
            shape = new Polygon(xpoints, ypoints, 4);
        }

        else if (shapetype == 4) {
            // horizontal rectangle
            shape = new Rectangle2D.Double(x - delta, y - delta / 2, size,
                    size / 2);
        }

        else if (shapetype == 5) {
            // down-pointing triangle
            xpoints = intArray(x - delta, x + delta, x);
            ypoints = intArray(y - delta, y - delta, y + delta);
            shape = new Polygon(xpoints, ypoints, 3);
        }

        else if (shapetype == 6) {
            // horizontal ellipse
            shape = new Ellipse2D.Double(x - delta, y - delta / 2, size,
                    size / 2);
        }

        else if (shapetype == 7) {
            // right-pointing triangle
            xpoints = intArray(x - delta, x + delta, x - delta);
            ypoints = intArray(y - delta, y, y + delta);
            shape = new Polygon(xpoints, ypoints, 3);
        }

        else if (shapetype == 8) {
            // vertical rectangle
            shape = new Rectangle2D.Double(x - delta / 2, y - delta, size / 2,
                    size);
        }

        else if (shapetype == 9) {
            // left-pointing triangle
            xpoints = intArray(x - delta, x + delta, x + delta);
            ypoints = intArray(y, y - delta, y + delta);
            shape = new Polygon(xpoints, ypoints, 3);
        }

        else {
            // square
            shape = new Rectangle2D.Double(x - delta, y - delta, size, size);
        }

        return shape;
    }

    public int getNumLines() {
        return 10;
    }

    public int getNumShapes() {
        return 10;
    }

    private BasicStroke createLine() {
        BasicStroke line;
        float[] dash;

        if (linetype == 0) {
            dash = new float[] { 10.0f, 0.0f };
        } else if (linetype == 1) {
            dash = new float[] { 10.0f, 10.0f };
        } else if (linetype == 2) {
            dash = new float[] { 5.0f, 5.0f };
        } else if (linetype == 3) {
            dash = new float[] { 10.0f, 5.0f };
        } else if (linetype == 4) {
            dash = new float[] { 5.0f, 10.0f };
        } else if (linetype == 5) {
            dash = new float[] { 1.0f, 8.0f };
        } else if (linetype == 6) {
            dash = new float[] { 1.0f, 3.0f, 2.0f };
        } else if (linetype == 7) {
            dash = new float[] { 2.0f, 6.0f, 4.0f };
        } else if (linetype == 8) {
            dash = new float[] { 1.0f, 3.0f, 4.0f, 5.0f };
        } else if (linetype == 9) {
            dash = new float[] { 3.0f, 6.0f, 3.0f };
        } else if (linetype == -1) {
            dash = new float[] { 0.0f, 10.f };
        } else {
            dash = new float[] { 10.0f, 0.0f };
        }

        line = new BasicStroke(width, BasicStroke.CAP_ROUND,
                BasicStroke.JOIN_ROUND, 1.0f, dash, 0.0f);
        return line;
    }

    private int[] intArray(double a, double b, double c) {
        return new int[] { (int) a, (int) b, (int) c };
    }

    private static int[] intArray(double a, double b, double c, double d) {
        return new int[] { (int) a, (int) b, (int) c, (int) d };
    }

}
