package org.jcon.df.edit.control;

import org.jcon.param.Param;
import org.jcon.util.DataLib;
import org.jcon.util.Hub;
import org.jcon.util.msg.Message;
import java.awt.Color;
import java.awt.Component;
import java.awt.TextField;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;

import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * A Control representing a TextField.
 * Note - Can easily add more custom edits since have
 * columnDef. JTextField still has too many bugs to use as
 * of 4/17/98.
 *
 * @author Jack Harich
 */
public class TextFieldControl extends Control
    implements TextListener, DocumentListener, FocusListener {

//---------- Private Fields ------------------------------
private TextField     textField = new TextField();
//private JTextField     textField = new JTextField();
private boolean       isEditable;
private String        proppertyAutoUpperCase; // null if not set in parex

//---------- Initialization ------------------------------
public TextFieldControl(int columns) {
    this();
    textField.setColumns(columns);
}
public TextFieldControl() {
    // Do nothing
}
//---------- Abstract Implementation ---------------------
public Component getComponent() {
    return (Component)textField;
}
//---------- Superclass Overrides ------------------------
public void init() { // Called after above
    textField.addTextListener(this);
    //textField.getDocument().addDocumentListener(this);
    textField.addFocusListener(this);

    if (myParam.hasProperty("Text")) {
        textField.setText(myParam.getString("Text"));
    }
    if (myParam.hasProperty("Columns")) {
        textField.setColumns(myParam.getInt("Columns"));
    }
    if (myParam.isTrueDefaultFalse("Password")) {
        textField.setEchoChar('*');
    }
    // null, "true" or "false"
    proppertyAutoUpperCase = myParam.getString("UpperCase");
    
    textField.setEditable(myParam.isTrueDefaultTrue("Editable"));
}
public void setEditable(boolean editable) {
    isEditable = editable;
    textField.setEditable(isEditable);
    refreshBackgroundColor();
}
public void setValue(Object value) {
    if (value == null) value = "";
    //print(".setValue() ------ before " + value);
    textField.setText(value.toString());
    //print(".setValue() ------ after " + value);
}
// Note trim. Perhaps we should only right trim. ***
public Object getValue() {
    return textField.getText().trim();
}
//---------- TextListener Implementation -----------------
public void textValueChanged(TextEvent evt) {
    checkIllegalCharacters();
    checkAutoUpperCase();
    refreshBackgroundColor();
}
//---------- DocumentListener Implementation -------------
public void changedUpdate(DocumentEvent evt) {
    checkIllegalCharacters();
    checkAutoUpperCase();
    refreshBackgroundColor();
}
public void insertUpdate(DocumentEvent evt) {
}
public void removeUpdate(DocumentEvent evt) {
}
//---------- FocusListener Implementation ----------------
public void focusGained(FocusEvent evt) {
    // Show status bar text if any
    if (columnDef == null) return;
    String text = columnDef.getDescription();
    if (text == null) text = "";
    Message message = new Message("SetStatusBarText");
    message.set("Text", text);
    Hub.getGlobalRouter().fire(message);
}
public void focusLost(FocusEvent evt) {
    if (columnDef == null) return;

    if (columnDef.getType().equals("Date")) {
        // Automatically add "19" or "00" if /YY
        String text = textField.getText().trim();
        if (text.length() < 6) return;

        int lastSlash = text.lastIndexOf("/");
        //print(" lastSlash = " + lastSlash);
        if (lastSlash < 0) return;

        String yy = text.substring(lastSlash + 1);
        if (yy.length() > 2) return;
        //print(" yy = " + yy);
        if (! DataLib.isInt(yy)) return;

        int year = Integer.parseInt(yy);
        String century = (year < 50 ? "20" : "19");

        String prefix = text.substring(0, lastSlash);
        String newText = prefix + "/" + century + yy;

        textField.setText(newText);
    }
}
//---------- Properties ----------------------------------

//---------- Private Methods -----------------------------
// ColumnDef overrides "UpperCase is: false" in parex
private void checkAutoUpperCase() {
    // Set autoUpperCase
    boolean autoUpperCase = false;
    
    if (columnDef != null) {
        autoUpperCase = columnDef.isUpperCase();
    } else if (proppertyAutoUpperCase != null) {
        autoUpperCase = (proppertyAutoUpperCase.equals("true") ? true : false);
    }
    // Change text if necessary
    String text = textField.getText().trim();
    if (autoUpperCase == true && ! text.equals(text.toUpperCase())) {
        // Must save and restore caret position for usability
        int caretPosition = textField.getCaretPosition();
        textField.setText(text.toUpperCase());
        textField.setCaretPosition(caretPosition);
    }
}
private void checkIllegalCharacters() {
    String text = textField.getText().trim();
    //----- Remove all single quotes since they cause
    //      errors in SQL statements
    if (text.indexOf("'") > -1) {
        text = DataLib.removeCharacter(text, '\'');
        // Must save and restore caret position for usability
        int caretPosition = textField.getCaretPosition();
        textField.setText(text);
        textField.setCaretPosition(caretPosition - 1); // -1 since char removed
    }
}
/**
 * Show white for normal, yellow for empty and required,
 * lightGray for not editable.
 */
private void refreshBackgroundColor() {
    Color color;
    boolean isEmpty = (textField.getText().trim().equals(""));
    //print(" isEmpty = " + isEmpty);
    if (! isEditable) {
        color = Color.lightGray;
    } else if (columnDef.isRequired() && isEmpty) {
        color = Color.yellow;
    } else {
        color = Color.white;
    }
    if (textField.getBackground() == null) return;

    if (! textField.getBackground().equals(color)) {
        textField.setBackground(color);
    }
}
//--- Std
private static void print(String text) {
    System.out.println("TextFieldControl" + text);
}

} // End class
