/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/12/01, 11:50
!  AUTHOR(S): KOGA, Junichiro
!  File : MouseMotionListenerChartPanel.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.mouse;

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.Format;

import javax.swing.JLabel;
import javax.swing.JPanel;

import org.apache.log4j.Logger;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.CombinedRangeXYPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;

import ciss.phase_viewer.graph.GraphPanel;
import ciss.phase_viewer.graph.dataset.PlotProperties;

/**
 * ChartPanelに付加するMouseMotionListener
 * (ChartPanelにはすでにズーム用のMouseMotionListenerはついている).
 * 
 * @author
 */
public class MouseMotionListenerChartPanel implements MouseMotionListener {
    private Logger logger = Logger
            .getLogger(MouseMotionListenerChartPanel.class.getName());
    private GraphPanel graphPanel;
    private JLabel labelxy;
    private Format format = ciss.phase_viewer.common.ConstParameters.formater_float;

    /** Creates a new instance of MouseListenerChartPanel */
    public MouseMotionListenerChartPanel(GraphPanel panel) {
        this.graphPanel = panel;
        labelxy = new JLabel("x: y: ");
        if (panel.getPlotProperties().getPlotType() == PlotProperties.XYPLOT) {
            JPanel p = new JPanel();
            p.setLayout(new BorderLayout());
            p.add(labelxy, BorderLayout.WEST);
            this.graphPanel.getContentPane().add(p, "South");
        }
    }

    public void mouseMoved(MouseEvent e) {
        float[] pos = mousePos2GraphPos(e);
        if (pos != null) {
            labelxy.setText(" x:  " + format.format(String.valueOf(pos[0]))
                    + "  y:  " + format.format(String.valueOf(pos[1])));
        }
    }

    private float[] prevPos = { 0, 0 };
    private int ignoreCount = 0;

    public void mouseDragged(MouseEvent e) {
        // if ( e.getButton() != MouseEvent.BUTTON3 ) {
        // return;
        // }
        // if ( ignoreCount < 5 ) {
        // ignoreCount++;
        // return;
        // }
        ignoreCount = 0;
        if (prevPos == null) {
            prevPos = new float[2];
            prevPos = mousePos2GraphPos(e);
            return;
        }
        float[] currentPos = mousePos2GraphPos(e);
        if (currentPos == null) {
            return;
        }
        logger.debug("currentPos: x=" + currentPos[0] + ", y=" + currentPos[1]);
        logger.debug("previousPos: x=" + prevPos[0] + ", y=" + prevPos[1]);
        float difx = prevPos[0] - currentPos[0];
        float dify = prevPos[1] - currentPos[1];
        Plot plot = graphPanel.getChart().getPlot();
        if (!(plot instanceof CombinedDomainXYPlot)
                && !(plot instanceof CombinedRangeXYPlot)) {
            return;
        }

        PlotRenderingInfo plotinfo = graphPanel.getChartPanel()
                .getChartRenderingInfo().getPlotInfo();
        XYPlot xyplot = null;
        if (plot instanceof CombinedDomainXYPlot) {
            xyplot = ((CombinedDomainXYPlot) plot).findSubplot(plotinfo,
                    new Point2D.Double((double) e.getX(), (double) e.getY()));
        } else if (plot instanceof CombinedRangeXYPlot) {
            xyplot = ((CombinedRangeXYPlot) plot).findSubplot(plotinfo,
                    new Point2D.Double((double) e.getX(), (double) e.getY()));
        }
        if (xyplot == null) {
            return;
        }

        ValueAxis domain = xyplot.getDomainAxis();
        ValueAxis range = xyplot.getRangeAxis();
        double xmin = domain.getLowerBound();
        double xmax = domain.getUpperBound();
        double ymin = range.getLowerBound();
        double ymax = range.getUpperBound();

        double newxmin = xmin + (float) difx;
        double newxmax = xmax + (float) difx;
        double newymin = ymin + (float) dify;
        double newymax = ymax + (float) dify;
        domain.setLowerBound(newxmin);
        domain.setUpperBound(newxmax);
        range.setLowerBound(newymin);
        range.setUpperBound(newymax);
        prevPos[0] = currentPos[0];
        prevPos[1] = currentPos[1];
    }

    private ValueAxis domain;
    private ValueAxis range;
    private double xmin;
    private double xmax;
    private double ymin;
    private double ymax;
    private double xh;
    private double yh;

    private float[] mousePos2GraphPos(MouseEvent e) {
        Plot plot = graphPanel.getChart().getPlot();
        if (!(plot instanceof CombinedDomainXYPlot)
                && !(plot instanceof CombinedRangeXYPlot)) {
            return null;
        }

        PlotRenderingInfo plotinfo = graphPanel.getChartPanel()
                .getChartRenderingInfo().getPlotInfo();
        XYPlot xyplot = null;
        if (plot instanceof CombinedDomainXYPlot) {
            xyplot = ((CombinedDomainXYPlot) plot).findSubplot(plotinfo,
                    new Point2D.Double((double) e.getX(), (double) e.getY()));
        } else if (plot instanceof CombinedRangeXYPlot) {
            xyplot = ((CombinedRangeXYPlot) plot).findSubplot(plotinfo,
                    new Point2D.Double((double) e.getX(), (double) e.getY()));
        }
        if (xyplot == null) {
            return null;
        }

        domain = xyplot.getDomainAxis();
        range = xyplot.getRangeAxis();

        xmin = domain.getLowerBound();
        xmax = domain.getUpperBound();
        ymin = range.getLowerBound();
        ymax = range.getUpperBound();

        Rectangle2D dataArea = graphPanel.getChartPanel().getScreenDataArea(
                e.getX(), e.getY());
        if (dataArea == null) {
            return null;
        }
        double x = (double) e.getX() - dataArea.getX();
        double y = dataArea.getY() + dataArea.getHeight() - (double) e.getY();
        xh = (xmax - xmin) / dataArea.getWidth();
        yh = (ymax - ymin) / dataArea.getHeight();

        float posx = (float) (xmin + x * xh);
        float posy = (float) (ymin + y * yh);
        return new float[] { posx, posy };
    }

}
