/*
 * @(#)TextTools.java    2.3.3   6 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.util;

import java.io.*;
import java.util.*;


/**
 * <p>Class <code>TextTools</code> is a special purpose class for
 * reading and writing data on local disk files.</p>
 *
 * <p>See also:</p>
 * 
 * <ul>
 *   <li><code>TextFileIO</code>
 *       in package <code>edu.neu.ccs.gui</code></li>
 * </ul>
 * 
 * @author  Richard Rasala
 * @version 2.3.3
 */
public class TextTools {

    /** Prevent instantiation. */
    private TextTools() { }
    
    
   /**
     * <p>Reads a text file and returns all of its data as a string.</p>
     * 
     * <p>Assumes that the entire file may be read into memory at once.</p>
     *
     * <p>Throws <code>RuntimeException</code> if an error occurs.</p>
     *
     * @param path the text file path on the local file system
     * @return the text file contents as a string
     */
    public static String readTextFile(String path)
    {
        if (path == null)
            throw new RuntimeException("Null path in readTextFile");
        
        int bufferSize = 8092;
        
        StringBuffer buffer = new StringBuffer(bufferSize);
        char[] data = new char[bufferSize];
        
        // read file
        try {
            // use pattern: open file; read file; close file
            FileReader reader = new FileReader(path);
            
            while(true) {
                int count = reader.read(data);
                
                if (count > 0)
                    buffer.append(data, 0, count);
                else
                    break;
            }
            
            reader.close();
        }
        catch (IOException ex) {
            throw new RuntimeException(ex.getMessage());
        }
        
        return buffer.toString();
    }
    
    
    /**
     * <p>Writes a text file whose contents will be the given data.</p>
     * 
     * <p>Throws <code>RuntimeException</code> if an error occurs.</p>
     *
     * @param path the text file path on the local file system
     * @param data the text file contents as a string
     */
    public static void writeTextFile(String path, String data)
    {
        if (path == null)
            throw new RuntimeException("Null path in writeTextFile");
        
        if (data == null)
            throw new RuntimeException("Null data in writeTextFile");
        
        try {
            // use pattern: open file; write page; close file
            FileWriter writer = new FileWriter(path);
            writer.write(data);
            writer.close();
        }
        catch (IOException ex) {
            throw new RuntimeException(ex.getMessage());
        }
    }
    
    
    /**
     * <p>Copies a text file from one place to another.</p>
     *
     * <p>Assumes that the entire file can be read into memory at once.</p>
     *
     * @param oldPath the source text file path on the local file system
     * @param newPath the target text file path on the local file system
     */
    public static void copyTextFile(String oldPath, String newPath)
    {
        writeTextFile(newPath, readTextFile(oldPath));
    }
    
    
    /**
     * <p>Reads and trims the lines in the given file and returns
     * the trimmed lines that are non-empty into a string array.</p>
     *
     * <p>Throws <code>RuntimeException</code> if an error occurs.</p>
     *
     * <p>Assumes that the entire file can be read into memory at once.</p>
     *
     * @param path the text file path on the local file system
     * @return the array with the non-empty trimmed lines from the text file
     */
    public static String[] readNonEmptyLines(String path) 
    {
        return extractNonEmptyLines(readTextFile(path));
    }
    
    
    /**  
     * <p>Finds and trims the lines in the given data and returns
     * the trimmed lines that are non-empty into a string array.</p>
     *
     * @param data the string data to convert into an array of lines
     * @return the array with the non-empty trimmed lines from the data
     */
    public static String[] extractNonEmptyLines(String data) {
        if ((data == null) || (data.length() == 0))
            return new String[0];
        
        StringTokenizer tokenizer =
            new StringTokenizer(data, "\n");
        
        Vector list = new Vector();
        
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken().trim();
            
             if (token.length() > 0)
                list.add(token);
        }
        
        return (String[]) list.toArray(new String[0]);
    }
    
    
    /**
     * <p>Returns the file names in the filelist text file
     * located in the given directory.</p>
     * 
     * <p>Assumes that filelist is the name of a text file
     * in the same directory as the files listed within it.</p>
     *
     * <p>The filelist text file should contain one name per
     * line.  Blank lines are permitted as separator lines.</p>
     *
     * <p>Appends the file separatory character to the given
     * directory string if necessary.</p>
     * 
     * <p>If an error occurs, returns a zero-length string array
     * rather than throw an exception.</p>
     *
     * @param directory the directory with the files and the file list
     * @param filelist the text file with the list of file names
     * @return the array with the list of file names
     */
    public static String[] readFileNames
        (String directory, String filelist)
    {
        try {
            return readNonEmptyLines(makePath(directory, filelist));
        }
        catch (Exception ex) {
            return new String[0];
        }
    }
    
    
    /**
     * <p>Makes a file path from the directory name and file name
     * adding a path separator character if necessary.</p>
     * 
     * <p>Throws <code>RuntimeException</code> if an error occurs.</p>
     *
     * @param directory the directory string
     * @param filename the file name string
     * @return the path that combines the directory and file name
     */
    public static String makePath
        (String directory, String filename)
    {
        if (directory == null)
            throw new RuntimeException("Null directory in makePath");
        
        if (filename == null)
            throw new RuntimeException("Null filename in makePath");
        
        String insert = "";
        
        int length = directory.length();
        
        if (length > 0)
            if (directory.charAt(length - 1) != File.separatorChar)
                insert = File.separator;
        
        return directory + insert + filename;
    }
    
}
