/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/08/16, 14:19
!  AUTHOR(S): KOGA, Junichiro
!  File : ChargeDensityPanel.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.projectmanipulator.phase.resultsviewerpanel;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.apache.log4j.Logger;

import ciss.phase_viewer.acviewer.ACVCaller;
import ciss.phase_viewer.acviewer.ACVData;
import ciss.phase_viewer.atomcoord.AtomCoords;
import ciss.phase_viewer.atomcoord.Cube2AtomCoords;
import ciss.phase_viewer.atomcoord.symmetry.BravaisLattice;
import ciss.phase_viewer.common.CoordsViewerBooter;
import ciss.phase_viewer.common.StringConstants;
import ciss.phase_viewer.file.ChaseFile;
import ciss.phase_viewer.inputinterface.DataManager;
import ciss.phase_viewer.plugins.projectmanipulator.phase.PhaseConstants;
import ciss.phase_viewer.projectbrowser.ProjectBrowserUtils;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.projectbrowser.ProjectManipulator;
import ciss.phase_viewer.projectbrowser.tools.NoFilePanel;

/**
 * 
 * @author KOGA, Junichiro
 */
public class ChargeDensityPanel extends ProjectManipulator implements
        ACVCaller, MouseListener, KeyListener {
    private Logger logger = Logger
            .getLogger(ChargeDensityPanel.class.getName());

    private String name;

    private ChaseFile cf;

    private String[] names;

    private GridBagLayout gridbag = new GridBagLayout();

    private GridBagConstraints constraints = new GridBagConstraints();

    /** Creates a new instance of ChargeDensityPanel */
    public ChargeDensityPanel(ProjectInfo projectInfo) {
        super(projectInfo);
        setLayout(new BorderLayout());
    }

    public void init() {
        removeAll();
        cf = projectInfo.getChaseFileManager().getFile("F_CHR");
        name = cf.getDefaultName().getValue();
        logger.debug("F_CHR file: " + name);
        createNames();
        createPanel();
    }

    private void createNames() {
        File dir = new File(projectInfo.getProjectDirectory());
        String[] files = dir.list();
        if (files == null || files.length == 0) {
            return;
        }

        Vector chrVec = new Vector();
        for (int i = 0; i < files.length; i++) {
            if (files[i].matches(name)) {
                chrVec.addElement(files[i]);
            }
        }

        if (chrVec.size() == 0) {
            return;
        }

        names = new String[chrVec.size()];
        chrVec.copyInto(names);
    }

    private JComboBox fileChooser;

    private JList fileList;

    private JLabel label1 = new JLabel();

    private JLabel label2 = new JLabel();

    private void createPanel() {
        JPanel panel = new JPanel();
        // panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
        panel.setLayout(gridbag);

        JPanel panel1 = new JPanel();
        panel1.setLayout(new BoxLayout(panel1, BoxLayout.X_AXIS));
        panel1.setBorder(new TitledBorder("select charge file"));

        if (names == null || names.length == 0) {
            add(new NoFilePanel("F_CHR"));
            return;
        }

        fileChooser = new JComboBox(names);
        fileList = new JList(names);

        fileList.addMouseListener(this);
        fileList.addKeyListener(this);

        JScrollPane sp = new JScrollPane(fileList);
        sp.setPreferredSize(new Dimension(200, 100));

        // panel1.add(fileChooser);
        panel1.add(sp);
        readHeaders(projectInfo.getProjectDirectory()
                + System.getProperty("file.separator")
                + names[names.length - 1]);

        JButton bootBSV = new JButton("boot BioStationViewer");
        JButton bootViewer = new JButton("boot internal viewer");
        JButton bootEditor = new JButton("boot editor");
        // panel1.add(bootBSV);
        panel1.add(bootViewer);
        panel1.add(bootEditor);

        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.anchor = GridBagConstraints.NORTH;
        constraints.weightx = 1;
        constraints.weighty = 0;
        constraints.fill = GridBagConstraints.BOTH;

        panel.add(panel1, constraints);

        JPanel panel2 = new JPanel();
        panel2.setBorder(new TitledBorder("info"));
        panel2.setLayout(new BoxLayout(panel2, BoxLayout.X_AXIS));
        JPanel plabel1 = new JPanel();
        plabel1.setBorder(new TitledBorder("title"));
        JPanel plabel2 = new JPanel();
        plabel2.setBorder(new TitledBorder("comment"));
        plabel1.add(label1);
        plabel2.add(label2);
        panel2.add(plabel1);
        panel2.add(plabel2);

        constraints.gridx = 0;
        constraints.gridy = 1;
        panel.add(panel2, constraints);
        //
        // fileChooser.addActionListener(new ActionListener(){
        // public void actionPerformed(ActionEvent e) {
        // String chfileNow =
        // projectInfo.getProjectDirectory()+System.getProperty("file.separator")+(String)
        // fileChooser.getSelectedItem();
        // readHeaders(chfileNow);
        // }
        // });

        fileList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                String chfileNow = projectInfo.getProjectDirectory()
                        + System.getProperty("file.separator")
                        + (String) fileList.getSelectedValue();
                readHeaders(chfileNow);
            }
        });

        bootEditor.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String chfileNow = projectInfo.getProjectDirectory()
                        + System.getProperty("file.separator")
                        + (String) fileList.getSelectedValue();
                ProjectBrowserUtils.bootTextViewer(chfileNow);
            }
        });

        bootBSV.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String chfileNow = projectInfo.getProjectDirectory()
                        + System.getProperty("file.separator")
                        + (String) fileList.getSelectedValue();
                ProjectBrowserUtils.bootBioStationViewer(chfileNow);
            }
        });

        bootViewer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String chfileNow = projectInfo.getProjectDirectory()
                        + System.getProperty("file.separator")
                        + (String) fileList.getSelectedValue();
                bootViewer();
            }
        });

        // fileChooser.setSelectedIndex(fileChooser.getItemCount()-1);

        this.add(panel, BorderLayout.NORTH);
        fileList.setSelectedIndex(0);
    }

    // /**
    // * GaussianCube形式のファイルを内蔵ビューアーで起動するメソッド.
    // * 補間の種類も選択できる.
    // */
    // public static void bootCubeViewer(String [] cubeFiles, int
    // interpolationScheme) {
    // if ( cubeFiles == null || cubeFiles.length == 0 ) {
    // //logger.info("file not selected");
    // return;
    // }
    // Cube2AtomCoords c2a = new Cube2AtomCoords(cubeFiles[0]);
    // AtomCoords coords = c2a.getAtomCoords();
    // coords.getChargeDensity().setInterpolationScheme(interpolationScheme);
    // Vector vec = new Vector();
    // vec.addElement(coords);
    // for ( int i=1 ; i<cubeFiles.length ; i++ ) {
    // Cube2AtomCoords cu = new Cube2AtomCoords(cubeFiles[i]);
    // cu.getAtomCoords();
    // VolumetricData vdata = cu.getChargeDensity();
    // vdata.setInterpolationScheme(interpolationScheme);
    // coords.addChargeDensity(vdata);
    // }
    // }

    private void bootViewer() {
        Object[] objs = fileList.getSelectedValues();
        if (objs == null || objs.length == 0) {
            logger.info("select file");
            return;
        }
        String dir = projectInfo.getProjectDirectory()
                + System.getProperty("file.separator");
        Cube2AtomCoords c2a = new Cube2AtomCoords(dir + objs[0].toString());
        AtomCoords coords = c2a.getAtomCoords();
        Vector vec = new Vector();
        vec.addElement(coords);
        for (int i = 1; i < objs.length; i++) {
            String file = dir + objs[i].toString();
            Cube2AtomCoords cu = new Cube2AtomCoords(file);
            cu.getAtomCoords(); // charge density作成; イマイチ...
            coords.addChargeDensity(cu.getChargeDensity());
        }

        double[][] dcell = coords.getCell()[0].getDouble();
        BravaisLattice blat = BravaisLattice.getBravaisLattice(dcell[0],
                dcell[1], dcell[2]);
        if (blat != null)
            blat.isBravais(false);

        DataManager manager = new DataManager("foo", PhaseConstants.TABLESPEC,
                false);
        manager.parse();
        ACVData acvdata = new ACVData(this, vec,
                projectInfo.getProjectDirectory(), manager.getInputInterface(),
                StringConstants.phase_atom_tag);
        acvdata.setFileName(objs[0].toString());
        acvdata.setBravaisLattice(blat);
        CoordsViewerBooter cvb = new CoordsViewerBooter(acvdata, 0);
        cvb.boot();
    }

    private void readHeaders(String file) {
        String line1 = "";
        String line2 = "";
        BufferedReader reader = null;
        try {
            FileReader freader = new FileReader(file);
            reader = new BufferedReader(freader);
            line1 = reader.readLine();
            line2 = reader.readLine();
        } catch (IOException ioe) {
            logger.error("failed to open file: " + file);
            return;
        } catch (NullPointerException npe) {
            logger.error("corrupted chr file...");
            return;
        } finally {
            try {
                reader.close();
            } catch (IOException ioe) {
                logger.error("failed to close file: " + file);
            }
        }
        label1.setText(line1);
        label2.setText(line2);
    }

    private void chosenFile(String fileName) {

    }

    public void initializeProject() {
    }

    public void save(AtomCoords coords) {
    }

    public void keyTyped(KeyEvent e) {
    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        logger.debug("keycode: " + e.getKeyCode());
        logger.debug("keychar: " + e.getKeyChar());
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            bootViewer();
        }
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
            bootViewer();
        }
    }

}
