/*
 * Copyright (C) 2012 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.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

class KeyguardMultiUserAvatar extends FrameLayout {
    private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
    private static final boolean DEBUG = KeyguardConstants.DEBUG;

    private ImageView mUserImage;
    private TextView mUserName;
    private UserInfo mUserInfo;
    private static final float ACTIVE_ALPHA = 1.0f;
    private static final float INACTIVE_ALPHA = 1.0f;
    private static final float ACTIVE_SCALE = 1.5f;
    private static final float ACTIVE_TEXT_ALPHA = 0f;
    private static final float INACTIVE_TEXT_ALPHA = 0.5f;
    private static final int SWITCH_ANIMATION_DURATION = 150;

    private final float mActiveAlpha;
    private final float mActiveScale;
    private final float mActiveTextAlpha;
    private final float mInactiveAlpha;
    private final float mInactiveTextAlpha;
    private final float mShadowRadius;
    private final float mStroke;
    private final float mIconSize;
    private final int mFrameColor;
    private final int mFrameShadowColor;
    private final int mTextColor;
    private final int mHighlightColor;

    private boolean mTouched;

    private boolean mActive;
    private boolean mInit = true;
    private KeyguardMultiUserSelectorView mUserSelector;
    private KeyguardCircleFramedDrawable mFramed;
    private boolean mPressLock;
    private UserManager mUserManager;

    public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
            KeyguardMultiUserSelectorView userSelector, UserInfo info) {
        KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
                LayoutInflater.from(context).inflate(resId, userSelector, false);

        icon.init(info, userSelector);
        return icon;
    }

    public KeyguardMultiUserAvatar(Context context) {
        this(context, null, 0);
    }

    public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        Resources res = mContext.getResources();
        mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
        mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
        mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
        mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
        mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
        mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
        mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
        mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
        mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
        mActiveScale = ACTIVE_SCALE;
        mActiveAlpha = ACTIVE_ALPHA;
        mInactiveAlpha = INACTIVE_ALPHA;
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);

        mTouched = false;

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    protected String rewriteIconPath(String path) {
        return path;
    }

    public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
        mUserInfo = user;
        mUserSelector = userSelector;

        mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
        mUserName = (TextView) findViewById(R.id.keyguard_user_name);

        mFramed = (KeyguardCircleFramedDrawable)
                MultiUserAvatarCache.getInstance().get(user.id);

        // If we can't find it or the params don't match, create the drawable again
        if (mFramed == null
                || !mFramed.verifyParams(mIconSize, mFrameColor, mStroke, mFrameShadowColor,
                        mShadowRadius, mHighlightColor)) {
            Bitmap icon = null;
            try {
                icon = mUserManager.getUserIcon(user.id);
            } catch (Exception e) {
                if (DEBUG) Log.d(TAG, "failed to get profile icon " + user, e);
            }

            if (icon == null) {
                icon = BitmapFactory.decodeResource(mContext.getResources(),
                        com.android.internal.R.drawable.ic_contact_picture);
            }

            mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
                    mFrameShadowColor, mShadowRadius, mHighlightColor);
            MultiUserAvatarCache.getInstance().put(user.id, mFramed);
        }

        mFramed.reset();

        mUserImage.setImageDrawable(mFramed);
        mUserName.setText(mUserInfo.name);
        setOnClickListener(mUserSelector);
        mInit = false;
    }

    public void setActive(boolean active, boolean animate, final Runnable onComplete) {
        if (mActive != active || mInit) {
            mActive = active;

            if (active) {
                KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
                parent.setTopChild(this);
                // TODO: Create an appropriate asset when string changes are possible.
                setContentDescription(mUserName.getText()
                        + ". " + mContext.getString(R.string.user_switched, ""));
            } else {
                setContentDescription(mUserName.getText());
            }
        }
        updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
    }

    void updateVisualsForActive(boolean active, boolean animate, int duration,
            final Runnable onComplete) {
        final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
        final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
        final float finalScale = active ? 1f : 1f / mActiveScale;
        final float initScale = mFramed.getScale();
        final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
                (int) (mInactiveTextAlpha * 255);
        final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
                (int) (mActiveTextAlpha * 255);
        int textColor = mTextColor;
        mUserName.setTextColor(textColor);

        if (animate && mTouched) {
            ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
            va.addUpdateListener(new AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float r = animation.getAnimatedFraction();
                    float scale = (1 - r) * initScale + r * finalScale;
                    float alpha = (1 - r) * initAlpha + r * finalAlpha;
                    int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
                    mFramed.setScale(scale);
                    mUserImage.setAlpha(alpha);
                    mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
                    mUserImage.invalidate();
                }
            });
            va.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    if (onComplete != null) {
                        onComplete.run();
                    }
                }
            });
            va.setDuration(duration);
            va.start();
        } else {
            mFramed.setScale(finalScale);
            mUserImage.setAlpha(finalAlpha);
            mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
            if (onComplete != null) {
                post(onComplete);
            }
        }

        mTouched = true;
    }

    @Override
    public void setPressed(boolean pressed) {
        if (mPressLock && !pressed) {
            return;
        }

        if (mPressLock || !pressed || isClickable()) {
            super.setPressed(pressed);
            mFramed.setPressed(pressed);
            mUserImage.invalidate();
        }
    }

    public void lockPressed(boolean pressed) {
        mPressLock = pressed;
        setPressed(pressed);
    }

    public UserInfo getUserInfo() {
        return mUserInfo;
    }
}
