/*
 * 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.text;

/**
 * Abstract class for filtering login-related text (user names and passwords)
 * 
 */
public abstract class LoginFilter implements InputFilter {
    private boolean mAppendInvalid;  // whether to append or ignore invalid characters
    /**
     * Base constructor for LoginFilter
     * @param appendInvalid whether or not to append invalid characters.
     */
    LoginFilter(boolean appendInvalid) {
        mAppendInvalid = appendInvalid;
    }
    
    /**
     * Default constructor for LoginFilter doesn't append invalid characters.
     */
    LoginFilter() {
        mAppendInvalid = false;
    }
    
    /**
     * This method is called when the buffer is going to replace the
     * range <code>dstart &hellip; dend</code> of <code>dest</code>
     * with the new text from the range <code>start &hellip; end</code>
     * of <code>source</code>.  Returns the CharSequence that we want
     * placed there instead, including an empty string
     * if appropriate, or <code>null</code> to accept the original
     * replacement.  Be careful to not to reject 0-length replacements,
     * as this is what happens when you delete text.
     */
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {
        onStart();
        
        // Scan through beginning characters in dest, calling onInvalidCharacter() 
        // for each invalid character.
        for (int i = 0; i < dstart; i++) {
            char c = dest.charAt(i);
            if (!isAllowed(c)) onInvalidCharacter(c);
        }

        // Scan through changed characters rejecting disallowed chars
        SpannableStringBuilder modification = null;
        int modoff = 0;

        for (int i = start; i < end; i++) {
            char c = source.charAt(i);
            if (isAllowed(c)) {
                // Character allowed.
                modoff++;
            } else {
                if (mAppendInvalid) {
                    modoff++;
                } else {
                    if (modification == null) {
                        modification = new SpannableStringBuilder(source, start, end);
                        modoff = i - start;
                    }

                    modification.delete(modoff, modoff + 1);
                }

                onInvalidCharacter(c);
            }
        }
        
        // Scan through remaining characters in dest, calling onInvalidCharacter() 
        // for each invalid character.
        for (int i = dend; i < dest.length(); i++) {
            char c = dest.charAt(i);
            if (!isAllowed(c)) onInvalidCharacter(c);
        }
        
        onStop();

        // Either returns null if we made no changes,
        // or what we wanted to change it to if there were changes.
        return modification;
    }
    
    /**
     * Called when we start processing filter.
     */
    public void onStart() {
        
    }
    
    /**
     * Called whenever we encounter an invalid character.
     * @param c the invalid character
     */
    public void onInvalidCharacter(char c) {
        
    }
    
    /**
     * Called when we're done processing filter
     */
    public void onStop() {
        
    }
    
    /**
     * Returns whether or not we allow character c. 
     * Subclasses must override this method.
     */
    public abstract boolean isAllowed(char c);

    /**
     * This filter rejects characters in the user name that are not compatible with GMail 
     * account creation. It prevents the user from entering user names with characters other than 
     * [a-zA-Z0-9.]. 
     * 
     */
    public static class UsernameFilterGMail extends LoginFilter {
        
        public UsernameFilterGMail() {
            super(false);
        }
        
        public UsernameFilterGMail(boolean appendInvalid) {
            super(appendInvalid);
        }
        
        @Override
        public boolean isAllowed(char c) {
            // Allow [a-zA-Z0-9@.]
            if ('0' <= c && c <= '9')
                return true;
            if ('a' <= c && c <= 'z')
                return true;
            if ('A' <= c && c <= 'Z')
                return true;
            if ('.' == c)
                return true;
            return false;
        }
    }

    /**
     * This filter rejects characters in the user name that are not compatible with Google login.
     * It is slightly less restrictive than the above filter in that it allows [a-zA-Z0-9._-+]. 
     * 
     */
    public static class UsernameFilterGeneric extends LoginFilter {
        private static final String mAllowed = "@_-+."; // Additional characters
        
        public UsernameFilterGeneric() {
            super(false);
        }
        
        public UsernameFilterGeneric(boolean appendInvalid) {
            super(appendInvalid);
        }
        
        @Override
        public boolean isAllowed(char c) {
            // Allow [a-zA-Z0-9@.]
            if ('0' <= c && c <= '9')
                return true;
            if ('a' <= c && c <= 'z')
                return true;
            if ('A' <= c && c <= 'Z')
                return true;
            if (mAllowed.indexOf(c) != -1)
                return true;
            return false;
        }
    }

    /**
     * This filter is compatible with GMail passwords which restricts characters to 
     * the Latin-1 (ISO8859-1) char set.
     * 
     */
    public static class PasswordFilterGMail extends LoginFilter {
        
        public PasswordFilterGMail() {
            super(false);
        }
        
        public PasswordFilterGMail(boolean appendInvalid) {
            super(appendInvalid);
        }
        
        // We should reject anything not in the Latin-1 (ISO8859-1) charset
        @Override
        public boolean isAllowed(char c) {
            if (32 <= c && c <= 127)
                return true; // standard charset
            // if (128 <= c && c <= 159) return true;  // nonstandard (Windows(TM)(R)) charset
            if (160 <= c && c <= 255)
                return true; // extended charset
            return false;
        }
    }
}
