/*
 * Copyright (C) 2009 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.view.accessibility;

import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * This class represents accessibility events that are sent by the system when
 * something notable happens in the user interface. For example, when a
 * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc.
 * <p>
 * This class represents various semantically different accessibility event
 * types. Each event type has associated a set of related properties. In other
 * words, each event type is characterized via a subset of the properties exposed
 * by this class. For each event type there is a corresponding constant defined
 * in this class. Since some event types are semantically close there are mask
 * constants that group them together. Follows a specification of the event
 * types and their associated properties:
 * <p>
 * <b>VIEW TYPES</b> <br>
 * <p>
 * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View}
 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
 * Type:{@link #TYPE_VIEW_CLICKED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()},
 * {@link #isChecked()},
 * {@link #isEnabled()},
 * {@link #isPassword()},
 * {@link #getItemCount()},
 * {@link #getCurrentItemIndex()}
 * <p>
 * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View}
 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
 * Type:{@link #TYPE_VIEW_LONG_CLICKED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()},
 * {@link #isChecked()},
 * {@link #isEnabled()},
 * {@link #isPassword()},
 * {@link #getItemCount()},
 * {@link #getCurrentItemIndex()}
 * <p>
 * <b>View selected</b> - represents the event of selecting an item usually in
 * the context of an {@link android.widget.AdapterView}. <br>
 * Type: {@link #TYPE_VIEW_SELECTED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()},
 * {@link #isChecked()},
 * {@link #isEnabled()},
 * {@link #isPassword()},
 * {@link #getItemCount()},
 * {@link #getCurrentItemIndex()}
 * <p>
 * <b>View focused</b> - represents the event of focusing a
 * {@link android.view.View}. <br>
 * Type: {@link #TYPE_VIEW_FOCUSED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()},
 * {@link #isChecked()},
 * {@link #isEnabled()},
 * {@link #isPassword()},
 * {@link #getItemCount()},
 * {@link #getCurrentItemIndex()}
 * <p>
 * <b>View text changed</b> - represents the event of changing the text of an
 * {@link android.widget.EditText}. <br>
 * Type: {@link #TYPE_VIEW_TEXT_CHANGED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()},
 * {@link #isChecked()},
 * {@link #isEnabled()},
 * {@link #isPassword()},
 * {@link #getItemCount()},
 * {@link #getCurrentItemIndex()},
 * {@link #getFromIndex()},
 * {@link #getAddedCount()},
 * {@link #getRemovedCount()},
 * {@link #getBeforeText()}
 * <p>
 * <b>TRANSITION TYPES</b> <br>
 * <p>
 * <b>Window state changed</b> - represents the event of opening/closing a
 * {@link android.widget.PopupWindow}, {@link android.view.Menu},
 * {@link android.app.Dialog}, etc. <br>
 * Type: {@link #TYPE_WINDOW_STATE_CHANGED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()}
 * <p>
 * <b>NOTIFICATION TYPES</b> <br>
 * <p>
 * <b>Notification state changed</b> - represents the event showing/hiding
 * {@link android.app.Notification}.
 * Type: {@link #TYPE_NOTIFICATION_STATE_CHANGED} <br>
 * Properties:
 * {@link #getClassName()},
 * {@link #getPackageName()},
 * {@link #getEventTime()},
 * {@link #getText()}
 * {@link #getParcelableData()}
 * <p>
 * <b>Security note</b>
 * <p>
 * Since an event contains the text of its source privacy can be compromised by leaking of
 * sensitive information such as passwords. To address this issue any event fired in response
 * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
 *
 * @see android.view.accessibility.AccessibilityManager
 * @see android.accessibilityservice.AccessibilityService
 */
public final class AccessibilityEvent implements Parcelable {

    /**
     * Invalid selection/focus position.
     *
     * @see #getCurrentItemIndex()
     */
    public static final int INVALID_POSITION = -1;

    /**
     * Maximum length of the text fields.
     *
     * @see #getBeforeText()
     * @see #getText()
     */
    public static final int MAX_TEXT_LENGTH = 500;

    /**
     * Represents the event of clicking on a {@link android.view.View} like
     * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
     */
    public static final int TYPE_VIEW_CLICKED = 0x00000001;

    /**
     * Represents the event of long clicking on a {@link android.view.View} like
     * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
     */
    public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;

    /**
     * Represents the event of selecting an item usually in the context of an
     * {@link android.widget.AdapterView}.
     */
    public static final int TYPE_VIEW_SELECTED = 0x00000004;

    /**
     * Represents the event of focusing a {@link android.view.View}.
     */
    public static final int TYPE_VIEW_FOCUSED = 0x00000008;

    /**
     * Represents the event of changing the text of an {@link android.widget.EditText}.
     */
    public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;

    /**
     * Represents the event of opening/closing a {@link android.widget.PopupWindow},
     * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
     */
    public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;

    /**
     * Represents the event showing/hiding a {@link android.app.Notification}.
     */
    public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;

    /**
     * Mask for {@link AccessibilityEvent} all types.
     *
     * @see #TYPE_VIEW_CLICKED
     * @see #TYPE_VIEW_LONG_CLICKED
     * @see #TYPE_VIEW_SELECTED
     * @see #TYPE_VIEW_FOCUSED
     * @see #TYPE_VIEW_TEXT_CHANGED
     * @see #TYPE_WINDOW_STATE_CHANGED
     * @see #TYPE_NOTIFICATION_STATE_CHANGED
     */
    public static final int TYPES_ALL_MASK = 0xFFFFFFFF;

    private static final int MAX_POOL_SIZE = 2;
    private static final Object mPoolLock = new Object();
    private static AccessibilityEvent sPool;
    private static int sPoolSize;

    private static final int CHECKED = 0x00000001;
    private static final int ENABLED = 0x00000002;
    private static final int PASSWORD = 0x00000004;
    private static final int FULL_SCREEN = 0x00000080;

    private AccessibilityEvent mNext;

    private int mEventType;
    private int mBooleanProperties;
    private int mCurrentItemIndex;
    private int mItemCount;
    private int mFromIndex;
    private int mAddedCount;
    private int mRemovedCount;

    private long mEventTime;

    private CharSequence mClassName;
    private CharSequence mPackageName;
    private CharSequence mContentDescription;
    private CharSequence mBeforeText;

    private Parcelable mParcelableData;

    private final List<CharSequence> mText = new ArrayList<CharSequence>();

    private boolean mIsInPool;

    /*
     * Hide constructor from clients.
     */
    private AccessibilityEvent() {
        mCurrentItemIndex = INVALID_POSITION;
    }

    /**
     * Gets if the source is checked.
     *
     * @return True if the view is checked, false otherwise.
     */
    public boolean isChecked() {
        return getBooleanProperty(CHECKED);
    }

    /**
     * Sets if the source is checked.
     *
     * @param isChecked True if the view is checked, false otherwise.
     */
    public void setChecked(boolean isChecked) {
        setBooleanProperty(CHECKED, isChecked);
    }

    /**
     * Gets if the source is enabled.
     *
     * @return True if the view is enabled, false otherwise.
     */
    public boolean isEnabled() {
        return getBooleanProperty(ENABLED);
    }

    /**
     * Sets if the source is enabled.
     *
     * @param isEnabled True if the view is enabled, false otherwise.
     */
    public void setEnabled(boolean isEnabled) {
        setBooleanProperty(ENABLED, isEnabled);
    }

    /**
     * Gets if the source is a password field.
     *
     * @return True if the view is a password field, false otherwise.
     */
    public boolean isPassword() {
        return getBooleanProperty(PASSWORD);
    }

    /**
     * Sets if the source is a password field.
     *
     * @param isPassword True if the view is a password field, false otherwise.
     */
    public void setPassword(boolean isPassword) {
        setBooleanProperty(PASSWORD, isPassword);
    }

    /**
     * Sets if the source is taking the entire screen.
     *
     * @param isFullScreen True if the source is full screen, false otherwise.
     */
    public void setFullScreen(boolean isFullScreen) {
        setBooleanProperty(FULL_SCREEN, isFullScreen);
    }

    /**
     * Gets if the source is taking the entire screen.
     *
     * @return True if the source is full screen, false otherwise.
     */
    public boolean isFullScreen() {
        return getBooleanProperty(FULL_SCREEN);
    }

    /**
     * Gets the event type.
     *
     * @return The event type.
     */
    public int getEventType() {
        return mEventType;
    }

    /**
     * Sets the event type.
     *
     * @param eventType The event type.
     */
    public void setEventType(int eventType) {
        mEventType = eventType;
    }

    /**
     * Gets the number of items that can be visited.
     *
     * @return The number of items.
     */
    public int getItemCount() {
        return mItemCount;
    }

    /**
     * Sets the number of items that can be visited.
     *
     * @param itemCount The number of items.
     */
    public void setItemCount(int itemCount) {
        mItemCount = itemCount;
    }

    /**
     * Gets the index of the source in the list of items the can be visited.
     *
     * @return The current item index.
     */
    public int getCurrentItemIndex() {
        return mCurrentItemIndex;
    }

    /**
     * Sets the index of the source in the list of items that can be visited.
     *
     * @param currentItemIndex The current item index.
     */
    public void setCurrentItemIndex(int currentItemIndex) {
        mCurrentItemIndex = currentItemIndex;
    }

    /**
     * Gets the index of the first character of the changed sequence.
     *
     * @return The index of the first character.
     */
    public int getFromIndex() {
        return mFromIndex;
    }

    /**
     * Sets the index of the first character of the changed sequence.
     *
     * @param fromIndex The index of the first character.
     */
    public void setFromIndex(int fromIndex) {
        mFromIndex = fromIndex;
    }

    /**
     * Gets the number of added characters.
     *
     * @return The number of added characters.
     */
    public int getAddedCount() {
        return mAddedCount;
    }

    /**
     * Sets the number of added characters.
     *
     * @param addedCount The number of added characters.
     */
    public void setAddedCount(int addedCount) {
        mAddedCount = addedCount;
    }

    /**
     * Gets the number of removed characters.
     *
     * @return The number of removed characters.
     */
    public int getRemovedCount() {
        return mRemovedCount;
    }

    /**
     * Sets the number of removed characters.
     *
     * @param removedCount The number of removed characters.
     */
    public void setRemovedCount(int removedCount) {
        mRemovedCount = removedCount;
    }

    /**
     * Gets the time in which this event was sent.
     *
     * @return The event time.
     */
    public long getEventTime() {
        return mEventTime;
    }

    /**
     * Sets the time in which this event was sent.
     *
     * @param eventTime The event time.
     */
    public void setEventTime(long eventTime) {
        mEventTime = eventTime;
    }

    /**
     * Gets the class name of the source.
     *
     * @return The class name.
     */
    public CharSequence getClassName() {
        return mClassName;
    }

    /**
     * Sets the class name of the source.
     *
     * @param className The lass name.
     */
    public void setClassName(CharSequence className) {
        mClassName = className;
    }

    /**
     * Gets the package name of the source.
     *
     * @return The package name.
     */
    public CharSequence getPackageName() {
        return mPackageName;
    }

    /**
     * Sets the package name of the source.
     *
     * @param packageName The package name.
     */
    public void setPackageName(CharSequence packageName) {
        mPackageName = packageName;
    }

    /**
     * Gets the text of the event. The index in the list represents the priority
     * of the text. Specifically, the lower the index the higher the priority.
     *
     * @return The text.
     */
    public List<CharSequence> getText() {
        return mText;
    }

    /**
     * Sets the text before a change.
     *
     * @return The text before the change.
     */
    public CharSequence getBeforeText() {
        return mBeforeText;
    }

    /**
     * Sets the text before a change.
     *
     * @param beforeText The text before the change.
     */
    public void setBeforeText(CharSequence beforeText) {
        mBeforeText = beforeText;
    }

    /**
     * Gets the description of the source.
     *
     * @return The description.
     */
    public CharSequence getContentDescription() {
        return mContentDescription;
    }

    /**
     * Sets the description of the source.
     *
     * @param contentDescription The description.
     */
    public void setContentDescription(CharSequence contentDescription) {
        mContentDescription = contentDescription;
    }

    /**
     * Gets the {@link Parcelable} data.
     *
     * @return The parcelable data.
     */
    public Parcelable getParcelableData() {
        return mParcelableData;
    }

    /**
     * Sets the {@link Parcelable} data of the event.
     *
     * @param parcelableData The parcelable data.
     */
    public void setParcelableData(Parcelable parcelableData) {
        mParcelableData = parcelableData;
    }

    /**
     * Returns a cached instance if such is available or a new one is
     * instantiated with type property set.
     *
     * @param eventType The event type.
     * @return An instance.
     */
    public static AccessibilityEvent obtain(int eventType) {
        AccessibilityEvent event = AccessibilityEvent.obtain();
        event.setEventType(eventType);
        return event;
    }

    /**
     * Returns a cached instance if such is available or a new one is
     * instantiated.
     *
     * @return An instance.
     */
    public static AccessibilityEvent obtain() {
        synchronized (mPoolLock) {
            if (sPool != null) {
                AccessibilityEvent event = sPool;
                sPool = sPool.mNext;
                sPoolSize--;
                event.mNext = null;
                event.mIsInPool = false;
                return event;
            }
            return new AccessibilityEvent();
        }
    }

    /**
     * Return an instance back to be reused.
     * <p>
     * <b>Note: You must not touch the object after calling this function.</b>
     */
    public void recycle() {
        if (mIsInPool) {
            return;
        }

        clear();
        synchronized (mPoolLock) {
            if (sPoolSize <= MAX_POOL_SIZE) {
                mNext = sPool;
                sPool = this;
                mIsInPool = true;
                sPoolSize++;
            }
        }
    }

    /**
     * Clears the state of this instance.
     */
    private void clear() {
        mEventType = 0;
        mBooleanProperties = 0;
        mCurrentItemIndex = INVALID_POSITION;
        mItemCount = 0;
        mFromIndex = 0;
        mAddedCount = 0;
        mRemovedCount = 0;
        mEventTime = 0;
        mClassName = null;
        mPackageName = null;
        mContentDescription = null;
        mBeforeText = null;
        mParcelableData = null;
        mText.clear();
    }

    /**
     * Gets the value of a boolean property.
     *
     * @param property The property.
     * @return The value.
     */
    private boolean getBooleanProperty(int property) {
        return (mBooleanProperties & property) == property;
    }

    /**
     * Sets a boolean property.
     *
     * @param property The property.
     * @param value The value.
     */
    private void setBooleanProperty(int property, boolean value) {
        if (value) {
            mBooleanProperties |= property;
        } else {
            mBooleanProperties &= ~property;
        }
    }

    /**
     * Creates a new instance from a {@link Parcel}.
     *
     * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
     */
    public void initFromParcel(Parcel parcel) {
        mEventType = parcel.readInt();
        mBooleanProperties = parcel.readInt();
        mCurrentItemIndex = parcel.readInt();
        mItemCount = parcel.readInt();
        mFromIndex = parcel.readInt();
        mAddedCount = parcel.readInt();
        mRemovedCount = parcel.readInt();
        mEventTime = parcel.readLong();
        mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
        mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
        mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
        mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
        mParcelableData = parcel.readParcelable(null);
        parcel.readList(mText, null);
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mEventType);
        parcel.writeInt(mBooleanProperties);
        parcel.writeInt(mCurrentItemIndex);
        parcel.writeInt(mItemCount);
        parcel.writeInt(mFromIndex);
        parcel.writeInt(mAddedCount);
        parcel.writeInt(mRemovedCount);
        parcel.writeLong(mEventTime);
        TextUtils.writeToParcel(mClassName, parcel, 0);
        TextUtils.writeToParcel(mPackageName, parcel, 0);
        TextUtils.writeToParcel(mContentDescription, parcel, 0);
        TextUtils.writeToParcel(mBeforeText, parcel, 0);
        parcel.writeParcelable(mParcelableData, flags);
        parcel.writeList(mText);
    }

    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(super.toString());
        builder.append("; EventType: " + mEventType);
        builder.append("; EventTime: " + mEventTime);
        builder.append("; ClassName: " + mClassName);
        builder.append("; PackageName: " + mPackageName);
        builder.append("; Text: " + mText);
        builder.append("; ContentDescription: " + mContentDescription);
        builder.append("; ItemCount: " + mItemCount);
        builder.append("; CurrentItemIndex: " + mCurrentItemIndex);
        builder.append("; IsEnabled: " + isEnabled());
        builder.append("; IsPassword: " + isPassword());
        builder.append("; IsChecked: " + isChecked());
        builder.append("; IsFullScreen: " + isFullScreen());
        builder.append("; BeforeText: " + mBeforeText);
        builder.append("; FromIndex: " + mFromIndex);
        builder.append("; AddedCount: " + mAddedCount);
        builder.append("; RemovedCount: " + mRemovedCount);
        builder.append("; ParcelableData: " + mParcelableData);
        return builder.toString();
    }

    /**
     * @see Parcelable.Creator
     */
    public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
            new Parcelable.Creator<AccessibilityEvent>() {
        public AccessibilityEvent createFromParcel(Parcel parcel) {
            AccessibilityEvent event = AccessibilityEvent.obtain();
            event.initFromParcel(parcel);
            return event;
        }

        public AccessibilityEvent[] newArray(int size) {
            return new AccessibilityEvent[size];
        }
    };
}
