/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/02/21, 13:43
!  AUTHOR(S): KOGA, Junichiro
!  File : EkcalUtils.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.ekcal;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.HashMap;

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

import ciss.phase_viewer.common.ExternalProgramExecuter;
import ciss.phase_viewer.inputinterface.InputInterface;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.scripting.ScriptUtils;

/**
 * ekcal操作にあたって便利と思われるメソッド群; uvsorでも使えるかもしれない.
 * 
 * @author
 */
public class EkcalUtils {
    private static Logger logger = Logger.getLogger(EkcalUtils.class.getName());
    public static String BAND = "band";
    public static String DOS = "dos";

    public static String EPSILON = "uvsor-epsilon";
    public static String EKCAL = "ekcal";

    /** static methods only */
    private EkcalUtils() {
    }

    /**
     * 初期化用のスクリプトのパスを取得
     * 
     * @param dir
     *            対象となるディレクトリー
     */
    public static String getScriptPath(String dir, String mode) {
        if (mode.equals(BAND)) {
            return dir + System.getProperty("file.separator") + "band_init.bsh";
        } else if (mode.equals(DOS)) {
            return dir + System.getProperty("file.separator") + "dos_init.bsh";
        } else if (mode.equals(EPSILON)) {
            return dir + System.getProperty("file.separator") + "eps_init.bsh";
        }
        return null;
    }

    /**
     * 初期化用スクリプトの初期化
     */
    public static void initScript(String dir, String projtype) {
        if (projtype.equals(EKCAL)) {
            java.net.URL bsh = EkcalUtils.class
                    .getResource("/ciss/phase_viewer/plugins/projectmanipulator/ekcal/bsh/dos_init.bsh");
            File scriptFile = new File(bsh.getFile());
            String script = dir + System.getProperty("file.separator")
                    + scriptFile.getName();
            try {
                ExternalProgramExecuter.copyBinary(
                        scriptFile.getAbsolutePath(), script);
            } catch (Exception exc) {
                logger.error("failed to copy " + scriptFile.getAbsolutePath()
                        + " to " + script);
            }

            java.net.URL bshband = EkcalUtils.class
                    .getResource("/ciss/phase_viewer/plugins/projectmanipulator/ekcal/bsh/band_init.bsh");
            File scriptFileband = new File(bshband.getFile());
            String scriptband = dir + System.getProperty("file.separator")
                    + scriptFileband.getName();
            try {
                ExternalProgramExecuter.copyBinary(
                        scriptFileband.getAbsolutePath(), scriptband);
            } catch (Exception exc) {
                logger.error("failed to copy "
                        + scriptFileband.getAbsolutePath() + " to "
                        + scriptband);
            }

            new File(script).deleteOnExit();
            new File(scriptband).deleteOnExit();
        } else if (projtype.equals(EPSILON)) {
            java.net.URL bsh = EkcalUtils.class
                    .getResource("/ciss/phase_viewer/plugins/projectmanipulator/uvsorepsilon/bsh/eps_init.bsh");
            File scriptFile = new File(bsh.getFile());
            String script = dir + System.getProperty("file.separator")
                    + scriptFile.getName();
            try {
                ExternalProgramExecuter.copyBinary(
                        scriptFile.getAbsolutePath(), script);
            } catch (Exception exc) {
                logger.error("failed to copy " + scriptFile.getAbsolutePath()
                        + " to " + script);
            }
            new File(script).deleteOnExit();
        }
    }

    /**
     * 初期化スクリプトの実行
     * 
     * @param dir
     *            プロジェクトのディレクトリー
     * @param mode
     *            どのモードか (DOS, BANDなど)
     */
    public static void runInitScript(String dir, String phaseDir,
            InputInterface inputInterface, String mode) {
        String scriptPath = getScriptPath(dir, mode);
        HashMap props = new HashMap();
        props.put("inputInterface", inputInterface);
        props.put("scriptPath", scriptPath);
        props.put("baseDir", dir);
        props.put("phaseDir", phaseDir);
        ScriptUtils.runScript(scriptPath, props);
//        new File(scriptPath).delete();
    }

    /**
     * 親プロジェクトのホスト情報を継承する
     * 
     * @param parentdir
     *            phaseのディレクトリー
     * @param doc
     *            このDocumentにホスト情報を書き込む.
     */
    public static void inheritHostInfo(String parentdir, Document doc) {
        Document orgDoc = ciss.phase_viewer.jdom.XMLUtils
                .getDocumentFromFile(new File(parentdir
                        + System.getProperty("file.separator")
                        + "phase-viewer.xml"));
        if (orgDoc == null)
            return;
        try {
            Element rootElem = orgDoc.getRootElement();
            if (rootElem != null) {
                Element jobcont = rootElem.getChild("jobcontrol");
                if (jobcont != null) {
                    Element targ = jobcont.getChild("targethost");
                    if (targ != null) {
                        Element root = doc.getRootElement();
                        Element jobcontrol = new Element("jobcontrol");
                        root.addContent(jobcontrol);
                        Element targetHost = new Element("targethost");
                        // targetHost.setText(targ.getTextTrim());
                        java.util.List children = targ.cloneContent();
                        for (int i = 0; i < children.size(); i++) {
                            targetHost.addContent((Content) children.get(i));
                        }
                        jobcontrol.addContent(targetHost);
                    }
                }
            }
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    /**
     * file_names.dataを作成
     * 
     * @param projectInfo
     *            プロジェクト情報
     * @param parentdir
     *            親ディレクトリー
     * @return F_INPファイルのファイル名
     */
    public static String initializeFileNamesData(ProjectInfo projectInfo,
            String parent) {
        String projdir = projectInfo.getProjectDirectory();
        String relativeDir = ciss.phase_viewer.common.Utils.getRelativePath(
                projdir, parent);
        if (!parent.endsWith(System.getProperty("file.separator")))
            parent = parent + System.getProperty("file.separator");

        if (!relativeDir.endsWith(System.getProperty("file.separator")))
            relativeDir = relativeDir + System.getProperty("file.separator");

        String parentfdata = parent + "file_names.data";
        String F_INP = "nfinp.data";
        if (!new File(parentfdata).exists()) {
            logger.error("parent directory does not have file_names.data");
            return F_INP;
        }
        String thisfdata = projectInfo.getProjectDirectory()
                + System.getProperty("file.separator") + "file_names.data";
        BufferedReader rd = null;
        PrintWriter wr = null;
        boolean foundCHGT = false;
        boolean foundOCC = false;
        boolean foundPAWcont = false;
        try {
            rd = new BufferedReader(new FileReader(parentfdata));
            wr = new PrintWriter(new BufferedWriter(new FileWriter(thisfdata)));
            String line = "";
            while ((line = rd.readLine()) != null) {
                if (line.equals("/"))
                    continue;
                if (line.trim().startsWith("F_CHGT")) {
                    foundCHGT = true;
                    String[] foo = line.split("=");
                    String fname = "nfchgt.data";
                    if (foo != null && foo.length >= 2) {
                        fname = new File(foo[1].replace('\'', ' ').trim())
                                .getName();
                    }
                    relativeDir = relativeDir.replaceAll("\\\\", "/");
                    line = "F_CHGT = '" + relativeDir + fname + "'";
                }
                if (line.trim().startsWith("F_OCC")) {
                    foundOCC = true;
                    String[] foo = line.split("=");
                    String fname = "occmat.data";
                    if (foo != null && foo.length >= 2) {
                        fname = new File(foo[1].replace('\'', ' ').trim())
                                .getName();
                    }
                    relativeDir = relativeDir.replaceAll("\\\\", "/");
                    line = "F_OCCMAT = '" + relativeDir + fname + "'";
                }
                if (line.trim().startsWith("F_CNTN_BIN_PAW")) {
                    foundPAWcont = true;
                    String[] foo = line.split("=");
                    String fname = "continue_bin_paw.data";
                    if (foo != null && foo.length >= 2) {
                        fname = new File(foo[1].replace('\'', ' ').trim())
                                .getName();
                    }
                    relativeDir = relativeDir.replaceAll("\\\\", "/");
                    line = "F_CNTN_BIN_PAW = '" + relativeDir + fname + "'";
                }
                if (line.trim().startsWith("F_POT")) {
                    String[] foo = line.split("=");
                    String fname = "";
                    String dir = "";
                    if (foo != null && foo.length >= 2) {
                        fname = new File(foo[1].replace('\'', ' ').trim())
                                .getName();
                        dir = new File(foo[1].replace('\'', ' ').trim())
                                .getParent();
                    }
                    String pdir = new File(parent + "/" + dir)
                            .getAbsolutePath();
                    String reldir = ciss.phase_viewer.common.Utils
                            .getRelativePath(projdir, pdir, true);
                    line = foo[0] + " = '" + reldir
                            + System.getProperty("file.separator") + fname
                            + "'";
                }
                if (line.trim().startsWith("F_INP")) {
                    String[] foo = line.split("=");
                    if (foo != null && foo.length >= 2) {
                        String fname = foo[1].replace('\'', ' ').trim();
                        F_INP = new File(fname).getName();
                    }
                }
                wr.println(line);
            }
            if (!foundCHGT) {
                relativeDir = relativeDir.replaceAll("\\\\", "/");
                wr.println("F_CHGT = '" + relativeDir + "nfchgt.data'");
            }
            if (!foundOCC) {
                relativeDir = relativeDir.replaceAll("\\\\", "/");
                wr.println("F_OCCMAT = '" + relativeDir + "occmat.data'");
            }
            if (!foundPAWcont) {
                relativeDir = relativeDir.replaceAll("\\\\", "/");
                wr.println("F_CNTN_BIN_PAW = '" + relativeDir
                        + "continue_bin_paw.data'");
            }
            wr.println("/");
        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            try {
                rd.close();
                wr.close();
            } catch (Exception exc) {
            }
        }
        return F_INP;
    }

    public static boolean isPhaseDir(ProjectInfo projectInfo) {
        if (projectInfo.getProjectType().equals("phase"))
            return true;
        return false;
    }

}
