/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/07/20, 11:56
!  AUTHOR(S): KOGA, Junichiro
!  File : SymmetryPointBG.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.acviewer.fbz;

import java.text.DecimalFormat;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import Jama.Matrix;

/**
 * 「対称点」を内包するBranchGroup
 * 
 * @author
 */
public class SymmetryPointBG extends BranchGroup {
    private Vector3f position;

    private Color3f selectedColor = new Color3f(1f, 0.8f, 0.4f);
    private Color3f unselectedColor = new Color3f(0f, 0.2f, 0.6f);

    private Appearance appearance;
    private Material material;

    private SymmetryPoint point;
    private WignerSeitzAttributes wsattrs;
    private Point3f[] lat;

    /**
     * 座標を指定して作成
     * 
     * @param position
     *            この対称点の座標
     * @param lat
     *            逆格子ベクトル
     * @param wsattrs
     *            描画方法の情報
     */
    public SymmetryPointBG(Vector3f position, Point3f[] lat,
            WignerSeitzAttributes wsattrs) {
        this.position = position;
        this.lat = lat;
        this.wsattrs = wsattrs;
        float rad = 0;
        if (wsattrs != null)
            rad = wsattrs.symmetricPointRadius;
        point = new SymmetryPoint(rad, wsattrs);
        point.setBG(this);

        TransformGroup tg = new TransformGroup();
        Transform3D t3d = new Transform3D();
        t3d.setTranslation(position);
        tg.setTransform(t3d);
        tg.addChild(point);

        addChild(tg);

        setCapability(BranchGroup.ENABLE_PICK_REPORTING);
    }

    public void setSelected(boolean selected) {
        point.setSelected(selected);
    }

    public boolean isSelected() {
        return point.isSelected();
    }

    public SymmetryPoint getPoint() {
        return point;
    }

    private String symbol = "";

    /**
     * この対称点に対応する記号をセット
     * 
     * @param この対称点の記号
     *            ; 例: 0,0,0から{/Symbol G}とか.
     */
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    /**
     * この対称点に対応する記号を取得
     * 
     * @return この対称点の記号
     */
    public String getSymbol() {
        return symbol;
    }

    private int[] xbunsu;

    private int[] ybunsu;
    private int[] zbunsu;
    private Point3f scaledPos;

    private void generateBunsuCoords() {
        double[][] bmat = new double[3][3];
        double[][] kmat = new double[3][1];
        kmat[0][0] = (double) position.x;
        kmat[1][0] = (double) position.y;
        kmat[2][0] = (double) position.z;
        for (int i = 0; i < 3; i++) {
            bmat[0][i] = (double) lat[i].x;
            bmat[1][i] = (double) lat[i].y;
            bmat[2][i] = (double) lat[i].z;
        }
        Matrix B = new Matrix(bmat);
        Matrix K = new Matrix(kmat);
        Matrix S = B.solve(K);
        int[] xbunsu__ = FBZUtils.getBunsu((float) S.get(0, 0));
        int[] ybunsu__ = FBZUtils.getBunsu((float) S.get(1, 0));
        int[] zbunsu__ = FBZUtils.getBunsu((float) S.get(2, 0));

        scaledPos = new Point3f();
        scaledPos.x = (float) S.get(0, 0);
        scaledPos.y = (float) S.get(1, 0);
        scaledPos.z = (float) S.get(2, 0);

        xbunsu = new int[] { xbunsu__[1], xbunsu__[2] };
        ybunsu = new int[] { ybunsu__[1], ybunsu__[2] };
        zbunsu = new int[] { zbunsu__[1], zbunsu__[2] };
    }

    /**
     * 分数で表示された座標を取得するメソッド.
     * 
     * @return 二次元の配列であり, 第一要素の0がx, 第二要素の1がy, 第三要素の2がzに相当する.
     *         さらに第二要素に相当するint配列は0番目が分子, 1番目が分母に相当する.
     */
    public int[][] getBunsuCoords() {
        if (xbunsu == null || ybunsu == null || zbunsu == null) {
            generateBunsuCoords();
        }
        return new int[][] { xbunsu, ybunsu, zbunsu };
    }

    /**
     * この対称点の座標を, 逆格子ベクトルで表した座標を取得.
     * 
     * @return 上記の通り
     */
    public Point3f getScaledPos() {
        if (scaledPos == null) {
            generateBunsuCoords();
        }
        return scaledPos;
    }

    /**
     * この対称点の座標を取得する.
     * 
     * @return 対称点の座標
     */
    public Vector3f getPos() {
        return this.position;
    }

    private DecimalFormat format = new DecimalFormat("0.000");

    public String toString() {
        if (xbunsu == null || ybunsu == null || zbunsu == null) {
            generateBunsuCoords();
        }
        String str = "pos: " + xbunsu[0] + "/" + xbunsu[1] + ", " + ybunsu[0]
                + "/" + ybunsu[1] + ", " + zbunsu[0] + "/" + zbunsu[1];
        return str;
    }

}
