/**
 * This JTextField allows for special filtering of what text can be entered.
 * It is specifically used for allowing the user to enter a file name using the 
 * DOS 8.3 format.
 * Spaces may be allowed or disallowed.
 * Valid characters may be specified, alphanumeric is the default.
 * A max file name length and max extension length may be specified.
 * By default only allows 1 "." in the file name.
 *
 * @author  Michael Pell, Solutions Plus, Inc.
 * @author This class was based upon Real Gagnon's (real.gagnon@tactika.com) work, found at
 * http://codeguru.earthweb.com/java/ *
 */


import javax.swing.text.*; 
import java.awt.Toolkit;
import dataccesstool.utilities.Logger;
public class JTextFieldFileNameFilter extends PlainDocument 
{
	public static final String LOWERCASE  = "abcdefghijklmnopqrstuvwxyz._";
	public static final String UPPERCASE  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
	public static final String ALPHA      = LOWERCASE + UPPERCASE;
	public static final String NUMERIC    = "0123456789";
	public static final String ALPHA_NUMERIC = ALPHA + NUMERIC;
	
	private static boolean DEBUG = false;
	
	private int maxFileNameLength = -1;  //-1 means that we're not checking this length
	private int maxExensionLength = -1;  //-1 means that we're not checking this length
	private boolean spacesAllowed = false;
	private String requiredPrefix = null;
	private String requiredSuffix = null;
	private boolean allowExtensionChange = true;
	private boolean multiplePeriodsAllowed = false;  //not yet implemented
	protected String acceptedChars = null;
	private boolean allowPeriods = true;
		
  
	/** Default constructor, sets accepted character to alpha numeric.*/
	public JTextFieldFileNameFilter()
	{
		this(ALPHA_NUMERIC);
	}
	/** Default to alpha numeric chars, specify a maximum file name length and extension length */
	public JTextFieldFileNameFilter(int aMaxFileNameLength, int aMaxExtensionLength) 
	{
	  this(ALPHA_NUMERIC);
	  this.maxFileNameLength = aMaxFileNameLength;
	  this.maxExensionLength = aMaxExtensionLength;
	}
	/** Default to alpha numeric chars, specify a maximum file name length and extension length, and 
	* set allow or disallow spaces.  */
	public JTextFieldFileNameFilter(int aMaxFileNameLength, int aMaxExtensionLength, boolean spacesAllowedArg) 
	{
	  this(aMaxFileNameLength, aMaxExtensionLength);
	  this.spacesAllowed = spacesAllowedArg;
	}
	/** Default to alpha numeric chars, specify a maximum file name length , and 
	* set allow or disallow spaces.  Do not check for an extension.  Do not allow periods.*/
	public JTextFieldFileNameFilter(int aMaxFileNameLength, boolean spacesAllowedArg, boolean allowPeriodArg) 
	{
	  this(ALPHA_NUMERIC);
	  this.maxFileNameLength = aMaxFileNameLength;
	  this.allowExtensionChange = false;
	  this.spacesAllowed = spacesAllowedArg;
	  this.allowPeriods = allowPeriodArg;
	}
/** Default to alpha numeric chars, specify a maximum file name length , and 
* set allow or disallow spaces.  Do not check for an extension.  Do not allow periods.
* Allow or not allow upper case chars.
*/
public JTextFieldFileNameFilter(int aMaxFileNameLength, boolean spacesAllowedArg, boolean allowPeriodArg, boolean allowUpperCase)
{
	this(JTextFieldFileNameFilter.LOWERCASE + JTextFieldFileNameFilter.NUMERIC);
	this.maxFileNameLength = aMaxFileNameLength;
	this.allowExtensionChange = false;
	this.spacesAllowed = spacesAllowedArg;
	this.allowPeriods = allowPeriodArg;
}
	/** Assign your own accepted characters. */
	public JTextFieldFileNameFilter(String acceptedchars) 
	{
	  acceptedChars = acceptedchars;
	}
/** Overrides the superclass.  This is where the rules are implemented for filtering user input.
*/
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException
{
	try
	{
		if (str == null)
		{
			super.insertString(offset, str, attr);
			return;
		}
		if (acceptedChars.equals(UPPERCASE))
			str = str.toUpperCase();
		else
			if (acceptedChars.equals(LOWERCASE))
				str = str.toLowerCase();

			//Ensure user input is a valid character, return if not valid
		for (int i = 0; i < str.length(); i++)
		{
			if (acceptedChars.indexOf(str.valueOf(str.charAt(i))) == -1)
				return;
		}

		//If we get here, then the user input is valid.

		String allText = this.getText(0, this.getLength());
		int indexOfPeriod = allText.indexOf(".");
		if (!allowPeriods && str.equals("."))
		{
			//Periods are not allowed
			Toolkit.getDefaultToolkit().beep();
			return;
		}
		//only allow 1 period
		if (!multiplePeriodsAllowed && str.equals("."))
		{
			for (int i = 0; i < allText.length(); i++)
			{
				if (allText.charAt(i) == '.')
				{
					//more than 1 period was found, so report error and return
					Toolkit.getDefaultToolkit().beep();
					return;
				}
			}
		}
		if (DEBUG)
		{
			Logger.LogTraceStatement("indexOfPeriod is " + indexOfPeriod);
			Logger.LogTraceStatement("string argument is " + str);
			Logger.LogTraceStatement("allText = " + allText);
			Logger.LogTraceStatement("offset argument is = " + offset);
		}


		//Parse out filename and extension

		String filename = "";
		String extension = "";
		if (indexOfPeriod > 0)
			//it coulb be in the first position
			filename = allText.substring(0, indexOfPeriod); //-1
		else
			if (indexOfPeriod == -1)
				//if no period, then all text is a filename
				filename = allText;

			//if the first character is not alpha, then return  
			//if (ALPHA.indexOf(str.valueOf(filename.charAt(0))) == -1)
			//    return;

		if (indexOfPeriod != -1 && indexOfPeriod < allText.length())
			//it could be the last position
			extension = allText.substring(indexOfPeriod + 1, allText.length()); //or if indexOfPeriod ==-1, there is no extension  

		if (DEBUG)
		{
			Logger.LogTraceStatement("Filename = " + filename);
			Logger.LogTraceStatement("Extension = " + extension);
		}

		//now decide if the user is entering a filename or extension

		if (maxFileNameLength != -1 && indexOfPeriod == -1 || offset <= indexOfPeriod) //entering a filename
		{
			if (filename.length() >= maxFileNameLength) //will it be too long? 
			{
				if (indexOfPeriod == -1 && str.equals(".")) // allow this to happen, its the only period  
				{
					super.insertString(offset, str, attr);
					return;
				}
				else
				{
					//We've reached the max filename length,
					//report an error and don't let the user add this character
					Toolkit.getDefaultToolkit().beep();
					return;
				}
			}
			else
			{
				//the entered text (fileName) is valid, so pass on to my super
				super.insertString(offset, str, attr);
				return;
			}
		}
		else
		{
			if (indexOfPeriod != -1 && offset >= indexOfPeriod)
				//entering an extension
			
				{
				if (allowExtensionChange)
				{
					if (extension.length() >= maxExensionLength)
					{
						//We've reached the max extension length,
						//report an error and don't let the user add this character
						Toolkit.getDefaultToolkit().beep();
						return;
					}
				}
				else
				{
					//We're not allowing the extension to be changed
					//report an error and don't let the user add this character
					Toolkit.getDefaultToolkit().beep();
					return;
				}
			}
		}
		super.insertString(offset, str, attr);
	}
	catch (java.lang.StringIndexOutOfBoundsException e)
	{
		return;
	}
}
public void remove(int offs,int len) throws BadLocationException
{


	super.remove(offs,len);
}
}    
