/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/11/18, 17:57
!  AUTHOR(S): KOGA, Junichiro
!  File : Annotations.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.plugins.graph.plotattributes;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;
import org.jfree.chart.annotations.XYImageAnnotation;
import org.jfree.chart.annotations.XYPointerAnnotation;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;

import ciss.phase_viewer.common.ChaseFileChooser;
import ciss.phase_viewer.common.FontChooser;
import ciss.phase_viewer.graph.plotattributes.PlotAttributesEditor;
import ciss.phase_viewer.graph.plotattributes.PlotAttributesSubEditor;

/**
 * 注釈などをグラフに付加.
 * 
 * @author
 */
public class Annotations extends PlotAttributesSubEditor {
    private Logger logger = Logger.getLogger(Annotations.class.getName());

    private XYPlot xyplot;
    private JPanel me;

    /** Creates a new instance of Annotations */
    public Annotations(PlotAttributesEditor parent) {
        super(parent);
    }

    protected void init() {
        me = this;
        if (parent == null) {
            logger.debug("'parent' is null.");
            return;
        }
        Plot plot = parent.getSelectedPlot();
        if (plot == null) {
            logger.debug("'plot' is null.");
            return;
        }

        if (plot instanceof XYPlot) {
            xyplot = (XYPlot) plot;
        } else {
            return;
        }
    }

    public boolean updateChart() {
        /* text annotation */
        String text = tftextannotation.getText();
        double textposx = 0.d;
        double textposy = 0.d;
        double textrot = 0.d;

        try {
            textposx = Double
                    .parseDouble(tftextannotationposx.getText().trim());
            textposy = Double
                    .parseDouble(tftextannotationposy.getText().trim());
            textrot = Double.parseDouble(tftextannotationrotation.getText()
                    .trim());
        } catch (Exception exc) {
        }

        XYTextAnnotation textAnnotation = new XYTextAnnotation(text, textposx,
                textposy);
        textAnnotation.setFont(btntextannotation.getFont());
        textAnnotation.setRotationAngle(Math.PI * textrot / 180.0);
        if (combotextannotation.getSelectedIndex() != 1) {
            xyplot.clearAnnotations();
        }
        if (combotextannotation.getSelectedIndex() != 2) {
            xyplot.addAnnotation(textAnnotation);
        }

        /* image annotation */
        if (imageFileName != null) {
            File f = new File(imageFileName);
            BufferedImage image;
            double imageScale = 1.d;
            double imposx = 0.d;
            double imposy = 0.d;
            try {
                imageScale = Double.valueOf(tfimagescale.getText())
                        .doubleValue();
                imposx = Double.valueOf(tfimageposx.getText()).doubleValue();
                imposy = Double.valueOf(tfimageposy.getText()).doubleValue();
            } catch (Exception exc) {
            }

            int image_width = (int) (((double) parent.getGraphPanel().getSize().width) * imageScale);
            try {
                image = ImageIO.read(f);
                XYImageAnnotation imageAnnotation = new XYImageAnnotation(
                        imposx, imposy, image.getScaledInstance(image_width,
                                -100, java.awt.Image.SCALE_SMOOTH));
                xyplot.addAnnotation(imageAnnotation);
            } catch (IOException ex) {
                ex.printStackTrace();
                logger.error("failed to put image annotation");
            }
        }

        /* arrow annotation */
        if (cbptan.isSelected()) {
            String pttext = tfptanlabel.getText();
            double ptx = 0.d;
            double pty = 0.d;
            double ptrot = 0.d;
            double ptbase = 0.d;
            double ptoffset = 0.d;
            try {
                ptx = Double.parseDouble(tfptanposx.getText());
                pty = Double.parseDouble(tfptanposy.getText());
                ptrot = Double.parseDouble(tfptanrotate.getText());
                ptbase = Double.parseDouble(tfptanbase.getText());
                ptoffset = Double.parseDouble(tfptanlabeloffset.getText());
            } catch (Exception exc) {
            }

            XYPointerAnnotation pointerAnnotation = new XYPointerAnnotation(
                    pttext, ptx, pty, Math.PI * ptrot / 180.0);

            pointerAnnotation.setBaseRadius(ptbase);
            pointerAnnotation.setLabelOffset(ptoffset);
            pointerAnnotation.setFont(btnptanlabelfont.getFont());
            xyplot.addAnnotation(pointerAnnotation);
        }

        return true;
    }

    private double avx;
    private double avy;
    private java.text.Format form = ciss.phase_viewer.common.ConstParameters.formater_smaller_digits;

    protected void initGUI() {
        removeAll();
        setLayout(new BorderLayout());

        JPanel p = new JPanel();
        p.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.weightx = 1;
        constraints.weighty = 0;

        p.add(createText(), constraints);

        constraints.gridy = 1;
        p.add(createImage(), constraints);

        constraints.gridy = 2;
        p.add(createArrow(), constraints);

        add(p, BorderLayout.NORTH);
    }

    private JTextField tftextannotation;
    private JTextField tftextannotationposx;
    private JTextField tftextannotationposy;
    private JTextField tftextannotationrotation;
    private JButton btntextannotation;
    private JComboBox combotextannotation;

    private JPanel createText() {
        String[] strtextannotation = { "new", "add", "clear all" };
        JPanel ptextan = new JPanel();
        ptextan.setLayout(new BoxLayout(ptextan, BoxLayout.Y_AXIS));
        ptextan.setBorder(new TitledBorder("text annotation"));

        JPanel pcomboandpos = new JPanel();
        pcomboandpos.setLayout(new BoxLayout(pcomboandpos, BoxLayout.X_AXIS));

        JPanel pcombo = new JPanel();
        combotextannotation = new JComboBox(strtextannotation);
        JPanel pcombotext = new JPanel();
        pcombotext.setBorder(new TitledBorder("mode"));
        pcombotext.add(combotextannotation);
        pcombo.add(pcombotext);
        pcomboandpos.add(pcombo);

        JPanel tfpos = new JPanel();
        JPanel tfx = new JPanel();
        JPanel tfy = new JPanel();
        JPanel tfrot = new JPanel();

        tfx.setBorder(new TitledBorder("position (x)"));
        tfy.setBorder(new TitledBorder("position (y)"));
        tfrot.setBorder(new TitledBorder("rot (degrees)"));
        tftextannotationposx = new JTextField(7);
        tftextannotationposy = new JTextField(7);
        tftextannotationrotation = new JTextField(7);
        tfx.add(tftextannotationposx);
        tfy.add(tftextannotationposy);
        tfrot.add(tftextannotationrotation);
        tfpos.add(tfx);
        tfpos.add(tfy);
        tfpos.add(tfrot);
        pcomboandpos.add(tfpos);

        avx = (xyplot.getDomainAxis().getLowerBound() + xyplot.getDomainAxis()
                .getUpperBound()) / 2.0;
        avy = (xyplot.getRangeAxis().getLowerBound() + xyplot.getRangeAxis()
                .getUpperBound()) / 2.0;
        tftextannotationposx.setText(form.format(new Double(avx)));
        tftextannotationposy.setText(form.format(new Double(avy)));
        tftextannotationrotation.setText("0.0");
        ptextan.add(pcomboandpos);

        tftextannotation = new JTextField(15);
        JPanel ptftext = new JPanel();
        ptftext.setBorder(new TitledBorder("annotation text"));
        ptftext.setLayout(new BoxLayout(ptftext, BoxLayout.X_AXIS));
        btntextannotation = new JButton("select font");

        ptftext.add(tftextannotation);
        ptftext.add(btntextannotation);

        ptextan.add(ptftext);

        /* add action listeners */
        btntextannotation.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Font font = FontChooser.chooseFont(btntextannotation.getFont(),
                        me);
                btntextannotation.setFont(font);
            }
        });

        return ptextan;
    }

    private String imageFileName;
    private JButton btnimageselect;
    private JTextField tfimagescale;
    private JTextField tfimageposx;
    private JTextField tfimageposy;

    private JPanel createImage() {
        JPanel pimagean = new JPanel();
        pimagean.setBorder(new TitledBorder("image annotation"));
        pimagean.setLayout(new BoxLayout(pimagean, BoxLayout.X_AXIS));
        btnimageselect = new JButton("choose image file");
        JPanel pimagepos = new JPanel();
        pimagepos.setLayout(new BoxLayout(pimagepos, BoxLayout.X_AXIS));

        tfimagescale = new JTextField(7);
        tfimagescale.setText("1.0");
        JPanel pimscale = new JPanel();
        pimscale.setBorder(new TitledBorder("scale"));
        pimscale.add(tfimagescale);

        tfimageposx = new JTextField(7);
        JPanel pimposx = new JPanel();
        pimposx.setBorder(new TitledBorder("position(x)"));
        pimposx.add(tfimageposx);
        tfimageposx.setText(form.format(new Double(avx)));

        tfimageposy = new JTextField(7);
        JPanel pimposy = new JPanel();
        pimposy.setBorder(new TitledBorder("position(y)"));
        pimposy.add(tfimageposy);
        tfimageposy.setText(form.format(new Double(avy)));

        pimagepos.add(pimscale);
        pimagepos.add(pimposx);
        pimagepos.add(pimposy);

        pimagean.add(btnimageselect);
        pimagean.add(pimagepos);

        btnimageselect.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ChaseFileChooser fdlg = new ChaseFileChooser(
                        ChaseFileChooser.media);
                fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
                fdlg.setDialogTitle("select image");
                fdlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
                fdlg.addChoosableFileFilter(new ciss.phase_viewer.common.ImageFilter());
                if (fdlg.showDialog(me, "open") != JFileChooser.APPROVE_OPTION) {
                    imageFileName = null;
                } else {
                    imageFileName = fdlg.getSelectedFile().getAbsolutePath();
                    File file = new File(imageFileName);
                    btnimageselect.setText(file.getName());
                }
            }
        });

        return pimagean;
    }

    private JCheckBox cbptan;
    private JButton btnptanlabelfont;

    private JTextField tfptanposx;
    private JTextField tfptanposy;
    private JTextField tfptanrotate;
    private JTextField tfptanbase;

    private JTextField tfptanlabel;
    private JTextField tfptanlabeloffset;

    private JPanel createArrow() {
        cbptan = new JCheckBox("display");
        JPanel parrowattributes = new JPanel();
        parrowattributes.setLayout(new BoxLayout(parrowattributes,
                BoxLayout.X_AXIS));

        tfptanposx = new JTextField(5);
        JPanel ptfptanposx = new JPanel();
        ptfptanposx.setBorder(new TitledBorder("position(x)"));
        ptfptanposx.add(tfptanposx);
        tfptanposx.setText(form.format(new Double(avx)));

        tfptanposy = new JTextField(5);
        JPanel ptfptanposy = new JPanel();
        ptfptanposy.setBorder(new TitledBorder("position(y)"));
        ptfptanposy.add(tfptanposy);
        tfptanposy.setText(form.format(new Double(avy)));

        tfptanrotate = new JTextField(5);
        JPanel ptfptanrotate = new JPanel();
        ptfptanrotate.setBorder(new TitledBorder("rotate(deg.)"));
        ptfptanrotate.add(tfptanrotate);
        tfptanrotate.setText("0.0");

        tfptanbase = new JTextField(5);
        JPanel ptfptanbase = new JPanel();
        ptfptanbase.setBorder(new TitledBorder("base"));
        ptfptanbase.add(tfptanbase);
        tfptanbase.setText("50.0");

        parrowattributes.add(ptfptanposx);
        parrowattributes.add(ptfptanposy);
        parrowattributes.add(ptfptanrotate);
        parrowattributes.add(ptfptanbase);

        JPanel parrow = new JPanel();
        parrow.setLayout(new BoxLayout(parrow, BoxLayout.X_AXIS));

        parrow.add(cbptan);
        parrow.add(parrowattributes);

        JPanel pptan = new JPanel();
        pptan.add(parrow);

        JPanel parrowlabel = new JPanel();
        parrowlabel.setLayout(new BoxLayout(parrowlabel, BoxLayout.X_AXIS));

        tfptanlabel = new JTextField(7);
        JPanel ptfptanlabel = new JPanel();
        ptfptanlabel.setBorder(new TitledBorder("label text"));
        ptfptanlabel.add(tfptanlabel);

        btnptanlabelfont = new JButton("select font");
        JPanel pbtnptanlabelfont = new JPanel();
        pbtnptanlabelfont.setBorder(new TitledBorder("label font"));
        pbtnptanlabelfont.add(btnptanlabelfont);

        tfptanlabeloffset = new JTextField(5);
        JPanel ptfptanlabeloffset = new JPanel();
        ptfptanlabeloffset.setBorder(new TitledBorder("label offset"));
        ptfptanlabeloffset.add(tfptanlabeloffset);
        tfptanlabeloffset.setText("10.0");

        parrowlabel.add(ptfptanlabel);
        parrowlabel.add(pbtnptanlabelfont);
        parrowlabel.add(ptfptanlabeloffset);
        pptan.setBorder(new TitledBorder("arrow annotation"));
        pptan.setLayout(new BoxLayout(pptan, BoxLayout.Y_AXIS));
        pptan.add(parrowlabel);

        btnptanlabelfont.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Font font = FontChooser.chooseFont(btnptanlabelfont.getFont(),
                        me);
                btnptanlabelfont.setFont(font);
            }
        });

        return pptan;
    }

    public void plotChanged(Plot plot) {
        updateChart();
        init();
        initGUI();
        revalidate();
    }

}
