/*
 * 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 com.android.internal.view.menu;

import com.android.internal.view.menu.MenuBuilder.ItemInvoker;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewDebug;
import android.widget.TextView;
import android.text.Layout;

/**
 * The item view for each item in the {@link IconMenuView}.  
 */
public final class IconMenuItemView extends TextView implements MenuView.ItemView {
    
    private static final int NO_ALPHA = 0xFF;
    
    private IconMenuView mIconMenuView;
    
    private ItemInvoker mItemInvoker;
    private MenuItemImpl mItemData; 
    
    private Drawable mIcon;
    
    private int mTextAppearance;
    private Context mTextAppearanceContext;
    
    private float mDisabledAlpha;

    private Rect mPositionIconAvailable = new Rect();
    private Rect mPositionIconOutput = new Rect();
    
    private boolean mShortcutCaptionMode;
    private String mShortcutCaption;
    
    private static String sPrependShortcutLabel;

    public IconMenuItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);

        if (sPrependShortcutLabel == null) {
            /*
             * Views should only be constructed from the UI thread, so no
             * synchronization needed
             */
            sPrependShortcutLabel = getResources().getString(
                    com.android.internal.R.string.prepend_shortcut_label);
        }
        
        TypedArray a =
            context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);

        mDisabledAlpha = a.getFloat(
                com.android.internal.R.styleable.MenuView_itemIconDisabledAlpha, 0.8f);
        mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
                                          MenuView_itemTextAppearance, -1);
        mTextAppearanceContext = context;
        
        a.recycle();
    }
    
    public IconMenuItemView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * Initializes with the provided title and icon
     * @param title The title of this item
     * @param icon The icon of this item
     */
    void initialize(CharSequence title, Drawable icon) {
        setClickable(true);
        setFocusable(true);

        if (mTextAppearance != -1) {
            setTextAppearance(mTextAppearanceContext, mTextAppearance);
        }

        setTitle(title);
        setIcon(icon);
    }
    
    public void initialize(MenuItemImpl itemData, int menuType) {
        mItemData = itemData;

        initialize(itemData.getTitleForItemView(this), itemData.getIcon());
        
        setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
        setEnabled(itemData.isEnabled());
    }

    @Override
    public boolean performClick() {
        // Let the view's click listener have top priority (the More button relies on this)
        if (super.performClick()) {
            return true;
        }
        
        if ((mItemInvoker != null) && (mItemInvoker.invokeItem(mItemData))) {
            playSoundEffect(SoundEffectConstants.CLICK);
            return true;
        } else {
            return false;
        }
    }
    
    public void setTitle(CharSequence title) {
        
        if (mShortcutCaptionMode) {
            /*
             * Don't set the title directly since it will replace the
             * shortcut+title being shown. Instead, re-set the shortcut caption
             * mode so the new title is shown.
             */
            setCaptionMode(true);
            
        } else if (title != null) {
            setText(title);
        }
    }
    
    void setCaptionMode(boolean shortcut) {
        /*
         * If there is no item model, don't do any of the below (for example,
         * the 'More' item doesn't have a model)
         */
        if (mItemData == null) {
            return;
        }
        
        mShortcutCaptionMode = shortcut && (mItemData.shouldShowShortcut());
        
        CharSequence text = mItemData.getTitleForItemView(this);
        
        if (mShortcutCaptionMode) {
            
            if (mShortcutCaption == null) {
                mShortcutCaption = mItemData.getShortcutLabel();
            }

            text = mShortcutCaption;
        }
        
        setText(text);
    }
    
    public void setIcon(Drawable icon) {
        mIcon = icon;
        
        if (icon != null) {
            
            /* Set the bounds of the icon since setCompoundDrawables needs it. */
            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
            
            // Set the compound drawables
            setCompoundDrawables(null, icon, null, null);
            
            // When there is an icon, make sure the text is at the bottom
            setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);

            /*
             * Request a layout to reposition the icon. The positioning of icon
             * depends on this TextView's line bounds, which is only available
             * after a layout.
             */  
            requestLayout();
        } else {
            setCompoundDrawables(null, null, null, null);
            
            // When there is no icon, make sure the text is centered vertically
            setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
        }
    }

    public void setItemInvoker(ItemInvoker itemInvoker) {
        mItemInvoker = itemInvoker;
    }
    
    @ViewDebug.CapturedViewProperty(retrieveReturn = true)
    public MenuItemImpl getItemData() {
        return mItemData;
    }

    @Override
    public void setVisibility(int v) {
        super.setVisibility(v);
        
        if (mIconMenuView != null) {
            // On visibility change, mark the IconMenuView to refresh itself eventually
            mIconMenuView.markStaleChildren();
        }
    }
    
    void setIconMenuView(IconMenuView iconMenuView) {
        mIconMenuView = iconMenuView;
    }

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

        if (mItemData != null && mIcon != null) {
            // When disabled, the not-focused state and the pressed state should
            // drop alpha on the icon
            final boolean isInAlphaState = !mItemData.isEnabled() && (isPressed() || !isFocused());
            mIcon.setAlpha(isInAlphaState ? (int) (mDisabledAlpha * NO_ALPHA) : NO_ALPHA);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        
        positionIcon();
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);

        // our layout params depend on the length of the text
        setLayoutParams(getTextAppropriateLayoutParams());
    }

    /**
     * @return layout params appropriate for this view.  If layout params already exist, it will
     *         augment them to be appropriate to the current text size.
     */
    IconMenuView.LayoutParams getTextAppropriateLayoutParams() {
        IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams();
        if (lp == null) {
            // Default layout parameters
            lp = new IconMenuView.LayoutParams(
                    IconMenuView.LayoutParams.MATCH_PARENT, IconMenuView.LayoutParams.MATCH_PARENT);
        }

        // Set the desired width of item
        lp.desiredWidth = (int) Layout.getDesiredWidth(getText(), getPaint());

        return lp;
    }

    /**
     * Positions the icon vertically (horizontal centering is taken care of by
     * the TextView's gravity).
     */
    private void positionIcon() {
        
        if (mIcon == null) {
            return;
        }
        
        // We reuse the output rectangle as a temp rect
        Rect tmpRect = mPositionIconOutput;
        getLineBounds(0, tmpRect);
        mPositionIconAvailable.set(0, 0, getWidth(), tmpRect.top);
        Gravity.apply(Gravity.CENTER_VERTICAL | Gravity.LEFT, mIcon.getIntrinsicWidth(), mIcon
                .getIntrinsicHeight(), mPositionIconAvailable, mPositionIconOutput);
        mIcon.setBounds(mPositionIconOutput);
    }

    public void setCheckable(boolean checkable) {
    }

    public void setChecked(boolean checked) {
    }

    public void setShortcut(boolean showShortcut, char shortcutKey) {
        
        if (mShortcutCaptionMode) {
            /*
             * Shortcut has changed and we're showing it right now, need to
             * update (clear the old one first).
             */
            mShortcutCaption = null;
            setCaptionMode(true);
        }
    }

    public boolean prefersCondensedTitle() {
        return true;
    }

    public boolean showsIcon() {
        return true;
    }

}
