/*
 * IfcSoilDatabase.java
 *
 * Created on April 19, 2007, 2:34 PM
 *
 */
package usda.weru.soil;

import de.schlichtherle.truezip.file.TFile;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.ProgressMonitor;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import usda.weru.util.AbstractLazyLoadingTreeNode;

/**
 *
 * @author Joseph Levin
 */
public class IfcSoilDatabase implements SoilDatabase {

    private static final String[] IGNORE = {"svn", "cvs", ".cvs", ".svn"};

    /**
     *
     */
    protected TFile c_file;

    /**
     *
     */
    protected String c_name;

    /**
     *
     */
    protected DefaultMutableTreeNode c_rootNode;

    /** Creates a new instance of IfcSoilDatabase
     * @param file
     */
    public IfcSoilDatabase(TFile file) {
        c_file = file;
    }

    /**
     *
     * @param file
     * @param name
     */
    public IfcSoilDatabase(TFile file, String name) {
        this(file);
        c_name = name;
    }

    @Override
    public MutableTreeNode[] createNodes() {
        if (c_rootNode == null) {
            if (c_file.isDirectory()) {
                //Create Directory node
                c_rootNode = new FolderNode(c_file, c_name);
            } else if (c_file.getName().toLowerCase().endsWith(".ifc")) {
                c_rootNode = new IfcNode(c_file);
            }
        }

        return new MutableTreeNode[]{c_rootNode};

    }

    /**
     *
     * @param node
     * @return
     */
    @Override
    public boolean isSoil(TreeNode node) {
        if (node != null && node instanceof IfcNode) {
            IfcNode n = (IfcNode) node;
            return c_rootNode.equals(node) || c_rootNode.isNodeDescendant(n);
        }
        return false;
    }

    /**
     *
     * @param node
     * @param progress
     * @return
     */
    @Override
    public IFC getIfcFromNode(TreeNode node, ProgressMonitor progress) {
        progress.setMinimum(0);
        progress.setMaximum(10);
        progress.setProgress(0);

        if (isSoil(node)) {
            progress.setProgress(2);
            IfcNode ifcNode = (IfcNode) node;
            IFC ifc = new IFC();
            progress.setProgress(5);
            progress.setNote(ifcNode.getFile().getName());
            ifc.readIfc(ifcNode.getFile());
            ifc.sendErrorsToInternalVariable();
            progress.setProgress(10);

            return ifc;
        }
        return null;
    }

    /**
     *
     */
    @Override
    public void dispose() {

    }

    class FolderNode extends AbstractLazyLoadingTreeNode {

        private static final long serialVersionUID = 1L;

        private final TFile c_file;

        public FolderNode(TFile file) {
            c_file = file;
            setUserObject(file.getName());
            setAllowsChildren(true);
        }

        public FolderNode(TFile file, String displayName) {
            c_file = file;
            if (displayName != null) {
                setUserObject(displayName);
            } else {
                setUserObject(file.getPath());
            }
            setAllowsChildren(true);
        }

        @Override
        public boolean isLeaf() {
            return false;
        }

        @Override
        protected MutableTreeNode[] createChildren() {
            List<MutableTreeNode> temp = new LinkedList<MutableTreeNode>();
            java.io.File[] fileList = c_file.listFiles();

            Files:
            for (java.io.File file : fileList) {
                if (file.isDirectory()) {
                    //Ignore
                    for (String ignore : IGNORE) {
                        if (file.getName().equalsIgnoreCase(ignore)) {
                            continue Files;
                        }
                    }
                    //Create Directory node
                    temp.add(new FolderNode(new TFile(file)));
                } else if (file.getName().toLowerCase().endsWith(".ifc")) {
                    //create soil node
                    temp.add(new IfcNode(new TFile(file)));
                }
            }
            Collections.sort(temp, new NodeComparator());
            MutableTreeNode[] nodes = new MutableTreeNode[0];
            return temp.toArray(nodes);
        }

    }

    static class NodeComparator implements Comparator<MutableTreeNode> {

        @Override
        public int compare(MutableTreeNode o1, MutableTreeNode o2) {
            boolean isDir1 = o1 instanceof FolderNode;
            boolean isDir2 = o2 instanceof FolderNode;

            if (isDir1 && !isDir2) {
                return -1;
            } else if (!isDir1 && isDir2) {
                return 1;
            } else {
                //Sort by name
                return o1.toString().compareTo(o2.toString());
            }
        }

    }

    static class IfcNode extends DefaultMutableTreeNode {

        private static final long serialVersionUID = 1L;

        private final TFile c_file;

        public IfcNode(TFile file) {
            c_file = file;
            setUserObject(file.getName());
        }

        public TFile getFile() {
            return c_file;
        }
    }

}
