/*
 * Copyright (c) 2006-2008 MiniMe. Code released under The MIT/X Window System
 * License. Full license text can be found in license.txt
 */
package minime.ui;

import java.util.Timer;

import javax.microedition.lcdui.Graphics;

import minime.Font;
import minime.Logger;
import minime.Portability;
import minime.FontManager;
import minime.core.CanSelect;
import minime.core.Component;
import minime.core.Event;
import minime.core.ResourceManager;
import minime.core.Runtime;
import minime.core.DelayTaskImp;
import minime.core.DelayTask;

/**
 * The EditField class is an editable text component , it's similar to
 * high-level TextField.
 * 
 * @author yishu
 * 
 */
public class EditField extends Component implements CanSelect, DelayTaskImp
{
    // The different constraints allow the application to request that the
    // user's input be restricted in a variety of ways. The implementation is
    // required to restrict the user's input as requested by the application.
    // For example, if the application requests the NUMERIC constraint on a
    // TextField, the implementation must allow only numeric characters to be
    // entered.
    public static final int NUMERIC = 0x0;
    public static final int EMAILADDR = 0x1;
    public static final int PHONENUMBER = 0x2;
    public static final int URL = 0x3;
    public static final int PASSWORD = 0x4;
    public static final int CONSTAINTS_COUNT = 5;

    private static final String STAR = "*";

    // Input Types
    // The application can request that the implementation use a particular
    // input type
    public static final int NUMBER = 0x0;
    public static final int LETTER = 0x1;
    public static final int SYMBOL = 0x2;
    public static final int INPUT_TYPES_COUNT = 2;
    private int inputType = NUMBER;

    private static final char[][] letters = { { ' ', '0' }, { '.', ':', '/', '?', '_', '-', '@', '!', ',', '#', '1' },
            { 'a', 'b', 'c', '2' }, { 'd', 'e', 'f', '3' }, { 'g', 'h', 'i', '4' }, { 'j', 'k', 'l', '5' },
            { 'm', 'n', 'o', '6' }, { 'p', 'q', 'r', 's', '7' }, { 't', 'u', 'v', '8' }, { 'w', 'x', 'y', 'z', '9' } };
    private int startOffset;
    private int previousKeyValue = -1;
    private int inputTextLen;
    char currentChar;
    private int cursor;
    int cursorWidth;

    private static final int INTERVAL = 800;
    private Timer timer;
    private boolean timeout = true;

    private int maxSize;
    private int displayedSize;
    private Font font;
    private StringBuffer textBuf;
    private int times = 0;
    private int constraints;
    public int cursorColor = Portability.C_BLACK; // the color of cursor
    private int textColor = Portability.C_BLACK; // the color of text
    private int fillColor = Portability.C_WHITE; // the color for filling

    // Selection member
    private int frameThickness;
    private int frameColor;
    private boolean framed;
    private boolean selected ;
    
    /**
     * Creates an editfield instance from the source editfield, a copy is
     * created and returned.The parameter editField should not be null.
     * 
     * @param editField
     *            the source editfield instance.
     * @throws IllegalArgumentException
     *             if maxSize is zero or less if the insertion would exceed the
     *             current maximum capacity
     * @throws IllegalArgumentException
     *             if the value of the constraints parameter is invalid
     */
    public EditField(EditField editField)
    {
        this((editField.textBuf).toString(), editField.textColor, editField.displayedSize, editField.maxSize,
                editField.constraints, editField.frameThickness, editField.frameColor, editField.fillColor);
    }

    /**
     * Create s a new EditField object with the given text, given text color,
     * given size for edit field displaying, maximum size in characters, and
     * constraints. If the text parameter is null, the TextField is created
     * empty. The maxSize parameter must be greater than zero.The default frame
     * thickness and frame color is zero, and the default filling color is
     * TRANSPARENT.
     * 
     * @param text
     *            the initial contents, or null if the TextField is to be empty
     * @param displayedSize
     *            the size for editfield displaying
     * @param maxSize
     *            the maximum capacity in characters
     * @param constraints
     *            The different constraints allow the application to request
     *            that the user's input be restricted in a variety of ways
     * @return return the EditField object created
     * @throws IllegalArgumentException
     *             if maxSize is zero or less if the insertion would exceed the
     *             current maximum capacity
     * @throws IllegalArgumentException
     *             if the value of the constraints parameter is invalid
     */
    public static EditField createEditField(String text, int textColor, int displayedSize, int maxSize, int constraints)
    {
        return new EditField(text, textColor, displayedSize, maxSize, constraints, 0, 0, Portability.TRANSPARENT);
    }

    /**
     * Create s a new EditField object with the given text, which is drawed from
     * resource file based on txRscId by ResourceManager, and given text color,
     * given size for edit field displaying, maximum size in characters, and
     * constraints. If the text parameter is null, the TextField is created
     * empty. The maxSize parameter must be greater than zero.The default frame
     * thickness and frame color is zero, and the default filling color is
     * TRANSPARENT.If initialization content is empty, set txRscId to
     * ResourceManager.NONE_RESOURCE.
     * 
     * @param txRscId
     *            the initial text index id, or ResourceManager.NONE_RESOURCE if
     *            the TextField is to be empty.
     * @param displayedSize
     *            the size for editfield displaying
     * @param maxSize
     *            the maximum capacity in characters
     * @param constraints
     *            The different constraints allow the application to request
     *            that the user's input be restricted in a variety of ways
     * @return return the EditField object created
     * @throws IllegalArgumentException
     *             if maxSize is zero or less if the insertion would exceed the
     *             current maximum capacity
     * @throws IllegalArgumentException
     *             if the value of the constraints parameter is invalid
     */
    public static EditField createEditField(int txRscId, int textColor, int displayedSize, int maxSize, int constraints)
    {
        return createEditField(txRscId, textColor, displayedSize, maxSize, constraints, 0, 0, Portability.TRANSPARENT);
    }

    /**
     * Create s a new EditField object with the given text to initialize
     * contents,which is drawed from resource file based on txRscId by
     * ResourceManager, the given rectangle, maximum size in characters, and
     * constraints. If the text parameter is null, the TextField is created
     * empty. The maxSize parameter must be greater than zero.If initialization
     * content is empty, set txRscId to ResourceManager.NONE_RESOURCE.
     * 
     * @param txRscId
     *            the initial text index id, or ResourceManager.NONE_RESOURCE if
     *            the TextField is to be empty.
     * @param displayedSize
     *            the size for editfield displaying
     * @param maxSize
     *            the maximum capacity in characters
     * @param constraints
     *            The different constraints allow the application to request
     *            that the user's input be restricted in a variety of ways
     * @param frameThickness
     *            the thickness for editfield frame
     * @param frameColor
     *            the color for editfield frame
     * @param fillColor
     *            the color for filling editfield
     * @return return the EditField object created
     * @throws IllegalArgumentException
     *             if maxSize is zero or less if the insertion would exceed the
     *             current maximum capacity
     * @throws IllegalArgumentException
     *             if the value of the constraints parameter is invalid
     */
    public static EditField createEditField(int txRscId, int textColor, int displayedSize, int maxSize,
            int constraints, int frameThickness, int frameColor, int fillColor)
    {
        return new EditField(ResourceManager.getString(txRscId), textColor, displayedSize, maxSize, constraints,
                frameThickness, frameColor, fillColor);
    }

    /**
     * Create s a new EditField object with the given text, initial contents,
     * the given rectangle, maximum size in characters, and constraints. If the
     * text parameter is null, the TextField is created empty. The maxSize
     * parameter must be greater than zero.
     * 
     * @param text
     *            the initial contents, or null if the TextField is to be empty
     * @param displayedSize
     *            the size for editfield displaying
     * @param maxSize
     *            the maximum capacity in characters
     * @param constraints
     *            NUMERIC, PHONENUMBER, PASSWORD, EMAILADDR, URL.The different
     *            constraints allow the application to request that the user's
     *            input be restricted in a variety of ways.
     * @param frameThickness
     *            the thickness for editfield frame
     * @param frameColor
     *            the color for editfield frame
     * @param fillColor
     *            the color for filling editfield
     * @throws IllegalArgumentException
     *             if maxSize is zero or less if the insertion would exceed the
     *             current maximum capacity
     * @throws IllegalArgumentException
     *             if the value of the constraints parameter is invalid
     */
    public EditField(String text, int textColor, int displayedSize, int maxSize, int constraints, int frameThickness,
            int frameColor, int fillColor) throws IllegalArgumentException
    {
        if (maxSize <= 0)
            throw new IllegalArgumentException();
        if (constraints < NUMERIC || constraints > CONSTAINTS_COUNT)
            throw new IllegalArgumentException();

        if (text != null)
        {
            inputTextLen = text.length();
            if (inputTextLen > maxSize)
                throw new IllegalArgumentException();
            else
                this.textBuf = new StringBuffer(text);
        }
        else
            this.textBuf = new StringBuffer();
        this.textColor = textColor;
        this.frameThickness = frameThickness;
        this.frameColor = frameColor;
        this.fillColor = fillColor;
//        if (frameThickness > 0)
//            framed = true;
//
        this.displayedSize = displayedSize;
        this.maxSize = maxSize;

        this.constraints = constraints;
        switch (constraints)
        {
            case NUMERIC:
            case PHONENUMBER:
            case PASSWORD:
                inputType = NUMBER;
                break;
            case EMAILADDR:
            case URL:
                inputType = LETTER;
                break;
            default:
                break;
        }

        font = FontManager.getFont(FontManager.EDITFIELD_FONT);
        timer = new Timer();
    }

    public void layoutImp()
    {
        // cal. the width of editfield, take the default char as common char
        // width
        int defaultCharWidth = 0;
        cursorWidth = 1;
        switch (inputType)
        { // selecte default char based on input type
            case NUMBER:
                defaultCharWidth = font.getCharWidth('3');
                break;
            case LETTER:
                defaultCharWidth = font.getCharWidth('m');
                break;
            case SYMBOL:
                defaultCharWidth = font.getCharWidth('/');
                break;
            default:
                break;
        }
        setWidth(displayedSize * defaultCharWidth + (cursorWidth + 2)*2);
        this.setHeight(font.getHeight() + 2);
    }

    /*
     * (non-Javadoc)
     * 
     * @see minime.Drawable#renderImpl(javax.microedition.lcdui.Graphics)
     */
    public void renderImpl(Graphics gc)
    {
        // if (hasFocus())
        // LOG.debug("current cursor: " + cursor);
        if (fillColor != Portability.TRANSPARENT)
        {
            gc.setColor(fillColor);
            gc.fillRect(0, 0, getWidth() + 2, getHeight());
        }
        int textBeginX = 5;
        // draw the editField rect.
        if (framed && frameThickness > 0)
        {
            gc.setColor(frameColor);
            int tmpX = 0;
            int tmpY = 0;
            int tmpW = getWidth() + 2;
            int tmpH = getHeight();
            for (int i = 0; i < frameThickness; i++)
            {
                gc.drawRect(tmpX, tmpY, tmpW, tmpH);
                tmpX++;
                tmpY++;
                tmpW-=2;
                tmpH-=2;
            }
            textBeginX = frameThickness + 2;
        }

        int cursorH = font.getHeight();
        int cursorY = (getHeight() - cursorH) / 2;

        if (size() <= 0)
        {
        	// should not be necessary, is disable, should not have focus
            if (isFocused())
            {
                // draw the cursor
                gc.setColor(cursorColor);
                gc.drawLine(textBeginX, cursorY, textBeginX, cursorH + 1);
            }
            return;
        }

        // draw the text
        gc.setColor(textColor);

        // draw the substring of editfield content, the substring begains at
        // startOffset and extends to charCount chars
        String subStr = textBuf.toString().substring(startOffset);
        int charCount = font.countChars(subStr, getWidth() - cursorWidth -5);
        String passwordStarStr = ""; // record star string when input
        // password
        if (constraints == PASSWORD)
        { // if enter password, displays "*"
            int charWidth = font.getStringWidth(STAR);
            int tmpX = textBeginX;
            for (int i = 0; i < charCount; i++)
            {
                font.drawString(gc, tmpX, cursorY, STAR);
                tmpX += charWidth;
                passwordStarStr += STAR;
            }
        }
        else
            font.drawSubString(gc, textBeginX, cursorY, subStr, 0, charCount);

        // draw the cursor when focused
        if (isFocused())
        {
            // draw the cursor
            int cursorX = textBeginX;

            if (cursor > startOffset)
                cursorX += font.getStringWidth(subStr.substring(0, (cursor - startOffset))) - 1;
            if (cursor < size())
            {
                // LOG.debug("draw cursor, cursor: " + cursor);
                // LOG.debug("cursor char: " + textBuf.charAt(cursor));

                // if input type is LETTER, when inputting, cursor is a block
                // and display a block on top of character, or display a
                // line as cursor
                gc.setColor(cursorColor);
                if (timeout)
                { // draw a line
                    if (constraints == PASSWORD && cursor > startOffset)
                        cursorX = (cursor - startOffset) * font.getStringWidth(STAR) + textBeginX - 1;
                    gc.drawLine(cursorX, cursorY, cursorX, cursorH + 1);
                }
                else
                { // draw rectangle
                    gc.fillRect(cursorX, cursorY, font.getCharWidth(textBuf.charAt(cursor)), cursorH + 1);
                    gc.setColor(~cursorColor);
                    font.drawString(gc, cursorX, cursorY, String.valueOf(textBuf.charAt(cursor)));
                }
            }
            else
            { // draw a line at the end of editfield string
                gc.setColor(cursorColor);
                if (constraints == PASSWORD && cursor > startOffset)
                    cursorX = (cursor - startOffset) * font.getStringWidth(STAR) + textBeginX - 1;
                gc.drawLine(cursorX, cursorY, cursorX, cursorH + 1);
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see minime.EventListener#onEvent(minime.Event)
     */
    public boolean onEvent(Event evt)
    {
        // LOG.debug("priEventcursor: " + cursor);
        if (evt.type != Event.KEY_EVENT || !isFocused())
        {
            return false;
        }

        boolean handled = false;
        int keyValue;
        long currTime = System.currentTimeMillis();

        if (evt.paramA == Portability.KEY_NUM0)
        {
            keyValue = 0;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM1)
        {
            keyValue = 1;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM2)
        {
            keyValue = 2;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM3)
        {
            keyValue = 3;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM4)
        {
            keyValue = 4;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM5)
        {
            keyValue = 5;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM6)
        {
            keyValue = 6;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM7)
        {
            keyValue = 7;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM8)
        {
            keyValue = 8;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_NUM9)
        {
            keyValue = 9;
            selectChar(keyValue, currTime);
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_POUND)
        {// press pound key change the input type
            timer.cancel();
            changeInputType();
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_STAR)
        {// call the symbol input type
            handled = true;
        }

        if (handled)
        {
            refresh();
            return true;
        }

        // translate back from game key code to key code
        if (evt.paramA == Portability.KEY_LEFT)
        {
            // cursor go back
            timerCancel();
            if (cursor > 0)
            {
                cursor--;
                // string moves to left by one char if cursor is less than
                // startOffset
                if (cursor < startOffset)
                    startOffset--;
            }
            previousKeyValue = -1;
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_RIGHT)
        {
            // cursor go forward
            timerCancel();

            if (cursor < size())
            {
                cursor++;
                // string moves to right by one char if substring width between
                // startOffset and cursor is greater than displayable width
                while (calCursorWidth() > (getWidth() - cursorWidth - 5))
                    startOffset++;
            }
            previousKeyValue = -1;
            handled = true;
        }
        else if (evt.paramA == Portability.KEY_SOFT_CLEAR)
        {// delete one character when press KEY_SOFT_RIGHT
            timerCancel();

            if (size() > 0)
            {// cursor back by 1 step, if have any letters, delete the letter
                // which be pointed by cursor
                if (cursor > 0)
                {
                    cursor--;
                    deleteChar(cursor);
                    if (startOffset > 0)
                        startOffset--;
                }
                handled = true;
            }
        }

        if (handled)
        {
            refresh();
            return true;
        }
        return false;
    }

    /**
     * when press a key, select a character according to input type, text will
     * append keyValue if input type equals to NUMBER, if input type equals to
     * LETTER, select a letter according to key value, interval of key pressed
     * twice and the times of key pressed
     * 
     * @param keyValue
     *            the keyvalue of key
     * @param currTime
     *            the current time
     */
    private void selectChar(int keyValue, long currTime)
    {
        // if EditField is full, just don't process the key
        if (size() >= maxSize)
            return;

        switch (inputType)
        {
            case NUMBER: // cursor move to the next position and the
                // insert keyValue into stringbuffer
                insertIntAt(keyValue, cursor);
                cursor++;
                break;
            case LETTER:
                char[] l = letters[keyValue];
                timerCancel();

                if (previousKeyValue == -1)
                {
                    // just time, insert the char
                    times = 0;
                    currentChar = l[times];
                    insertCharAt(cursor, currentChar);
                    int inputTextW = font.getStringWidth(textBuf.toString());
                    if (inputTextW > (getWidth() - cursorWidth - 5) && (calCursorWidth() > (getWidth() - cursorWidth - 5) / 2))
                    { // string moves to right by one char if substring width
                        // between startOffset and cursor is greater than
                        // displayable width
                        startOffset++;
                    }
                }
                else if (keyValue != previousKeyValue)
                {
                    // go to next position
                    cursor++;
                    times = 0;
                    currentChar = l[times];
                    insertCharAt(cursor, currentChar);
                    int inputTextW = font.getStringWidth(textBuf.toString());
                    if (inputTextW > getWidth() && (calCursorWidth() > getWidth() / 2))
                    { // string moves to right by one char if substring width
                        // between startOffset and cursor is greater than
                        // displayable width
                        startOffset++;
                    }
                    refresh();
                }
                else
                {
                    // just replace with next char at same position
                    times = (times + 1) % l.length;
                    currentChar = l[times];
                    textBuf.setCharAt(cursor, currentChar);
                    refresh();
                }

                timerReset();
                break;
            case SYMBOL:
                break;
            default:
                break;
        }
        // LOG.debug("keyValue: " + keyValue + " times:" + times);
        previousKeyValue = keyValue;
    }

    // cal. the width of string between startOffset and cursor
    private int calCursorWidth()
    {
        int width = 0;
        if (cursor < size())
        {
            width = font.getCharsWidth(textBuf.toString().toCharArray(), startOffset, (cursor - startOffset) + 1);
        }
        return width;
    }

    /**
     * sets the font
     * 
     * @param font
     *            font for editfieldTitleLabel and editField text
     * @throws NullPointerException
     *             if font is null
     */
    public void setFont(Font font) throws NullPointerException
    {
        if (font == null)
            throw new NullPointerException();

        this.font = font;
        refresh();
    }

    /**
     * sets color for text
     * 
     * @param color
     *            color for text
     */
    public void setTextColor(int textColor)
    {
        this.textColor = textColor;
        refresh();
    }

    /**
     * Sets the contents of the EditField as a string value, replacing the
     * previous contents.If the current content is empty, set txRscId to
     * ResourceManager.NONE_RESOURCE.
     * 
     * @param txRscId
     *            the text index id, or ResourceManager.NONE_RESOURCE if the
     *            TextField is to be empty
     * @throws IllegalArgumentException
     *             if the text would exceed the current maximum capacity
     */
    public void setString(int txRscId) throws IllegalArgumentException
    {
        setString(ResourceManager.getString(txRscId));
    }

    /**
     * Sets the contents of the EditField as a string value, replacing the
     * previous contents.
     * 
     * @param text
     *            the new value of the EditField, or null if the EditField is to
     *            be made empty
     * @throws IllegalArgumentException
     *             if the text would exceed the current maximum capacity
     */
    public void setString(String text) throws IllegalArgumentException
    {
        if (text == null || text.equals(""))
        {
            this.textBuf = new StringBuffer();
            inputTextLen = 0;
            cursor = 0;
            startOffset = 0;
            refresh();
            return;
        }

        if (text.length() <= maxSize)
        {
            this.textBuf = new StringBuffer(text);
            inputTextLen = text.length();
            refresh();
        }
        else
            throw new IllegalArgumentException();
    }

    /**
     * Gets the contents of the EditField as a string value.
     * 
     * @return the current contents
     */
    public String getString()
    {
        if (size() > 0)
            return textBuf.toString();
        else
            return null;
    }

    /**
     * Inserts a string into the contents of the EditField, str should not be
     * null.
     * 
     * @param str
     *            the String to be inserted
     * @param position
     *            the position at which insertion is to occur
     * 
     * @throws IllegalArgumentException
     *             if the insertion would exceed the current maximum capacity
     * @throws NullPointerException
     *             if src is null
     */
    private void insert(String str, int position) throws IllegalArgumentException, NullPointerException
    {
        if (str == null)
        {
            throw new NullPointerException();
        }
        if ((size() + str.length()) > maxSize)
        {
            throw new IllegalArgumentException();
        }
        if (position <= 0)
            textBuf.insert(0, str);
        else if (position >= size())
            // text.insert(size(), str);
            textBuf.append(str);
        else
            textBuf.insert(position, str);
        inputTextLen = textBuf.length();
        refresh();
    }

    /**
     * Inserts the string representation of the first int argument into
     * EditField
     * 
     * @param i
     *            an int
     * @param position
     *            the position at which insertion is to occur
     */
    private void insertIntAt(int i, int position)
    {
        insert(String.valueOf(i), position);
    }

    /**
     * Inserts the string representation of the first char argument into
     * EditField
     * 
     * @param c
     *            a char
     * @param position
     *            the position at which insertion is to occur
     */
    private void insertCharAt(int position, char c)
    {
        insert(String.valueOf(c), position);
    }

    /**
     * Deletes characters from the TextField.
     * 
     * The offset and length parameters must specify a valid range of characters
     * within the contents of the EditField. The offset parameter must be within
     * the range [0..(size())], inclusive. The length parameter must be a
     * non-negative integer such that (offset + length) <= size().
     * 
     * @param offset
     *            the beginning of the region to be deleted
     */
    private void deleteChar(int offset) throws StringIndexOutOfBoundsException
    {
        textBuf.delete(offset, offset + 1);
        inputTextLen = textBuf.length();
    }

    /**
     * Sets the maximum size (number of characters) that can be contained in
     * this TextField. If the current contents of the TextField are larger than
     * maxSize, the contents are truncated to fit.
     * 
     * @param maxSize
     */
    // public void setMaxSize(int maxSize)
    // {
    // this.maxSize = maxSize;
    // if (size() > maxSize)
    // {
    // textBuf.delete(maxSize - 1, inputTextLen - 1);
    // inputTextLen = maxSize;
    // }
    // refresh();
    // }
    /**
     * Gets the number of characters that are currently stored in this
     * EditField.
     * 
     * @return number of characters in the EditField
     */
    public int size()
    {
        return inputTextLen;
    }

    // change the input type
    private void changeInputType()
    {
        if (constraints != NUMERIC && constraints != PHONENUMBER && constraints != PASSWORD)
        {
            inputType++;
            if (inputType >= INPUT_TYPES_COUNT)
                inputType = 0;
        }
    }

    private void refresh()
    {
        Runtime.getInstance().repaint();
    }

    private void timerReset()
    {
        if (timer != null)
            timer.cancel();

        timer = new Timer();
        timer.schedule(new DelayTask(this), INTERVAL);
        timeout = false;
        refresh();
    }

    // cancel timer
    private void timerCancel()
    {
        if (timer != null)
        {
            timer.cancel();
            timer = null;
        }
        timeout = true;
        refresh();
    }

    /**
     * Sets the EditField is framed or not
     * 
     * @param framed boolean
     *            
     */
    public void setFrame(boolean framed)
    {
        this.framed = framed;
    }

    /**
     * Sets the EditField frame thickness and color.
     * 
     * @param frameThickness
     *            the frame thickness
     * @param frameColor
     *            the color for frame
     */
    public void setFrameThicknessAndColor(int frameThickness, int frameColor)
    {
        this.frameThickness = frameThickness;
        this.frameColor = frameColor;
        setNeedLayout();
    }

    public void delayTaskRun()
    {
        cursor++;
        times = 0;
        previousKeyValue = -1;
        timeout = true;
        refresh();
    }

	public boolean isSelected()
	{
		return selected;
	}

	public void renderImplSelected(Graphics gc)
	{
		renderImpl(gc) ;		
	}

	/*
	 * Set selected.   
	 * 
	 * Set the frame on/off, set the selected/non selected image
	 * 
	 * @see minime.core.CanSelect#setSelected(boolean)
	 */
	public void setSelected(boolean select)
	{
		if (select!=selected)
		{
			setFrame(select) ;
			setNeedLayout() ;
		}
		
		selected = select ;
	}
}
