/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2005/07/14, 17:01
!  AUTHOR(S): KOGA, Junichiro
!  File : SubProjectCreatorPanel.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.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.net.URL;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
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.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import ciss.phase_viewer.common.Utils;
import ciss.phase_viewer.jdom.MyElement;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.projectbrowser.ProjectManipulator;
import ciss.phase_viewer.projectbrowser.projectdirbrowser.ProjectDirBrowser;
import ciss.phase_viewer.projectbrowser.projectdirbrowser.ProjectDirBrowserNode;

/**
 * 
 * @author KOGA, Junichiro
 */
public class SubProjectCreatorPanel extends JPanel implements
        ProjectStateChanger {
    private Logger logger = Logger.getLogger(SubProjectCreatorPanel.class
            .getName());
    private ProjectDirBrowserNode parentNode;
    private java.util.Vector components = new java.util.Vector();
    private JComboBox cbtype;
    private JTextField name;
    private ProjectDirBrowser dirBrowser;
    private Vector listeners = new Vector();

    /** Creates a new instance of SubProjectCreatorPanel */
    public SubProjectCreatorPanel(ProjectDirBrowserNode parentNode,
            ProjectDirBrowser dirBrowser) {
        this.parentNode = parentNode;
        this.dirBrowser = dirBrowser;
        init();
    }

    private ProjectStateGUI parentGUI;

    public SubProjectCreatorPanel(ProjectDirBrowserNode parentNode,
            ProjectDirBrowser dirBrowser, ProjectStateGUI parentGUI) {
        this.parentNode = parentNode;
        this.dirBrowser = dirBrowser;
        this.parentGUI = parentGUI;
        init();
    }

    private void init() {
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

        p.setBorder(new TitledBorder("sub project info"));
        JPanel pcb = new JPanel();
        pcb.setLayout(new GridLayout(1, 1));
        pcb.setBorder(new TitledBorder("sub project type"));
        cbtype = new JComboBox(getTypeList());
        pcb.add(cbtype);
        p.add(pcb);

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

        components.addElement(cbtype);
        components.addElement(name);

        cbtype.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                name.setText(getDefaultName());
            }
        });

        name.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent ce) {
                File par = new File(parentNode.getProjectInfo()
                        .getProjectDirectory());
                boolean ch = Utils.isCreatable(par, name.getText());
                if (parentGUI != null)
                    parentGUI.getOKButton().setEnabled(ch);
            }
        });

        name.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                if (parentGUI != null && parentGUI.getOKButton().isEnabled())
                    parentGUI.getOKButton().doClick();
            }
        });

        add(p);
        add(new JPanel());
    }

    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        for (int i = 0; i < components.size(); i++) {
            JComponent comp = (JComponent) components.elementAt(i);
            comp.setEnabled(enabled);
        }
    }

    public void manipulateProjectState() {
        createElement();
        // notifyListeners();
    }

    public void setParentNode(ProjectDirBrowserNode parentNode) {
        this.parentNode = parentNode;
    }

    protected void createElement() {
        String sname = name.getText();
        String type = cbtype.getSelectedItem().toString();
        logger.debug("name and type of sub project...: " + sname + " " + type);

        /*
         * Element elem = new Element("subproject"); elem.setAttribute(new
         * Attribute("display","true"));
         * 
         * Element elemname = new Element("name");
         * elemname.setText(MyElement.encode(sname)); elem.addContent(elemname);
         * 
         * Element elemdate = new Element("date");
         * elemdate.setText(MyElement.encode
         * (Calendar.getInstance().getTime().toString()));
         * elem.addContent(elemdate);
         * 
         * Element elemtype = new Element("type");
         * elemtype.setText(MyElement.encode(type)); elem.addContent(elemtype);
         * 
         * Element elemdir = new Element("directory");
         * 
         * String dir =
         * parentNode.getProjectInfo().getProjectDirectory()+System.
         * getProperty("file.separator")+sname;
         * elemdir.setText(MyElement.encode(dir)); elem.addContent(elemdir);
         */
        String dir = parentNode.getProjectInfo().getProjectDirectory()
                + System.getProperty("file.separator") + sname;
        Element elem = createSubProjectElement(dir, sname, type);

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

        ProjectDirBrowserNode nd = new ProjectDirBrowserNode(elem, dirBrowser,
                true);
        nd.addProjectDirBrowserNodeChangeListener(dirBrowser);
        dirBrowser.addObject(parentNode, nd, true);

        ProjectManipulator component = ProjectManipulator
                .createProjectManipulator(nd.getProjectInfo());
        if (component == null) {
            return;
        }
        component.initializeProject(nd);
    }

    /**
     * subprojectのノードを作成する
     * 
     * @param dirBrowser
     *            関連付けられたProjectDirBrowser
     * @param baseDir
     *            ベースとなるディレクトリー
     * @param name
     *            subprojectの名前
     * @param type
     *            subprojectの種類 (phaseとか)
     * @return 上記のノード
     */
    public static Element createSubProjectElement(String baseDir, String name,
            String type) {
        Element elem = new Element("subproject");
        elem.setAttribute(new Attribute("display", "true"));

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

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

        Element elemtype = new Element("type");
        elemtype.setText(MyElement.encode(type));
        elem.addContent(elemtype);

        Element elemdir = new Element("directory");
        elemdir.setText(MyElement.encode(baseDir));
        elem.addContent(elemdir);
        return elem;
    }

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

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

    private java.util.Vector getTypeList() {
        Element elem = getProjSpecElement();
        java.util.List list = elem.getChildren("project");
        java.util.Vector retvec = new java.util.Vector();
        for (int i = 0; i < list.size(); i++) {
            Element pro = (Element) list.get(i);
            String type = MyElement.decode(pro.getChildTextTrim("type"));
            if (type.equals("sub")) {
                retvec.addElement(MyElement.decode(pro.getChildTextTrim("name")));
            }
        }
        return retvec;
    }

    private Element getProjSpecElement() {
        Document doc = null;
        SAXBuilder builder = new SAXBuilder();
        URL projurl = null;
        projurl = SubProjectCreatorPanel.class
                .getResource(ProjectManipulator.PROJECT_MANIPULATOR_XML_PATH);
        try {
            doc = builder.build(projurl);
        } catch (JDOMException jde) {
            logger.error("failed to parse " + projurl);
            logger.error("unrecoverable error.");
        } catch (java.io.IOException ioe) {
            logger.error("failed to parse " + projurl);
            logger.error("unrecoverable error.");
        }

        Element elem = doc.getRootElement();
        if (!elem.getName().equals("root")) {
            logger.error("invalid ProjectSpecification file.");
        }
        return elem;
    }

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

}
