/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/10/19, 18:20
!  AUTHOR(S): KOGA, Junichiro
!  File : RightClickAction.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.mouselistener;

import java.awt.event.MouseEvent;
import java.util.Enumeration;
import java.util.Vector;

import javax.media.j3d.Behavior;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Transform3D;
import javax.vecmath.Matrix3d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import org.apache.log4j.Logger;

import ciss.phase_viewer.acviewer.MainPanel;
import ciss.phase_viewer.acviewer.scenegraphelements.DynamicallyEditable;
import ciss.phase_viewer.acviewer.scenegraphelements.TGAtom;
import ciss.phase_viewer.acviewer.scenegraphelements.atom.AtomObjectBG;
import ciss.phase_viewer.acviewer.scenegraphelements.atom.AtomSphere;

import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.PickTool;

/**
 * 「右クリック」時の動作.
 * 
 * @author
 */
public class RightClickAction extends MouseMotionListenerAction {
    private Logger logger = Logger.getLogger(RightClickAction.class.getName());

    private double x_last = 0.d;
    private double y_last = 0.d;

    private Transform3D buffer;

    private PickCanvas pickTool;

    /** Creates a new instance of RightClickAction */
    public RightClickAction(MainPanel parent) {
        super(parent);
        pickTool = new PickCanvas(parent.getCanvas(), parent.getRootBranch());
        pickTool.setMode(PickTool.GEOMETRY);
    }

    private boolean moveAtoms = false;
    private boolean inAction = false;

    void init(MouseEvent e) {
        if (inAction)
            return;
        x_last = 0.d;
        y_last = 0.d;
        buffer = new Transform3D();

        pickTool.setShapeLocation(e);
        PickResult[] result = pickTool.pickAllSorted();
        boolean tmp = false;
        if (result != null) {
            for (int i = 0; i < result.length; i++) {
                Primitive pri = (Primitive) result[i]
                        .getNode(PickResult.PRIMITIVE);
                // logger.debug("primitive selected: "+pri.getClass().getName());
                if (pri != null && pri instanceof AtomSphere) {
                    AtomSphere atom = (AtomSphere) pri;
                    if (atom.getAtomObject().isSelected()) {
                        tmp = true;
                        break;
                    }
                }
            }
        }

        moveAtoms = tmp;

        if (moveAtoms) {
            BranchGroup root = parent.getRootBranch();
            Enumeration enu = root.getAllChildren();
            while (enu.hasMoreElements()) {
                Object object = enu.nextElement();
                if (object instanceof MouseTranslate) {
                    ((Behavior) object).setEnable(false);
                }
            }
        }
        inAction = true;

    }

    void finalize(MouseEvent e) {
        inAction = false;
        TGAtom tgatom = (TGAtom) parent.getScene().getTGAtom();
        int selected = tgatom.getSelectedAtomCount();
        if (selected == 0) {
            return;
        }

        if (!moveAtoms)
            return;

        DynamicallyEditable[] editable = tgatom
                .getDynamicallyEditableElements();

        boolean update = false;
        Vector aobjVector = new Vector();
        Vector buffervec = new Vector();

        for (int i = 0; i < editable.length; i++) {
            editable[i].dynamicallyEditFinalize(tgatom);
            buffervec.addElement(editable[i].getBuffer());
        }
        parent.getCD().getAtomCoords().getAtomList().setUndoCount(selected);
        parent.getCD().update();

        for (int i = 0; i < buffervec.size(); i++) {
            if (buffervec.elementAt(i) != null) {
                ((BranchGroup) buffervec.elementAt(i)).detach();
            }
        }

        for (int i = 0; i < buffervec.size(); i++) {
            if (buffervec.elementAt(i) instanceof AtomObjectBG) {
                ((AtomObjectBG) buffervec.elementAt(i))
                        .getAssociatedAtomObject().createBuffer();
            }
        }

        x_last = 0.d;
        y_last = 0.d;
        buffer = new Transform3D();

        BranchGroup root = parent.getRootBranch();
        Enumeration enu = root.getAllChildren();
        while (enu.hasMoreElements()) {
            Object object = enu.nextElement();
            if (object instanceof MouseTranslate) {
                ((Behavior) object).setEnable(true);
            }
        }
    }

    void processMouseDrag(MouseEvent e) {
        if (!moveAtoms) {
            logger.debug("moveAtoms=false");
            return;
        }
        logger.debug(this);
        logger.debug(" modifiersex: "
                + MouseEvent.getModifiersExText(e.getModifiersEx()));
        // if ( ((TGAtom) parent.getScene().getTGAtom()).getSelectedAtomCount()
        // == 0 ) {
        // return;
        // }

        Point3d ptmp = getCoordsFromMousePos(parent, e);
        double x = ptmp.x;
        double y = ptmp.y;

        if (x_last == 0.d && y_last == 0.d) {
            x_last = x;
            y_last = y;
            return;
        }

        Transform3D tgatom3d = new Transform3D();
        parent.getScene().getTGAtom().getTransform(tgatom3d);

        if (!tgatom3d.equals(buffer)) {
            buffer = new Transform3D(tgatom3d);
            x_last = x;
            y_last = y;
            return;
        }

        double dx = x - x_last;
        double dy = y - y_last;

        TGAtom tgatom = (TGAtom) parent.getScene().getTGAtom();
        Vector3d translation = new Vector3d();
        translation.x = dx;
        translation.y = -dy;
        Matrix3d rotation = new Matrix3d();
        Transform3D transform3d = new Transform3D(rotation, translation, 1.d);
        DynamicallyEditable[] editables = tgatom
                .getDynamicallyEditableElements();
        if (editables == null || editables.length == 0) {
            logger.debug("no editable tg");
            return;
        }
        for (int i = 0; i < editables.length; i++) {
            editables[i].dynamicallyEditIntermediateState(transform3d, tgatom,
                    e);
        }
        x_last = x;
        y_last = y;
        logger.debug("x_last, y_last: " + x_last + ", " + y_last);
    }

    void processMouseMove(MouseEvent e) {
    }

    public String toString() {
        return "right click action!";
    }
}
