/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.widget;

import android.content.Context;
import android.view.KeyEvent;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.method.DialerKeyListener;
import android.text.method.KeyListener;
import android.text.method.TextKeyListener;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.View;
import android.graphics.Rect;



public class DialerFilter extends RelativeLayout
{
    public DialerFilter(Context context) {
        super(context);
    }

    public DialerFilter(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        // Setup the filter view
        mInputFilters = new InputFilter[] { new InputFilter.AllCaps() };

        mHint = (EditText) findViewById(com.android.internal.R.id.hint);
        if (mHint == null) {
            throw new IllegalStateException("DialerFilter must have a child EditText named hint");
        }
        mHint.setFilters(mInputFilters);

        mLetters = mHint;
        mLetters.setKeyListener(TextKeyListener.getInstance());
        mLetters.setMovementMethod(null);
        mLetters.setFocusable(false);

        // Setup the digits view
        mPrimary = (EditText) findViewById(com.android.internal.R.id.primary);
        if (mPrimary == null) {
            throw new IllegalStateException("DialerFilter must have a child EditText named primary");
        }
        mPrimary.setFilters(mInputFilters);

        mDigits = mPrimary;
        mDigits.setKeyListener(DialerKeyListener.getInstance());
        mDigits.setMovementMethod(null);
        mDigits.setFocusable(false);

        // Look for an icon
        mIcon = (ImageView) findViewById(com.android.internal.R.id.icon);

        // Setup focus & highlight for this view
        setFocusable(true);

        // XXX Force the mode to QWERTY for now, since 12-key isn't supported
        mIsQwerty = true;
        setMode(DIGITS_AND_LETTERS);
    }

    /**
     * Only show the icon view when focused, if there is one.
     */
    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);

        if (mIcon != null) {
            mIcon.setVisibility(focused ? View.VISIBLE : View.GONE);
        }
    }


    public boolean isQwertyKeyboard() {
        return mIsQwerty;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean handled = false;

        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_DPAD_LEFT:
            case KeyEvent.KEYCODE_DPAD_RIGHT:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_DPAD_CENTER:
                break;

            case KeyEvent.KEYCODE_DEL:
                switch (mMode) {
                    case DIGITS_AND_LETTERS:
                        handled = mDigits.onKeyDown(keyCode, event);
                        handled &= mLetters.onKeyDown(keyCode, event);
                        break;

                    case DIGITS_AND_LETTERS_NO_DIGITS:
                        handled = mLetters.onKeyDown(keyCode, event);
                        if (mLetters.getText().length() == mDigits.getText().length()) {
                            setMode(DIGITS_AND_LETTERS);
                        }
                        break;

                    case DIGITS_AND_LETTERS_NO_LETTERS:
                        if (mDigits.getText().length() == mLetters.getText().length()) {
                            mLetters.onKeyDown(keyCode, event);
                            setMode(DIGITS_AND_LETTERS);
                        }
                        handled = mDigits.onKeyDown(keyCode, event);
                        break;

                    case DIGITS_ONLY:
                        handled = mDigits.onKeyDown(keyCode, event);
                        break;

                    case LETTERS_ONLY:
                        handled = mLetters.onKeyDown(keyCode, event);
                        break;
                }
                break;

            default:
                //mIsQwerty = msg.getKeyIsQwertyKeyboard();

                switch (mMode) {
                    case DIGITS_AND_LETTERS:
                        handled = mLetters.onKeyDown(keyCode, event);

                        // pass this throw so the shift state is correct (for example,
                        // on a standard QWERTY keyboard, * and 8 are on the same key)
                        if (KeyEvent.isModifierKey(keyCode)) {
                            mDigits.onKeyDown(keyCode, event);
                            handled = true;
                            break;
                        }

                        // Only check to see if the digit is valid if the key is a printing key
                        // in the TextKeyListener. This prevents us from hiding the digits
                        // line when keys like UP and DOWN are hit.
                        // XXX note that KEYCODE_TAB is special-cased here for 
                        // devices that share tab and 0 on a single key.
                        boolean isPrint = event.isPrintingKey();
                        if (isPrint || keyCode == KeyEvent.KEYCODE_SPACE
                                || keyCode == KeyEvent.KEYCODE_TAB) {
                            char c = event.getMatch(DialerKeyListener.CHARACTERS);
                            if (c != 0) {
                                handled &= mDigits.onKeyDown(keyCode, event);
                            } else {
                                setMode(DIGITS_AND_LETTERS_NO_DIGITS);
                            }
                        }
                        break;

                    case DIGITS_AND_LETTERS_NO_LETTERS:
                    case DIGITS_ONLY:
                        handled = mDigits.onKeyDown(keyCode, event);
                        break;

                    case DIGITS_AND_LETTERS_NO_DIGITS:
                    case LETTERS_ONLY:
                        handled = mLetters.onKeyDown(keyCode, event);
                        break;
                }
        }

        if (!handled) {
            return super.onKeyDown(keyCode, event);
        } else {
            return true;
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        boolean a = mLetters.onKeyUp(keyCode, event);
        boolean b = mDigits.onKeyUp(keyCode, event);
        return a || b;
    }

    public int getMode() {
        return mMode;
    }

    /**
     * Change the mode of the widget.
     *
     * @param newMode The mode to switch to.
     */
    public void setMode(int newMode) {
        switch (newMode) {
            case DIGITS_AND_LETTERS:
                makeDigitsPrimary();
                mLetters.setVisibility(View.VISIBLE);
                mDigits.setVisibility(View.VISIBLE);
                break;

            case DIGITS_ONLY:
                makeDigitsPrimary();
                mLetters.setVisibility(View.GONE);
                mDigits.setVisibility(View.VISIBLE);
                break;

            case LETTERS_ONLY:
                makeLettersPrimary();
                mLetters.setVisibility(View.VISIBLE);
                mDigits.setVisibility(View.GONE);
                break;

            case DIGITS_AND_LETTERS_NO_LETTERS:
                makeDigitsPrimary();
                mLetters.setVisibility(View.INVISIBLE);
                mDigits.setVisibility(View.VISIBLE);
                break;

            case DIGITS_AND_LETTERS_NO_DIGITS:
                makeLettersPrimary();
                mLetters.setVisibility(View.VISIBLE);
                mDigits.setVisibility(View.INVISIBLE);
                break;

        }
        int oldMode = mMode;
        mMode = newMode;
        onModeChange(oldMode, newMode);
    }

    private void makeLettersPrimary() {
        if (mPrimary == mDigits) {
            swapPrimaryAndHint(true);
        }
    }

    private void makeDigitsPrimary() {
        if (mPrimary == mLetters) {
            swapPrimaryAndHint(false);
        }
    }

    private void swapPrimaryAndHint(boolean makeLettersPrimary) {
        Editable lettersText = mLetters.getText();
        Editable digitsText = mDigits.getText();
        KeyListener lettersInput = mLetters.getKeyListener();
        KeyListener digitsInput = mDigits.getKeyListener();

        if (makeLettersPrimary) {
            mLetters = mPrimary;
            mDigits = mHint;
        } else {
            mLetters = mHint;
            mDigits = mPrimary;
        }

        mLetters.setKeyListener(lettersInput);
        mLetters.setText(lettersText);
        lettersText = mLetters.getText();
        Selection.setSelection(lettersText, lettersText.length());

        mDigits.setKeyListener(digitsInput);
        mDigits.setText(digitsText);
        digitsText = mDigits.getText();
        Selection.setSelection(digitsText, digitsText.length());

        // Reset the filters
        mPrimary.setFilters(mInputFilters);
        mHint.setFilters(mInputFilters);
    }


    public CharSequence getLetters() {
        if (mLetters.getVisibility() == View.VISIBLE) {
            return mLetters.getText();
        } else {
            return "";
        }
    }

    public CharSequence getDigits() {
        if (mDigits.getVisibility() == View.VISIBLE) {
            return mDigits.getText();
        } else {
            return "";
        }
    }

    public CharSequence getFilterText() {
        if (mMode != DIGITS_ONLY) {
            return getLetters();
        } else {
            return getDigits();
        }
    }

    public void append(String text) {
        switch (mMode) {
            case DIGITS_AND_LETTERS:
                mDigits.getText().append(text);
                mLetters.getText().append(text);
                break;

            case DIGITS_AND_LETTERS_NO_LETTERS:
            case DIGITS_ONLY:
                mDigits.getText().append(text);
                break;

            case DIGITS_AND_LETTERS_NO_DIGITS:
            case LETTERS_ONLY:
                mLetters.getText().append(text);
                break;
        }
    }

    /**
     * Clears both the digits and the filter text.
     */
    public void clearText() {
        Editable text;

        text = mLetters.getText();
        text.clear();

        text = mDigits.getText();
        text.clear();

        // Reset the mode based on the hardware type
        if (mIsQwerty) {
            setMode(DIGITS_AND_LETTERS);
        } else {
            setMode(DIGITS_ONLY);
        }
    }

    public void setLettersWatcher(TextWatcher watcher) {
        CharSequence text = mLetters.getText();
        Spannable span = (Spannable)text;
        span.setSpan(watcher, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    }

    public void setDigitsWatcher(TextWatcher watcher) {
        CharSequence text = mDigits.getText();
        Spannable span = (Spannable)text;
        span.setSpan(watcher, 0, text.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
    }

    public void setFilterWatcher(TextWatcher watcher) {
        if (mMode != DIGITS_ONLY) {
            setLettersWatcher(watcher);
        } else {
            setDigitsWatcher(watcher);
        }
    }

    public void removeFilterWatcher(TextWatcher watcher) {
        Spannable text;
        if (mMode != DIGITS_ONLY) {
            text = mLetters.getText();
        } else {
            text = mDigits.getText();
        }
        text.removeSpan(watcher);
    }

    /**
     * Called right after the mode changes to give subclasses the option to
     * restyle, etc.
     */
    protected void onModeChange(int oldMode, int newMode) {
    }

    /** This mode has both lines */
    public static final int DIGITS_AND_LETTERS = 1;
    /** This mode is when after starting in {@link #DIGITS_AND_LETTERS} mode the filter
     *  has removed all possibility of the digits matching, leaving only the letters line */
    public static final int DIGITS_AND_LETTERS_NO_DIGITS = 2;
    /** This mode is when after starting in {@link #DIGITS_AND_LETTERS} mode the filter
     *  has removed all possibility of the letters matching, leaving only the digits line */
    public static final int DIGITS_AND_LETTERS_NO_LETTERS = 3;
    /** This mode has only the digits line */
    public static final int DIGITS_ONLY = 4;
    /** This mode has only the letters line */
    public static final int LETTERS_ONLY = 5;

    EditText mLetters;
    EditText mDigits;
    EditText mPrimary;
    EditText mHint;
    InputFilter mInputFilters[];
    ImageView mIcon;
    int mMode;
    private boolean mIsQwerty;
}
