package org.jcon.io;

import org.jcon.ui.WindowMgr;
import org.jcon.util.msg.Message;
import org.jcon.util.msg.MessageListener;
import java.awt.FileDialog;
import java.util.Vector;

/**
 * A reusable open file dialog that supports the ability
 * to select a particular file type via a FileValidator.
 * Fires a Message if a valid file is selected.
 * Fires no event if user cancels.
 *
 * @author Jack Harich
 */
public class OpenFileDialog implements MessageListener {

//---------- Private Fields ------------------------------
private String title;
private String fileFilter = "*.*"; // Default
private String openMessageName;
private FileValidator  validator = new FileValidator();
private Vector         listeners = new Vector();

//---------- MessageListener Implementation --------------
public void processMessage(Message evt) {
    if (evt.getName().equals(openMessageName)) {
        openDialog();
    }
}
public String[] loadMessageInterests() {
    return new String[] {openMessageName};
}
//---------- Properties ----------------------------------
//----- title
public void setTitle(String title) {
    this.title = title;
}
public String getTitle() {
    return title;
}
//----- fileFilter
public void setFileFilter(String fileFilter) {
    this.fileFilter = fileFilter;
}
public String getFileFilter() {
    return fileFilter;
}
//----- openMessageName
public void setOpenMessageName(String openMessageName) {
    this.openMessageName = openMessageName;
}
public String getOpenMessageName() {
    return openMessageName;
}
//----- validatorType
/**
 * The validator type may be "File", "Class" or constants
 * in FileValidator. For example "class" will cause the
 * dialog to demand a file extension of "class", case
 * insensitive.
 */
public void setValidatorType(String validatorType) {
    validator.setFileType(validatorType);
}
public String getValidatorType() {
    return (validator == null ? null : validator.getFileType());
}
//---------- Events --------------------------------------
/**
 * Events fired are:
 *  "FileOpened" with property "FullName" containing
 *      full path selected.
 */
public void addMessageListener(MessageListener listener) {
    listeners.addElement(listener);
}
public void removeMessageListener(MessageListener listener) {
    listeners.removeElement(listener);
}
//---------- Private Methods -----------------------------
private void openDialog() {
    FileDialog dialog = new FileDialog(WindowMgr.getLastActiveFrame(), "abc");
    dialog.setTitle(title); // No effect
    dialog.setMode(FileDialog.LOAD);
    dialog.setFile(fileFilter);

    boolean working = true;
    while (working) {

        dialog.setVisible(true);
        // The above line blocks

        if (dialog.getFile() == null) {
            break; // User cancelled
        } else {
            String dirName = dialog.getDirectory();
            String fileName = dialog.getFile();
            boolean success = validator.validate(dirName, fileName);
            if (success) {
                fireMessageEvent(dirName, fileName);
                working = false;
            }
        }
    }
    dialog.setVisible(false);
    dialog.dispose();
}
private void fireMessageEvent(String dirName, String fileName) {
    // Create event
    String name = dirName + fileName;
    if (validator != null) name = validator.getMessageName();
    Message message = new Message("FileOpened");
    message.set("FullName", name);
    // Send event
    message.send(listeners, this);
}
//--- Std
private static void print(String text) {
    System.out.println(text);
}

} // End class
