/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/01/25, 15:38
!  AUTHOR(S): KOGA, Junichiro
!  File : ExporterGUIPanel.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.atomcoord.io;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;

import ciss.phase_viewer.atomcoord.AtomCoords;
import ciss.phase_viewer.common.ChaseFileChooser;
import ciss.phase_viewer.main.PluginLoader;

/**
 * エクスポート用GUIの内部のパネル. light-weightなコンポーネントもheavy-weightなコンポーネントもこのパネルを内部では利用する.
 * 
 * @author
 */
public class ExporterGUIPanel extends JPanel {
    private Logger logger = Logger.getLogger(ExporterGUIPanel.class.getName());
    private Exportable caller;
    private Exporter[] exporters;
    private JInternalFrame internalFrame;
    private JFrame jFrame;
    private AtomCoords[] targetCoords;

    /**
     * light-weightコンポーネントに使いたい場合このコンストラクターを使う
     * 
     * @param caller
     *            「export元」, エクスポートすべきAtomCoordsを作成/その参照を持っている
     * @param internalFrame
     *            呼び出し元のlight-weightコンポーネント
     */
    public ExporterGUIPanel(Exportable caller, JInternalFrame internalFrame) {
        this.caller = caller;
        this.internalFrame = internalFrame;
        this.targetCoords = caller.getCoordsToExport();
        init();
    }

    /**
     * heavy-weightコンポーネントに使いたい場合このコンストラクターを使う
     * 
     * @param caller
     *            「export元」, エクスポートすべきAtomCoordsを作成/その参照を持っている
     * @param jFrame
     *            呼び出し元のheavy-weightコンポーネント
     */
    public ExporterGUIPanel(Exportable caller, JFrame jFrame) {
        this.caller = caller;
        this.jFrame = jFrame;
        this.targetCoords = caller.getCoordsToExport();
        init();
    }

    private JComboBox comboType;
    private JTextField pathTF;
    private JButton bootChooser;
    private JButton btnopt;

    private void init() {
        createExporters();
        String[] types = new String[exporters.length];
        for (int i = 0; i < exporters.length; i++) {
            types[i] = exporters[i].getType();
        }
        comboType = new JComboBox(types);
        pathTF = new JTextField(20);
        bootChooser = new JButton("choose...");

        JPanel panel1 = new JPanel();

        JPanel pcomboType = new JPanel();
        pcomboType.setBorder(new TitledBorder("file type"));
        pcomboType.add(comboType);
        JPanel pchooser = new JPanel();
        btnopt = new JButton("options");

        pchooser.setLayout(new BoxLayout(pchooser, BoxLayout.X_AXIS));
        pchooser.add(pathTF);
        pchooser.add(bootChooser);
        pchooser.add(btnopt);

        panel1.add(pcomboType);
        panel1.add(pchooser);

        JPanel pbtns = new JPanel();
        pbtns.setLayout(new BoxLayout(pbtns, BoxLayout.X_AXIS));
        JButton exportbtn = new JButton("export");
        JButton btncancel = new JButton("cancel");
        pbtns.add(exportbtn);
        pbtns.add(btncancel);

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.add(panel1);
        panel.add(pbtns);

        comboType.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (exporters[comboType.getSelectedIndex()].hasOptions()) {
                    btnopt.setEnabled(true);
                } else {
                    btnopt.setEnabled(false);
                }
            }
        });

        bootChooser.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                chooser();
            }
        });

        exportbtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                new Thread(new doExport()).start();
                if (jFrame != null) {
                    jFrame.dispose();
                } else if (internalFrame != null) {
                    internalFrame.dispose();
                }
            }
        });

        btnopt.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                boolean isHeavy = true;
                if (internalFrame != null) {
                    isHeavy = false;
                }
                exporters[comboType.getSelectedIndex()].createOptionsPanel(
                        isHeavy, null, "");
            }
        });

        btncancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (jFrame != null) {
                    jFrame.dispose();
                } else if (internalFrame != null) {
                    internalFrame.dispose();
                }
            }
        });

        add(panel);
        comboType.setSelectedIndex(0);
    }

    /**
     * export作業は別スレッドで行うので, 別スレッドへ投げるためのRunnableインターフェースを実装したクラス.
     */
    class doExport implements Runnable {
        public void run() {
            String file = pathTF.getText();
            exporters[comboType.getSelectedIndex()].writeAtomCoordsTo(
                    targetCoords, file);
            caller.coordsExported(targetCoords, comboType.getSelectedItem()
                    .toString(), file);
        }
    }

    private void createExporters() {
        Document doc = ciss.phase_viewer.jdom.XMLUtils
                .getDocumentFromURL(AtomCoordsIO.SUPPORTED_FILETYPE);
        Element root = doc.getRootElement();
        java.util.List list = root.getChildren("exporter");
        Vector vec = new Vector();
        for (int i = 0; i < list.size(); i++) {
            String loadClass = ((Element) list.get(i))
                    .getChildTextTrim("loadclass");
            vec.addElement(loadClass);
        }
        exporters = new Exporter[vec.size()];
        for (int i = 0; i < vec.size(); i++) {
            String load = (String) vec.get(i);
            exporters[i] = (Exporter) PluginLoader.instantiate(load, null);
        }
    }

    private void chooser() {
        ChaseFileChooser fdlg = new ChaseFileChooser(ChaseFileChooser.atom,
                true);

        fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
        fdlg.setDialogTitle("select atomic configuration file");
        fdlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
        javax.swing.filechooser.FileFilter filter = exporters[comboType
                .getSelectedIndex()].getFileFilter();
        if (filter != null) {
            fdlg.addChoosableFileFilter(filter);
        }

        if (fdlg.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) {
            return;
        }
        pathTF.setText(fdlg.getSelectedFile().getAbsolutePath());
    }

}
