/**
 * @(#)TextFileIO.java  2.5.0  2 September 2006
 *
 * Copyright 2006
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.gui;

import edu.neu.ccs.filter.*;
import edu.neu.ccs.util.*;

import javax.swing.*;
import java.io.*;

/**
 * <p>Class <code>TextFileIO</code> contains methods
 * to read an entire text file into a string and
 * to save a string as the content of a text file.</p>
 * 
 * <p>The basic methods use file dialogs.  The most
 * complex methods assume a File object has been
 * defined and associated with a text file and then
 * work with that object.</p>
 * 
 * <p>An instance retains information about the
 * extension, file filter, and most recent directory
 * visited by its file chooser internal object.</p>
 * 
 * <p>See also:</p>
 * 
 * <ul>
 *   <li><code>FileUtilities</code>
 *       in package <code>edu.neu.ccs.util</code></li>
 *   <li><code>FileExtensionFilter</code>
 *       in package <code>edu.neu.ccs.util</code></li>
 *   <li><code>TextTools</code>
 *       in package <code>edu.neu.ccs.util</code></li>
 * </ul>
 * 
 * @author Richard Rasala
 * @version 2.5.0
 */
public class TextFileIO {
    /**
     * The file extension to filter files.
     * 
     * Do not include the period character.
     */
    protected String extension = null;
    
    
    /** The file filter for file I/O. */
    protected FileExtensionFilter textFileFilter = null;
    
    
    /** Initialization for home directory as directory ".". */
    protected File home = new File(".");
    
    
    /** The file chooser used for file I/O by this object. */
    protected JFileChooser filechooser = new JFileChooser();
    
    
    /**
     * <p>The constructor that uses no file extension and therefore
     * may read or save any text file using file dialogs.</p>
     */
    public TextFileIO() {
        this(null);
    }
    
    
    /**
     * <p>The constructor that can read or save text files
     * that may be filtered using the optional file extension
     * to filter the files shown in the file dialogs.</p>
     * 
     * <p>Uses no file extension and no file filter if the
     * given extension is <code>null</code>.</p>
     * 
     * <p>The extension, if supplied, should not contain a
     * period.</p>
     * 
     * @param extension the optional file extension
     */
    public TextFileIO(String extension) {
        this.extension = extension;
        
        if (extension != null) {
            textFileFilter = new FileExtensionFilter(extension);
            filechooser.setFileFilter(textFileFilter);
        }
        
        filechooser.setCurrentDirectory(home);
    }
    
    
    /**
     * <p>Opens a file dialog to get the file name of a text file
     * and then reads all data into a String that is returned.<p>
     *
     * <p>Displays error dialogs.</p>
     * 
     * <p>Returns <code>null</code> if an errors occur.</p>
     *
     * @return the file content as a String or <code>null</code>
     */
    public String readDataFromFile()
    {
        return readDataFromFile(true);
    }
    
    /**
     * <p>Opens a file dialog to get the file name of a text file
     * and then reads all data into a String that is returned.<p>
     *
     * <p>Displays error dialogs if the last parameter is
     * set to true.</p>
     * 
     * <p>Returns <code>null</code> if an errors occur.</p>
     *
     * @return the file content as a String or <code>null</code>
     */
    public String readDataFromFile(boolean displayErrorDialogs)
    {
        int result = filechooser.showOpenDialog(null);
        
        if (result == JFileChooser.CANCEL_OPTION)
            return null;
        
        if (result == JFileChooser.ERROR_OPTION) {
            if (displayErrorDialogs) {
                GeneralDialog.showOKDialog
                    ("File Open Dialog Error", "File Read Error");
            }
            
            return null;
        }
        
        File source = filechooser.getSelectedFile();
        
        filechooser.setCurrentDirectory(source);
        
        return readDataFromFile(source, displayErrorDialogs);
    }
    
    
    /**
     * <p>Reads the text data from the given source text file
     * and returns that data in a String.<p>
     *
     * <p>Displays error dialogs if the last parameter is
     * set to true.</p>
     * 
     * <p>Returns <code>null</code> if an errors occur.</p>
     *
     * @param source the data source
     * @param displayErrorDialogs if true display error dialogs
     *
     * @return the file content as a String or <code>null</code>
     */
    public String readDataFromFile
        (File source, boolean displayErrorDialogs)
    {
        String data = null;
        
        if (source == null) {
             if (displayErrorDialogs) {
                String message =
                    "Error in reading file\n"
                    + "Null source File object\n";
                
                GeneralDialog.showOKDialog
                    (message, "File Read Error");
            }
            
           return null;
        }
        
        try {
            data = FileUtilities.readFile(source);
        }
        catch (Throwable ex) {
            if (displayErrorDialogs) {
                String message =
                    "Error in reading file\n"
                    + source.getName() + "\n\n"
                    + ex.getMessage() + "\n";
                
                GeneralDialog.showOKDialog
                    (message, "File Read Error");
            }
            
            return null;
        }
        
        return data;
    }
    
    
    /**
     * <p>Opens a file dialog to get the file name of a file
     * and then saves the given text data to the file.<p>
     *
     * <p>Displays error dialogs.</p>
     * 
     * <p>Does no save if any errors occur.</p>
     * 
     * @param data the data to save
     * @return true if the operation succeeds
     */
    public boolean saveDataToFile(String data) {
        return saveDataToFile(data, true);
    }
    
    
    /**
     * <p>Opens a file dialog to get the file name of a file
     * and then saves the given text data to the file.<p>
     *
     * <p>Displays error dialogs if the last parameter is
     * set to true.</p>
     * 
     * <p>Does no save if any errors occur.</p>
     *
     * @param data the data to save
     * @param displayErrorDialogs if true display error dialogs
     * @return true if the operation succeeds
     */
    public boolean saveDataToFile
        (String data, boolean displayErrorDialogs)
    {
        int result = filechooser.showSaveDialog(null);
        
        if (result == JFileChooser.CANCEL_OPTION)
            return false;
        
        if (result == JFileChooser.ERROR_OPTION) {
            GeneralDialog.showOKDialog
                ("File Save Dialog Error", "File Save Error");
            
            return false;
        }
        
        File target = filechooser.getSelectedFile();
        String path = target.getPath();
        
        if (textFileFilter != null) {
            if (! textFileFilter.accept(target)) {
                path += "." + extension;
                target = new File(path);
            }
        }
        
        filechooser.setCurrentDirectory(target);
        
        return saveDataToFile(target, data, displayErrorDialogs);
    }
    
    
    /**
     * <p>Saves the given text data to the file.<p>
     *
     * <p>Displays error dialogs if the last parameter is
     * set to true.</p>
     * 
     * <p>Does no save if any errors occur.</p>
     *
     * @param target the target file
     * @param data the data to save
     * @param displayErrorDialogs if true display error dialogs
     * @return true if the operation succeeds
     */
    public boolean saveDataToFile
        (File target, String data, boolean displayErrorDialogs)
    {
        if (target == null) {
             if (displayErrorDialogs) {
                String message =
                    "Error in writing file\n"
                    + "Null target File\n";
                
                GeneralDialog.showOKDialog
                    (message, "File Save Error");
            }
            
           return false;
        }
        
        try {
            FileUtilities.writeFile(target, data, true);
        }
        catch (Exception ex) {
            if (displayErrorDialogs) {
                String message =
                    "Error in writing file\n"
                    + target.getName() + "\n\n"
                    + ex.getMessage() + "\n";
                
                GeneralDialog.showOKDialog
                    (message, "File Save Error");
            }
            
            return false;
        }
        
        return true;
    }
    
}

