/*
 * Copyright (C) 2011 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;

import android.annotation.NonNull;
import android.annotation.XmlRes;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.util.SparseArray;

import com.android.internal.util.XmlUtils;

/**
 * Represents an icon that can be used as a mouse pointer.
 * <p>
 * Pointer icons can be provided either by the system using system types,
 * or by applications using bitmaps or application resources.
 * </p>
 */
public final class PointerIcon implements Parcelable {
    private static final String TAG = "PointerIcon";

    /** {@hide} Type constant: Custom icon with a user-supplied bitmap. */
    public static final int TYPE_CUSTOM = -1;

    /** Type constant: Null icon.  It has no bitmap. */
    public static final int TYPE_NULL = 0;

    /** Type constant: no icons are specified. If all views uses this, then falls back
     * to the default type, but this is helpful to distinguish a view explicitly want
     * to have the default icon.
     * @hide
     */
    public static final int TYPE_NOT_SPECIFIED = 1;

    /** Type constant: Arrow icon.  (Default mouse pointer) */
    public static final int TYPE_ARROW = 1000;

    /** {@hide} Type constant: Spot hover icon for touchpads. */
    public static final int TYPE_SPOT_HOVER = 2000;

    /** {@hide} Type constant: Spot touch icon for touchpads. */
    public static final int TYPE_SPOT_TOUCH = 2001;

    /** {@hide} Type constant: Spot anchor icon for touchpads. */
    public static final int TYPE_SPOT_ANCHOR = 2002;

    // Type constants for additional predefined icons for mice.
    /** Type constant: context-menu. */
    public static final int TYPE_CONTEXT_MENU = 1001;

    /** Type constant: hand. */
    public static final int TYPE_HAND = 1002;

    /** Type constant: help. */
    public static final int TYPE_HELP = 1003;

    /** Type constant: wait. */
    public static final int TYPE_WAIT = 1004;

    /** Type constant: cell. */
    public static final int TYPE_CELL = 1006;

    /** Type constant: crosshair. */
    public static final int TYPE_CROSSHAIR = 1007;

    /** Type constant: text. */
    public static final int TYPE_TEXT = 1008;

    /** Type constant: vertical-text. */
    public static final int TYPE_VERTICAL_TEXT = 1009;

    /** Type constant: alias (indicating an alias of/shortcut to something is
      * to be created. */
    public static final int TYPE_ALIAS = 1010;

    /** Type constant: copy. */
    public static final int TYPE_COPY = 1011;

    /** Type constant: no-drop. */
    public static final int TYPE_NO_DROP = 1012;

    /** Type constant: all-scroll. */
    public static final int TYPE_ALL_SCROLL = 1013;

    /** Type constant: horizontal double arrow mainly for resizing. */
    public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014;

    /** Type constant: vertical double arrow mainly for resizing. */
    public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015;

    /** Type constant: diagonal double arrow -- top-right to bottom-left. */
    public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016;

    /** Type constant: diagonal double arrow -- top-left to bottom-right. */
    public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017;

    /** Type constant: zoom-in. */
    public static final int TYPE_ZOOM_IN = 1018;

    /** Type constant: zoom-out. */
    public static final int TYPE_ZOOM_OUT = 1019;

    /** Type constant: grab. */
    public static final int TYPE_GRAB = 1020;

    /** Type constant: grabbing. */
    public static final int TYPE_GRABBING = 1021;

    // OEM private types should be defined starting at this range to avoid
    // conflicts with any system types that may be defined in the future.
    private static final int TYPE_OEM_FIRST = 10000;

    /** The default pointer icon. */
    public static final int TYPE_DEFAULT = TYPE_ARROW;

    private static final PointerIcon gNullIcon = new PointerIcon(TYPE_NULL);
    private static final SparseArray<PointerIcon> gSystemIcons = new SparseArray<PointerIcon>();
    private static boolean sUseLargeIcons = false;

    private final int mType;
    private int mSystemIconResourceId;
    private Bitmap mBitmap;
    private float mHotSpotX;
    private float mHotSpotY;
    // The bitmaps for the additional frame of animated pointer icon. Note that the first frame
    // will be stored in mBitmap.
    private Bitmap mBitmapFrames[];
    private int mDurationPerFrame;

    private PointerIcon(int type) {
        mType = type;
    }

    /**
     * Gets a special pointer icon that has no bitmap.
     *
     * @return The null pointer icon.
     *
     * @see #TYPE_NULL
     * @hide
     */
    public static PointerIcon getNullIcon() {
        return gNullIcon;
    }

    /**
     * Gets the default pointer icon.
     *
     * @param context The context.
     * @return The default pointer icon.
     *
     * @throws IllegalArgumentException if context is null.
     * @hide
     */
    public static PointerIcon getDefaultIcon(@NonNull Context context) {
        return getSystemIcon(context, TYPE_DEFAULT);
    }

    /**
     * Gets a system pointer icon for the given type.
     * If typeis not recognized, returns the default pointer icon.
     *
     * @param context The context.
     * @param type The pointer icon type.
     * @return The pointer icon.
     *
     * @throws IllegalArgumentException if context is null.
     */
    public static PointerIcon getSystemIcon(@NonNull Context context, int type) {
        if (context == null) {
            throw new IllegalArgumentException("context must not be null");
        }

        if (type == TYPE_NULL) {
            return gNullIcon;
        }

        PointerIcon icon = gSystemIcons.get(type);
        if (icon != null) {
            return icon;
        }

        int typeIndex = getSystemIconTypeIndex(type);
        if (typeIndex == 0) {
            typeIndex = getSystemIconTypeIndex(TYPE_DEFAULT);
        }

        int defStyle = sUseLargeIcons ?
                com.android.internal.R.style.LargePointer : com.android.internal.R.style.Pointer;
        TypedArray a = context.obtainStyledAttributes(null,
                com.android.internal.R.styleable.Pointer,
                0, defStyle);
        int resourceId = a.getResourceId(typeIndex, -1);
        a.recycle();

        if (resourceId == -1) {
            Log.w(TAG, "Missing theme resources for pointer icon type " + type);
            return type == TYPE_DEFAULT ? gNullIcon : getSystemIcon(context, TYPE_DEFAULT);
        }

        icon = new PointerIcon(type);
        if ((resourceId & 0xff000000) == 0x01000000) {
            icon.mSystemIconResourceId = resourceId;
        } else {
            icon.loadResource(context, context.getResources(), resourceId);
        }
        gSystemIcons.append(type, icon);
        return icon;
    }

    /**
     * Updates wheter accessibility large icons are used or not.
     * @hide
     */
    public static void setUseLargeIcons(boolean use) {
        sUseLargeIcons = use;
        gSystemIcons.clear();
    }

    /**
     * Creates a custom pointer icon from the given bitmap and hotspot information.
     *
     * @param bitmap The bitmap for the icon.
     * @param hotSpotX The X offset of the pointer icon hotspot in the bitmap.
     *        Must be within the [0, bitmap.getWidth()) range.
     * @param hotSpotY The Y offset of the pointer icon hotspot in the bitmap.
     *        Must be within the [0, bitmap.getHeight()) range.
     * @return A pointer icon for this bitmap.
     *
     * @throws IllegalArgumentException if bitmap is null, or if the x/y hotspot
     *         parameters are invalid.
     */
    public static PointerIcon create(@NonNull Bitmap bitmap, float hotSpotX, float hotSpotY) {
        if (bitmap == null) {
            throw new IllegalArgumentException("bitmap must not be null");
        }
        validateHotSpot(bitmap, hotSpotX, hotSpotY);

        PointerIcon icon = new PointerIcon(TYPE_CUSTOM);
        icon.mBitmap = bitmap;
        icon.mHotSpotX = hotSpotX;
        icon.mHotSpotY = hotSpotY;
        return icon;
    }

    /**
     * Loads a custom pointer icon from an XML resource.
     * <p>
     * The XML resource should have the following form:
     * <code>
     * &lt;?xml version="1.0" encoding="utf-8"?&gt;
     * &lt;pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     *   android:bitmap="@drawable/my_pointer_bitmap"
     *   android:hotSpotX="24"
     *   android:hotSpotY="24" /&gt;
     * </code>
     * </p>
     *
     * @param resources The resources object.
     * @param resourceId The resource id.
     * @return The pointer icon.
     *
     * @throws IllegalArgumentException if resources is null.
     * @throws Resources.NotFoundException if the resource was not found or the drawable
     * linked in the resource was not found.
     */
    public static PointerIcon load(@NonNull Resources resources, @XmlRes int resourceId) {
        if (resources == null) {
            throw new IllegalArgumentException("resources must not be null");
        }

        PointerIcon icon = new PointerIcon(TYPE_CUSTOM);
        icon.loadResource(null, resources, resourceId);
        return icon;
    }

    /**
     * Loads the bitmap and hotspot information for a pointer icon, if it is not already loaded.
     * Returns a pointer icon (not necessarily the same instance) with the information filled in.
     *
     * @param context The context.
     * @return The loaded pointer icon.
     *
     * @throws IllegalArgumentException if context is null.
     * @hide
     */
    public PointerIcon load(@NonNull Context context) {
        if (context == null) {
            throw new IllegalArgumentException("context must not be null");
        }

        if (mSystemIconResourceId == 0 || mBitmap != null) {
            return this;
        }

        PointerIcon result = new PointerIcon(mType);
        result.mSystemIconResourceId = mSystemIconResourceId;
        result.loadResource(context, context.getResources(), mSystemIconResourceId);
        return result;
    }

    /** @hide */
    public int getType() {
        return mType;
    }

    public static final Parcelable.Creator<PointerIcon> CREATOR
            = new Parcelable.Creator<PointerIcon>() {
        public PointerIcon createFromParcel(Parcel in) {
            int type = in.readInt();
            if (type == TYPE_NULL) {
                return getNullIcon();
            }

            int systemIconResourceId = in.readInt();
            if (systemIconResourceId != 0) {
                PointerIcon icon = new PointerIcon(type);
                icon.mSystemIconResourceId = systemIconResourceId;
                return icon;
            }

            Bitmap bitmap = Bitmap.CREATOR.createFromParcel(in);
            float hotSpotX = in.readFloat();
            float hotSpotY = in.readFloat();
            return PointerIcon.create(bitmap, hotSpotX, hotSpotY);
        }

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

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mType);

        if (mType != TYPE_NULL) {
            out.writeInt(mSystemIconResourceId);
            if (mSystemIconResourceId == 0) {
                mBitmap.writeToParcel(out, flags);
                out.writeFloat(mHotSpotX);
                out.writeFloat(mHotSpotY);
            }
        }
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }

        if (other == null || !(other instanceof PointerIcon)) {
            return false;
        }

        PointerIcon otherIcon = (PointerIcon) other;
        if (mType != otherIcon.mType
                || mSystemIconResourceId != otherIcon.mSystemIconResourceId) {
            return false;
        }

        if (mSystemIconResourceId == 0 && (mBitmap != otherIcon.mBitmap
                || mHotSpotX != otherIcon.mHotSpotX
                || mHotSpotY != otherIcon.mHotSpotY)) {
            return false;
        }

        return true;
    }

    private void loadResource(Context context, Resources resources, @XmlRes int resourceId) {
        final XmlResourceParser parser = resources.getXml(resourceId);
        final int bitmapRes;
        final float hotSpotX;
        final float hotSpotY;
        try {
            XmlUtils.beginDocument(parser, "pointer-icon");

            final TypedArray a = resources.obtainAttributes(
                    parser, com.android.internal.R.styleable.PointerIcon);
            bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0);
            hotSpotX = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
            hotSpotY = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
            a.recycle();
        } catch (Exception ex) {
            throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex);
        } finally {
            parser.close();
        }

        if (bitmapRes == 0) {
            throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute.");
        }

        Drawable drawable;
        if (context == null) {
            drawable = resources.getDrawable(bitmapRes);
        } else {
            drawable = context.getDrawable(bitmapRes);
        }
        if (drawable instanceof AnimationDrawable) {
            // Extract animation frame bitmaps.
            final AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
            final int frames = animationDrawable.getNumberOfFrames();
            drawable = animationDrawable.getFrame(0);
            if (frames == 1) {
                Log.w(TAG, "Animation icon with single frame -- simply treating the first "
                        + "frame as a normal bitmap icon.");
            } else {
                // Assumes they have the exact duration.
                mDurationPerFrame = animationDrawable.getDuration(0);
                mBitmapFrames = new Bitmap[frames - 1];
                final int width = drawable.getIntrinsicWidth();
                final int height = drawable.getIntrinsicHeight();
                for (int i = 1; i < frames; ++i) {
                    Drawable drawableFrame = animationDrawable.getFrame(i);
                    if (!(drawableFrame instanceof BitmapDrawable)) {
                        throw new IllegalArgumentException("Frame of an animated pointer icon "
                                + "must refer to a bitmap drawable.");
                    }
                    if (drawableFrame.getIntrinsicWidth() != width ||
                        drawableFrame.getIntrinsicHeight() != height) {
                        throw new IllegalArgumentException("The bitmap size of " + i + "-th frame "
                                + "is different. All frames should have the exact same size and "
                                + "share the same hotspot.");
                    }
                    mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap();
                }
            }
        }
        if (!(drawable instanceof BitmapDrawable)) {
            throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
                    + "refer to a bitmap drawable.");
        }

        // Set the properties now that we have successfully loaded the icon.
        mBitmap = ((BitmapDrawable)drawable).getBitmap();
        mHotSpotX = hotSpotX;
        mHotSpotY = hotSpotY;
    }

    private static void validateHotSpot(Bitmap bitmap, float hotSpotX, float hotSpotY) {
        if (hotSpotX < 0 || hotSpotX >= bitmap.getWidth()) {
            throw new IllegalArgumentException("x hotspot lies outside of the bitmap area");
        }
        if (hotSpotY < 0 || hotSpotY >= bitmap.getHeight()) {
            throw new IllegalArgumentException("y hotspot lies outside of the bitmap area");
        }
    }

    private static int getSystemIconTypeIndex(int type) {
        switch (type) {
            case TYPE_ARROW:
                return com.android.internal.R.styleable.Pointer_pointerIconArrow;
            case TYPE_SPOT_HOVER:
                return com.android.internal.R.styleable.Pointer_pointerIconSpotHover;
            case TYPE_SPOT_TOUCH:
                return com.android.internal.R.styleable.Pointer_pointerIconSpotTouch;
            case TYPE_SPOT_ANCHOR:
                return com.android.internal.R.styleable.Pointer_pointerIconSpotAnchor;
            case TYPE_HAND:
                return com.android.internal.R.styleable.Pointer_pointerIconHand;
            case TYPE_CONTEXT_MENU:
                return com.android.internal.R.styleable.Pointer_pointerIconContextMenu;
            case TYPE_HELP:
                return com.android.internal.R.styleable.Pointer_pointerIconHelp;
            case TYPE_WAIT:
                return com.android.internal.R.styleable.Pointer_pointerIconWait;
            case TYPE_CELL:
                return com.android.internal.R.styleable.Pointer_pointerIconCell;
            case TYPE_CROSSHAIR:
                return com.android.internal.R.styleable.Pointer_pointerIconCrosshair;
            case TYPE_TEXT:
                return com.android.internal.R.styleable.Pointer_pointerIconText;
            case TYPE_VERTICAL_TEXT:
                return com.android.internal.R.styleable.Pointer_pointerIconVerticalText;
            case TYPE_ALIAS:
                return com.android.internal.R.styleable.Pointer_pointerIconAlias;
            case TYPE_COPY:
                return com.android.internal.R.styleable.Pointer_pointerIconCopy;
            case TYPE_ALL_SCROLL:
                return com.android.internal.R.styleable.Pointer_pointerIconAllScroll;
            case TYPE_NO_DROP:
                return com.android.internal.R.styleable.Pointer_pointerIconNodrop;
            case TYPE_HORIZONTAL_DOUBLE_ARROW:
                return com.android.internal.R.styleable.Pointer_pointerIconHorizontalDoubleArrow;
            case TYPE_VERTICAL_DOUBLE_ARROW:
                return com.android.internal.R.styleable.Pointer_pointerIconVerticalDoubleArrow;
            case TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW:
                return com.android.internal.R.styleable.
                        Pointer_pointerIconTopRightDiagonalDoubleArrow;
            case TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW:
                return com.android.internal.R.styleable.
                        Pointer_pointerIconTopLeftDiagonalDoubleArrow;
            case TYPE_ZOOM_IN:
                return com.android.internal.R.styleable.Pointer_pointerIconZoomIn;
            case TYPE_ZOOM_OUT:
                return com.android.internal.R.styleable.Pointer_pointerIconZoomOut;
            case TYPE_GRAB:
                return com.android.internal.R.styleable.Pointer_pointerIconGrab;
            case TYPE_GRABBING:
                return com.android.internal.R.styleable.Pointer_pointerIconGrabbing;
            default:
                return 0;
        }
    }
}
