/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/10/10, 18:40
!  AUTHOR(S): KOGA, Junichiro
!  File : PhaseInputImporter.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.beans.PropertyChangeListener;
import java.io.File;
import java.util.HashMap;

import javax.swing.filechooser.FileFilter;

import org.apache.log4j.Logger;

import ciss.phase_viewer.atomcoord.AtomCoords;
import ciss.phase_viewer.atomcoord.Cell;
import ciss.phase_viewer.inputinterface.DataManager;
import ciss.phase_viewer.inputinterface.InputInterface;
import ciss.phase_viewer.inputinterface.InputInterfacePrimitiveEntry;
import ciss.phase_viewer.inputinterface.InputInterfaceUnits;

/**
 * PHASE入力から''structure''ブロックを抜き出してAtomCoordsに.
 * 
 * @author
 */
public class PhaseInputImporter implements Importer {
    private Logger logger = Logger
            .getLogger(PhaseInputImporter.class.getName());

    /** Creates a new instance of PhaseInputImporter */
    public PhaseInputImporter() {
    }

    public boolean isImportable(String fileName) {
        if (new java.io.File(fileName).isDirectory()) {
            return false;
        }
        return true;
    }

    public AtomCoords[] getAtomCoordsFrom(String fileName) {
        AtomCoords coords = new AtomCoords();

        DataManager manager = new DataManager(fileName);
        if (!manager.parse())
            return null;
        InputInterface inputFrom = manager.getInputInterface();
        String coordsys = inputFrom.getInputInterfacePrimitiveEntry(
                "structure.atom_list.coordinate_system").getValue();

        inputFrom.selectBlock("structure.unit_cell");
        InputInterfaceUnits units = inputFrom.getUnits();
        int lenunit = AtomCoords.BOHR;
        String[] uni = units.getUnits();
        String lenu = "bohr";
        if (uni != null) {
            for (int i = 0; i < uni.length; i++) {
                if (uni[i].toLowerCase().equals("angstrom")) {
                    lenunit = AtomCoords.ANGSTROM;
                    lenu = "angstrom";
                } else if (uni[i].toLowerCase().equals("nm")) {
                    lenunit = AtomCoords.NM;
                    lenu = "nm";
                }
            }
        }

        InputInterfacePrimitiveEntry[] cellentries = inputFrom
                .getAllPrimitiveEntries();
        boolean validCell = true;
        double[][] cellVector = null;
        double[] cellabc = null;
        HashMap hashcell = null;
        if (cellentries == null)
            validCell = false;
        else {
            hashcell = new HashMap();
            for (int i = 0; i < cellentries.length; i++) {
                hashcell.put(cellentries[i].getName(),
                        cellentries[i].getValue());
            }
        }
        if (hashcell.get("a_vector") != null
                && hashcell.get("b_vector") != null
                && hashcell.get("c_vector") != null) {
            cellVector = new double[3][3];
            try {
                String[] stravec = hashcell.get("a_vector").toString()
                        .split("\\s+");
                String[] strbvec = hashcell.get("b_vector").toString()
                        .split("\\s+");
                String[] strcvec = hashcell.get("c_vector").toString()
                        .split("\\s+");
                for (int i = 0; i < 3; i++) {
                    cellVector[0][i] = Double.parseDouble(stravec[i]);
                    cellVector[1][i] = Double.parseDouble(strbvec[i]);
                    cellVector[2][i] = Double.parseDouble(strcvec[i]);
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
                cellVector = null;
            } catch (ArrayIndexOutOfBoundsException aobe) {
                aobe.printStackTrace();
                cellVector = null;
            }
        } else if (hashcell.get("a") != null && hashcell.get("b") != null
                && hashcell.get("c") != null && hashcell.get("alpha") != null
                && hashcell.get("beta") != null
                && hashcell.get("gamma") != null) {
            cellabc = new double[6];
            try {
                cellabc[0] = Double.parseDouble(hashcell.get("a").toString());
                cellabc[1] = Double.parseDouble(hashcell.get("b").toString());
                cellabc[2] = Double.parseDouble(hashcell.get("c").toString());
                cellabc[3] = Double.parseDouble(hashcell.get("alpha")
                        .toString());
                cellabc[4] = Double
                        .parseDouble(hashcell.get("beta").toString());
                cellabc[5] = Double.parseDouble(hashcell.get("gamma")
                        .toString());
            } catch (NumberFormatException e) {
                e.printStackTrace();
                cellabc = null;
            }
        }
        if (cellVector == null && cellabc == null) {
            validCell = false;
        } else if (cellVector != null) {
            validCell = true;
            Cell ce = new Cell(cellVector[0], cellVector[1], cellVector[2]);
            coords.setCell(ce);
        } else if (cellabc != null) {
            validCell = true;
            Cell ce = new Cell(cellabc[0], cellabc[1], cellabc[2], cellabc[3],
                    cellabc[4], cellabc[5]);
            coords.setCell(ce);
        }

        boolean iscart = coordsys.equalsIgnoreCase("cartesian");
        coords.isCart(iscart);
        logger.debug("is cart? " + iscart);

        inputFrom.selectBlock("structure.atom_list.atoms");
        InputInterfaceUnits unitAtom = inputFrom.getUnits();
        int lenunitAtom = AtomCoords.BOHR;
        String[] uniAtom = units.getUnits();
        if (uniAtom != null) {
            for (int i = 0; i < uniAtom.length; i++) {
                if (uniAtom[i].toLowerCase().equals("angstrom")) {
                    lenunit = AtomCoords.ANGSTROM;
                    lenu = "angstrom";
                } else if (uniAtom[i].toLowerCase().equals("nm")) {
                    lenunit = AtomCoords.NM;
                    lenu = "nm";
                }
            }
        }
        coords.setUnit(lenunit);

        logger.debug("length unit: " + lenu);

        coords.inputInterface2AtomCoords(inputFrom, "structure.atom_list.atoms");

        coords.convert(AtomCoords.TO_CART, AtomCoords.TO_ANG);

        if (coords.getNumAt() != 0) {
            return new AtomCoords[] { coords };
        } else {
            return null;
        }
    }

    public void setOptions(HashMap options) {
    }

    public void createOptionsPanel(boolean heavy,
            PropertyChangeListener listener, String fileName) {
    }

    public boolean hasOptions() {
        return false;
    }

    public String getType() {
        return "phase input file";
    }

    public FileFilter getFileFilter() {
        return new PhaseInputFileFilter();
    }

}

class PhaseInputFileFilter extends javax.swing.filechooser.FileFilter {

    public boolean accept(File f) {
        return true;
    }

    public String getDescription() {
        return "phase input (default name: nfinp.data)";
    }

}
