/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/07/14, 13:59
!  AUTHOR(S): KOGA, Junichiro
!  File : NewProjectCreator.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.projectbrowser.projectstatemanipulator;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

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

import ciss.phase_viewer.common.Utils;
import ciss.phase_viewer.jdom.MyElement;
import ciss.phase_viewer.mainpanel.InternalFrameChase;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.projectbrowser.projectdirbrowser.ProjectDirBrowser;
import ciss.phase_viewer.projectbrowser.projectdirbrowser.ProjectDirBrowserNode;
import ciss.phase_viewer.ssh.hosts.HostInfo;
import ciss.phase_viewer.ssh.hosts.HostList;

/**
 * 
 * @author KOGA, Junichiro
 */
public class NewProjectCreator extends InternalFrameChase implements
        ProjectStateChanger, ProjectStateGUI {
    private static Logger logger = Logger.getLogger(NewProjectCreator.class
            .getName());

    /*
     * (non-Javadoc)
     * 
     * @see
     * ciss.phase_viewer.projectbrowser.projectstatemanipulator.ProjectStateGUI
     * #getOKButton()
     */
    public JButton getOKButton() {
        return ok;
    }

    private ProjectDirBrowserNode parentNode;

    private SubProjectCreatorPanel subpanel;
    private JCheckBox subedit;

    private JTextField name;
    private JTextField path;

    private Vector listeners = new Vector();
    private ProjectDirBrowser dirBrowser;

    private File[] files;
    private File parentDir;

    /** Creates a new instance of NewProjectCreator */
    public NewProjectCreator(ProjectDirBrowserNode parentNode,
            ProjectDirBrowser dirBrowser) {
        super("new project", true, true, true, true, new Dimension(500, 300));
        this.parentNode = parentNode;
        this.dirBrowser = dirBrowser;
        init();
    }

    private JButton ok;

    private void init() {
        getContentPane().setLayout(
                new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        JPanel p = new JPanel();
        p.setBorder(new TitledBorder("edit project info"));
        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

        HostInfo info = HostList.getHostList().getHostInfo("localhost");
        String baseDir = info.getProperty("basedir");

        File f = new File(baseDir);
        if (!f.exists()) {
            if (!f.mkdirs()) {
                logger.error("failed to create " + baseDir);
                dispose();
                return;
            }
        }

        name = new JTextField(getDefaultName(), 10);
        JPanel pname = new JPanel();
        pname.add(name);
        pname.setBorder(new TitledBorder("project name"));
        // pname.setLayout(new GridLayout(1,1));

        String defaultDir = parentNode.getProjectInfo().getProjectDirectory();
        path = new JTextField(defaultDir, 30);
        path.setEditable(false);
        files = new File(defaultDir).listFiles();
        parentDir = new File(defaultDir);

        // ChooserButton cb = new ChooserButton(ChooserButton.DIRECTORY, path);
        JPanel ppath = new JPanel();
        // ppath.setLayout(new BoxLayout(ppath,BoxLayout.X_AXIS));
        ppath.add(path);
        // ppath.add(cb);
        ppath.setBorder(new TitledBorder("parent directory"));

        p.add(pname);
        p.add(ppath);
        JPanel ptmp = new JPanel();
        ptmp.setLayout(new BoxLayout(ptmp, BoxLayout.Y_AXIS));
        ptmp.add(p);

        getContentPane().add(ptmp);

        JPanel psub = new JPanel();
        psub.setBorder(new TitledBorder("initial sub project"));
        psub.setLayout(new BoxLayout(psub, BoxLayout.Y_AXIS));

        subedit = new JCheckBox("create initial sub project");
        JPanel psubedit = new JPanel();
        psubedit.setLayout(new BoxLayout(psubedit, BoxLayout.X_AXIS));
        psub.add(subedit);

        subpanel = new SubProjectCreatorPanel(parentNode, dirBrowser, this);
        psub.add(subpanel);
        getContentPane().add(psub);

        subedit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                subpanel.setEnabled(subedit.isSelected());
            }
        });

        // subedit.setSelected(true);

        JPanel pbtn = new JPanel();
        pbtn.setLayout(new GridLayout(1, 2));
        ok = new JButton("ok");
        JButton cancel = new JButton("cancel");
        pbtn.add(ok);
        pbtn.add(cancel);
        cancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });

        ok.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
                manipulateProjectState();
            }
        });

        name.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent ce) {
                boolean ch = Utils.isCreatable(parentDir, name.getText());
                ok.setEnabled(ch);
            }
        });

        name.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                if (ok.isEnabled())
                    ok.doClick();
            }
        });

        getContentPane().add(pbtn);

        subpanel.setEnabled(false);
    }

    public void addProjectStateChangeListener(
            ProjectStateChangeListener listener) {
        listeners.addElement(listener);
    }

    public void manipulateProjectState() {
        // create new dir
        String nam = name.getText();
        if (nam == null || nam.trim().length() == 0) {
            logger.error("enter a valid directory name.");
            return;
        }

        String projdir = path.getText() + System.getProperty("file.separator")
                + nam.trim();
        File f = new File(projdir);

        if (f.exists()) {
            logger.error("directory " + projdir + " exists!");
            return;
        }

        if (!f.mkdirs()) {
            logger.error("failed to create " + projdir);
            dispose();
            return;
        }

        Element element = new Element("project");
        element.setAttribute(new Attribute("display", "true"));
        element.setAttribute(new Attribute("hassub", "true"));
        element.setAttribute(new Attribute("subident", "subproject"));

        Element elemname = new Element("name");
        elemname.setText(MyElement.encode(name.getText()));
        element.addContent(elemname);

        Element elemdate = new Element("date");
        Calendar calendar = Calendar.getInstance();
        elemdate.setText(MyElement.encode(calendar.getTime().toString()));
        element.addContent(elemdate);

        Element elemtype = new Element("type");
        elemtype.setText("chase project");
        element.addContent(elemtype);

        Element elemdir = new Element("directory");
        elemdir.setText(MyElement.encode(path.getText()
                + System.getProperty("file.separator") + name.getText()));
        element.addContent(elemdir);

        ProjectDirBrowserNode nd = new ProjectDirBrowserNode(element,
                dirBrowser, true);
        nd.addProjectDirBrowserNodeChangeListener(dirBrowser);

        // parentNode.add(nd);
        dirBrowser.addObject(nd);

        if (subedit.isSelected()) {
            subpanel.setParentNode(nd);
            subpanel.createElement();
        }

        notifyListeners();
    }

    private void notifyListeners() {
        for (int i = 0; i < listeners.size(); i++) {
            ProjectStateChangeListener listener = (ProjectStateChangeListener) listeners
                    .elementAt(i);
            listener.projectStateChanged(new ProjectStateChangeEvent(this, name
                    .getText()));
        }
    }

    private String getDefaultName() {
        int proj = 0;
        Enumeration enumeration = parentNode.children();
        String defaultName = "project";
        Vector vec = new Vector();
        while (enumeration.hasMoreElements()) {
            ProjectDirBrowserNode node = (ProjectDirBrowserNode) enumeration
                    .nextElement();
            ProjectInfo info = node.getProjectInfo();
            if (info.getInfoType() == ProjectInfo.BASE) {
                String name = info.getProjectName().toLowerCase();
                if (name.startsWith(defaultName)) {
                    vec.addElement(name);
                }
            }
        }
        if (vec.size() == 0) {
            return defaultName;
        }
        return getNonDupliString(defaultName, vec);
    }

    protected static String getNonDupliString(String string, Vector comp) {
        String compstring = string;
        int max = 500;
        int co = 0;
        while (true) {
            boolean foundDupli = false;
            for (int i = 0; i < comp.size(); i++) {
                if (compstring.equals((String) comp.elementAt(i))) {
                    foundDupli = true;
                    compstring = string + String.valueOf(co);
                    co++;
                }
            }
            if (!foundDupli || co >= max) {
                return compstring;
            }
        }
    }

}
