package usda.weru.util.tree;

import de.schlichtherle.truezip.file.TFile;
import java.awt.Cursor;
import static java.awt.Cursor.getPredefinedCursor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import usda.weru.util.ConfigData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; 

/**
 *
 * @author mhaas
 */
public class WepsTreeModel extends DefaultTreeModel implements PropertyChangeListener, FileFilter {

    private static final long serialVersionUID = 1L;

    protected static final Logger LOGGER = LogManager.getLogger(WepsTreeModel.class);
    protected usda.weru.util.tree.WepsTreeComboBox treeCombo;
    
    protected final boolean includeProjectNode;
    protected final boolean includeTemplateNode;
    // These may renmain null if desired
    protected WepsTreeNodeFile templateNode;
    protected WepsTreeNodeFile projectNode;
    
    protected boolean useWaitCursor;
    boolean isNRCSMode;
    protected boolean isLoading;
    Cursor cursorSave;
    


    public WepsTreeModel(WepsTreeComboBox treeCombo, boolean useWaitCursor) {
        this (treeCombo, false, false, useWaitCursor);
    }
    
    public WepsTreeModel(WepsTreeComboBox treeCombo, boolean includeProjectNode, boolean includeTemplateNode, boolean useWaitCursor) {
        super(null);
        this.treeCombo = treeCombo;
        
        this.includeProjectNode = includeProjectNode;
        this.includeTemplateNode = includeTemplateNode;
        
        templateNode = null;
        projectNode = null;

        isNRCSMode = (ConfigData.checkParmValue("CD-defaultrunmode","NRCS")) ? true : false;
        
        if (includeProjectNode) {
            ConfigData.getDefault().addPropertyChangeListener(ConfigData.CurrentProj, this);
        }
        
        setUseWaitCursor(useWaitCursor);
        
        isLoading = false;
        // default val. Shoud re-set this to the current cursor whenactually using.
        cursorSave = getPredefinedCursor(Cursor.DEFAULT_CURSOR);
    }
        

    public usda.weru.util.tree.WepsTreeComboBox getTreeCombo () {
        return treeCombo;
    }
    
    public boolean useWaitCursor() {
        return useWaitCursor;
    }
    
    public void setUseWaitCursor(boolean wait) {
        useWaitCursor = wait;
    }
    
    public boolean getIsLoading () {
        return isLoading;
    }
    
    public void refresh() {
        
    }
    
    protected void build() { 
        setRoot(new DefaultMutableTreeNode());

        if (includeProjectNode) {
            addCurrentProjectNode();
        }
    }
    
    protected void build(boolean projectNode) {
        setRoot(new DefaultMutableTreeNode());
        if(projectNode) {
            addCurrentProjectNode();
        }
    }

    public void addCurrentProjectNode() {
        addCurrentProjectNode (null);
    }
    
    public void addCurrentProjectNode(String name) {

        final String path = ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj);
        if (path != null) {
            projectNode = addFileNode (new TFile(path), (name == null) ? "Current Project": name);
        }
    }

    protected void addTemplateNode(TFile file) {
        addTemplateNode (file, null);
    }
    protected void addTemplateNode(TFile file, String name) {
        templateNode = addFileNode (file, (name == null) ? "Templates" : name);
    }

    protected WepsTreeNodeFile addFileNode(TFile file, String name) {
        
        WepsTreeNodeFile node = new WepsTreeNodeFile(file, this);
        addNode (node, name);
        return node;
    }

    protected void addNode(WepsTreeNode node, String name) {
        node.setDisplayName(name);
        addNode (node);
    }    

    protected void addNode(WepsTreeNode node) {
        ((DefaultMutableTreeNode)getRoot()).add(node);
        this.reload();
    }

    protected void removeNode(WepsTreeNode node) {
        ((DefaultMutableTreeNode)getRoot()).remove(node);
        this.reload();
    }

    public TreePath getPathToProject() {
        return projectNode != null ? new TreePath(getPathToRoot(projectNode)) : null;
    }

    public TreePath getPathToTemplates() {
        return templateNode != null ? new TreePath(getPathToRoot(templateNode)) : null;
    }
    
    public WepsTreeNodeFile getProjectNode() {
        return projectNode;
    }

    public WepsTreeNodeFile getTemplateNode() {
        return templateNode;
    }

    
    protected void updateFileNodes(final WepsTreeNodeFile node) {
        if (node.updateSubtree()) {
                    node.refreshChildren();
                    reload(node);
        }
    }
    
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        synchronized (this) {
            if (null != evt.getPropertyName()) {
                switch (evt.getPropertyName()) {
                    case ConfigData.CurrentProj: {
                        build();
                            // CrLmod nodes have static controllers, so need to 
                            // set the new path manually
                        if (this instanceof WepsTreeModelMan) {
                            if(((WepsTreeModelMan)this).crlmodNode != null) {
                                ((WepsTreeModelMan)this).crlmodNode.setDefaultDest(
                                    new File(ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj)).toPath());
                            }
                        } else if (this instanceof WepsTreeModelSoil) {
                            ((WepsTreeModelSoil)this).csipSoilServiceNode.setDefaultDest(
                                new File(ConfigData.getDefault().getDataParsed(ConfigData.CurrentProj)).toPath());
                        }
                        break;
                    }
                }
            }
        }
    }

    //
    // Override to control desired filtering
    //
    @Override
    public boolean accept(java.io.File file) {
        return true;
    }
  
    
    protected void updateFileNodes() {
        updateFileNode (projectNode);
        updateFileNode (templateNode);
    }
    
    protected void updateFileNode(final WepsTreeNodeFile node) {
        if (node != null) {
            if (node.updateSubtree()) {
                node.refreshChildren();
                reload(node);
            }
        }
    }
    
    public void updateProjectNodes () {
        updateFileNodes (projectNode);
    }
    

    public void updateTemplateNodes () {
        updateFileNodes (templateNode);
    }
}

