package kr.gui.util;

import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.text.PlainDocument;
import javax.swing.text.Document;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.BorderFactory;


/**
 * A Restricted field can restrict inserts for various criteria.
 */
public class RestrictedField extends JTextField
{
	private InsertRestrictor restrictor;
	private JComponent label;

	public RestrictedField(String text, int columns)
	{
		super(text, columns);
		init();
	}

	public RestrictedField(String text)
	{
		super(text);
		init();
	}

	public RestrictedField()
	{
		init();
	}

	public RestrictedField(int columns)
	{
		super(columns);
		init();
	}

	protected void init()
	{
	}

	/**
	 * Adds a custom InsertRestrictor to restrict input. InsertRestrictors will be able to intercept
	 * inserts and modify them.
	 */
	public void addInsertRestrictor(InsertRestrictor other)
	{
		if(this.restrictor != null)
			other.chain(this.restrictor);

		this.restrictor = other;
	}

	/**
	 * Sets the maximum length of the field.
	 *
	 * @param maxLength maximum length
	 *
	 * @return this for lazy users
	 */
	public RestrictedField setMaxLength(int maxLength)
	{
		addInsertRestrictor(new MaxLengthRestrictor(maxLength));
		return this;
	}

	public void reset()
	{
	}

	public boolean isSet()
	{
		if ((getText() == null) || (getText().equals("")))
			return false;
		else
			return true;
	}

    protected Document createDefaultModel() {
        return new RestrictorDocument();
    }

    protected class RestrictorDocument extends PlainDocument
	{
		public RestrictorDocument()
		{
		}

        public void insertString(int offs,
                                 String str,
                                 AttributeSet a)
                throws BadLocationException
		{
			if(restrictor != null)
				super.insertString(offs, restrictor.insertString(this, offs, str, a), a);
			else
				super.insertString(offs, str, a);
        }
    }

	/**
	 * Sets the label for this field.  The implementer, should call setLabelFor
	 * on the label if the label is an instance of JLabel.  The label should
	 * have the same parent as this.
	 */
	public void setMyLabel(JComponent label)
	{
		this.label = label;
		if (label instanceof JLabel)
		{
			((JLabel)label).setLabelFor(this);
		}
	}

	/**
	 * Gets the label for this field
	 */
	public JComponent getMyLabel()
	{
		return label;
	}

	public Dimension getPreferredSize()
	{
		Dimension d = super.getPreferredSize();
		Insets i = getInsets();
		d.width += i.left + i.right;
		return d;
	}
}
