/*
 * SoilChooser.java
 *
 * Created on April 18, 2007, 9:58 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package usda.weru.soil;

import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeSupport;
import de.schlichtherle.io.File;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.apache.log4j.Logger;
import usda.weru.soil.gui.SoilChooser_n;
import usda.weru.util.ConfigData;
import usda.weru.util.LazyLoadingTreeController;
import usda.weru.util.WepsMessage;
import usda.weru.util.WepsMessageDialog;
import usda.weru.util.WepsMessageLog;
import usda.weru.weps.RunFileData;

/**
 *
 * @author Joseph Levin
 */
public class SoilChooser extends SoilChooser_n{
    private static final Logger LOGGER = Logger.getLogger(SoilChooser.class);
    private File c_projectDirectory;
    private SoilTreeModel c_model;
    private PropertyChangeSupport c_changes;
    private Soil c_soil;
    
    /** Creates a new instance of SoilChooser */
    public SoilChooser() {
        init();
    }
    
    public SoilChooser(Frame parent, File projectDirectory, File soilFile, PropertyChangeSupport changes) {
        super(parent);        
        LOGGER.debug("creating soil chooser");
        init();
        c_projectDirectory = projectDirectory;
        //setRootFile(soilFile);
        c_changes = changes;
        if (parent instanceof Soil){
            c_soil = (Soil)parent;
        }        
    }
    
    @Override
    protected void formWindow_closed(java.awt.event.WindowEvent evt) {   
    }
    
    private void init(){
        setModal(true);
        c_model = new InternalSoilTreeModel();
        g_tree.setModel(c_model);
        new LazyLoadingTreeController(g_tree);
        g_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        g_tree.expandPath(c_model.getPathToTemplates());
        g_tree.setRootVisible(false);
        setTitle("Select Soil");        
    }
    
    public void setProjectDirectory(File dir){
        c_projectDirectory = dir;
    }
    
    public void setChanges(PropertyChangeSupport changes){
        c_changes = changes;
    }
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        JFileChooser jfc = new JFileChooser();
        jfc.setMultiSelectionEnabled(false);
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        final SoilChooser sc = new SoilChooser();
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                sc.setVisible(true);
            }
        });
        int result = jfc.showOpenDialog(sc);
        if (result == JFileChooser.APPROVE_OPTION){
            //sc.setRootFile(file);
            sc.setProjectDirectory(new File("."));
        }
        
    }
    
    private boolean isSoil(Object o){
        if (o instanceof TreeNode){
            TreeNode node = (TreeNode) o;
            for (SoilDatabase database : c_model.getDatabases()){
                if (database.isSoil(node)){
                    return true;
                }
            }
        }
        return false;
    }
    
    protected void treeValueChanged(TreeSelectionEvent evt) {
        Object o = evt.getPath().getLastPathComponent();
        g_selectButton.setEnabled(isSoil(o));
    }
    
    protected void treeMouseClicked(java.awt.event.MouseEvent evt) {
        if (evt.getClickCount() == 2){
            loadSelectedNode();
        }
    }
    
    private void loadSelectedNode(){
        TreePath selectedPath = g_tree.getSelectionPath();
        if(selectedPath == null){
            return;
        }
        Object o = selectedPath.getLastPathComponent();
        if (o instanceof TreeNode){
            final TreeNode node = (TreeNode) o;
            for (final SoilDatabase database : c_model.getDatabases()){
                if (database.isSoil(node)){
                    //Thread off the loading of the soil ifc with a progress monitor.
                    final ProgressMonitor progress = new ProgressMonitor(this, "Loading Soil Record", "", 0, 100);
                    progress.setMillisToDecideToPopup(0);
                    progress.setMillisToPopup(0);
                    Thread task = new Thread("Selected Node Loader"){
                        public void run(){
                            setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
                            try{
                                IFC ifc = database.getIfcFromNode(node, progress);
                                if (ifc != null){
                                    //WepsMessageLog log = new WepsMessageLog();
                                    WepsMessageLog log = ifc.getLog();

                                    if (log.getCount(WepsMessage.MessageSeverity.ERROR) == 0){
                                        if (c_soil != null) {
                                            c_soil.ifcptr = ifc;
                                            c_soil.ifcptr.adjustIfc();
                                            c_soil.viewLayers(c_soil.ifcptr.getFileName());
                                            c_soil.setMenuEnable("Save", true);
                                            c_soil.setMenuEnable("Save As", true);
                                            c_soil.setMenuEnable("print", true);
                                        } else {
                                            // sends double errors to IFC file extracted from NASIS
                                            // ifc.sendErrorsToInternalVariable();
                                            ifc.writeNewIfc(c_projectDirectory.getAbsolutePath(), c_changes);
                                            c_changes.firePropertyChange(RunFileData.SoilRockFragments, null, "0.0");
                                            c_changes.firePropertyChange(RunFileData.AverageSlope, null, "-1");
                                        }
                                        //Ask the swing thread to hide the form
                                        SwingUtilities.invokeLater(new Runnable(){
                                            public void run() {
                                                progress.close();
                                                //setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                                                setVisible(false);
                                            }
                                        });
                                    } else{ //We have errors to report
                                        if (!NASIS.getEstimateNullValues() && log.getCount(WepsMessage.MessageSeverity.ERROR) > 0){
                                            WepsMessageDialog.showMessageList(null, "Soil Record", c_projectDirectory.getAbsolutePath(), log.getMessages(WepsMessage.MessageSeverity.ERROR));
                                        } else{
                                            WepsMessageDialog.showMessageList(null, "Soil Record", c_projectDirectory.getAbsolutePath(), log.getMessages(WepsMessage.MessageSeverity.ERROR, WepsMessage.MessageSeverity.WARNING));
                                        }

                                    }
                                }
                            }
                            catch(OrganicSoilException ose){
                                //the soil being loaded
                                String message = ose.getMessage();
                                final JOptionPane pane = new JOptionPane("The selected soil is not supported by the WEPS science model.  The high organic content may cause unexpected results." + (message != null ? "\n" + message + "\n" : "\n")+ "Do you want to use the supplied organic soil substitue?", JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION){
                                

                                    @Override
                                    public int getMaxCharactersPerLineCount() {
                                        return 80;
                                    }

                                };

                                final JDialog dialog = pane.createDialog(SoilChooser.this, "Organic Soil");
                                try{
                                    EventQueue.invokeAndWait(new Runnable(){

                                        @Override
                                        public void run() {
                                            dialog.setVisible(true);
                                            int result = pane.getValue() != null ? Integer.valueOf(pane.getValue().toString()) : JOptionPane.CANCEL_OPTION;
                                            if(result == JOptionPane.YES_OPTION){
                                                //use the organic soil, close soil chooser
                                                c_changes.firePropertyChange(RunFileData.SoilFile, null, ConfigData.getDefault().getDataParsed(ConfigData.SoilOrganicFile));
                                                SoilChooser.this.setVisible(false);

                                            }
                                            else{
                                                //do nothing, the SoilChooser remains open
                                            }
                                        }

                                    });
                                }
                                catch(Exception e){
                                    LOGGER.error("Unexpected error while waiting for the edt to return from the organic soil prompt.", e);
                                }
                            }
                            catch(Exception e){
                                //some error loading the soil record.
                                progress.close();
                                JOptionPane.showMessageDialog(SoilChooser.this, "Unknown error while loading a soil record.", "Loading Error", JOptionPane.ERROR_MESSAGE);
                                

                            }
                            finally{
                                progress.close();
                                setCursor(java.awt.Cursor.getDefaultCursor());
                            }
                            
                        }
                    };
                    task.start();
                    
                    //This database was able to provide the soil,                     
                    break;
                }
            }
        }
    }
    
    protected void cancelButtonActionPerformed(ActionEvent evt) {
        setVisible(false);        
    }
    
    protected void selectButtonActionPerformed(ActionEvent evt) {
        loadSelectedNode();
    }
    
    protected void indexActionPerformed(java.awt.event.ActionEvent evt) {
        //setRootFile(c_rootFile);
    }

    @Override
    public void setVisible(boolean b) {
        if (b){
            LOGGER.debug("showing soil chooser");
        }
        else{
            LOGGER.debug("hiding soil chooser");
        }
        super.setVisible(b);
    }
        
    
    class InternalSoilTreeModel extends SoilTreeModel{
         public InternalSoilTreeModel(){
             super(false);
         }

//        @Override
//        public void refresh() {
//            super.refresh();
//            g_tree.expandPath(getPathToTemplates());
//        }
                           
     }
    
}
