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

import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
import android.app.Notification;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pools;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RemoteViews;

import com.android.internal.R;

import java.io.IOException;

/**
 * A message of a {@link MessagingLayout} that is an image.
 */
@RemoteViews.RemoteView
public class MessagingImageMessage extends ImageView implements MessagingMessage {
    private static final String TAG = "MessagingImageMessage";
    private static Pools.SimplePool<MessagingImageMessage> sInstancePool
            = new Pools.SynchronizedPool<>(10);
    private final MessagingMessageState mState = new MessagingMessageState(this);
    private final int mMinImageHeight;
    private final Path mPath = new Path();
    private final int mImageRounding;
    private final int mMaxImageHeight;
    private final int mIsolatedSize;
    private final int mExtraSpacing;
    private Drawable mDrawable;
    private float mAspectRatio;
    private int mActualWidth;
    private int mActualHeight;
    private boolean mIsIsolated;
    private ImageResolver mImageResolver;

    public MessagingImageMessage(@NonNull Context context) {
        this(context, null);
    }

    public MessagingImageMessage(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MessagingImageMessage(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public MessagingImageMessage(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mMinImageHeight = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.messaging_image_min_size);
        mMaxImageHeight = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.messaging_image_max_height);
        mImageRounding = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.messaging_image_rounding);
        mExtraSpacing = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.messaging_image_extra_spacing);
        setMaxHeight(mMaxImageHeight);
        mIsolatedSize = getResources().getDimensionPixelSize(R.dimen.messaging_avatar_size);
    }

    @Override
    public MessagingMessageState getState() {
        return mState;
    }

    @Override
    public boolean setMessage(Notification.MessagingStyle.Message message) {
        MessagingMessage.super.setMessage(message);
        Drawable drawable;
        try {
            Uri uri = message.getDataUri();
            drawable = mImageResolver != null ? mImageResolver.loadImage(uri) :
                    LocalImageResolver.resolveImage(uri, getContext());
        } catch (IOException | SecurityException e) {
            e.printStackTrace();
            return false;
        }
        if (drawable == null) {
            return false;
        }
        int intrinsicHeight = drawable.getIntrinsicHeight();
        if (intrinsicHeight == 0) {
            Log.w(TAG, "Drawable with 0 intrinsic height was returned");
            return false;
        }
        mDrawable = drawable;
        mAspectRatio = ((float) mDrawable.getIntrinsicWidth()) / intrinsicHeight;
        setImageDrawable(drawable);
        setContentDescription(message.getText());
        return true;
    }

    static MessagingMessage createMessage(MessagingLayout layout,
            Notification.MessagingStyle.Message m, ImageResolver resolver) {
        MessagingLinearLayout messagingLinearLayout = layout.getMessagingLinearLayout();
        MessagingImageMessage createdMessage = sInstancePool.acquire();
        if (createdMessage == null) {
            createdMessage = (MessagingImageMessage) LayoutInflater.from(
                    layout.getContext()).inflate(
                            R.layout.notification_template_messaging_image_message,
                            messagingLinearLayout,
                            false);
            createdMessage.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
        }
        createdMessage.setImageResolver(resolver);
        boolean created = createdMessage.setMessage(m);
        if (!created) {
            createdMessage.recycle();
            return MessagingTextMessage.createMessage(layout, m);
        }
        return createdMessage;
    }

    private void setImageResolver(ImageResolver resolver) {
        mImageResolver = resolver;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        canvas.clipPath(getRoundedRectPath());
        int width = (int) Math.max(getActualWidth(), getActualHeight() * mAspectRatio);
        int height = (int) (width / mAspectRatio);
        int left = (int) ((getActualWidth() - width) / 2.0f);
        mDrawable.setBounds(left, 0, left + width, height);
        mDrawable.draw(canvas);
        canvas.restore();
    }

    public Path getRoundedRectPath() {
        int left = 0;
        int right = getActualWidth();
        int top = 0;
        int bottom = getActualHeight();
        mPath.reset();
        int width = right - left;
        float roundnessX = mImageRounding;
        float roundnessY = mImageRounding;
        roundnessX = Math.min(width / 2, roundnessX);
        roundnessY = Math.min((bottom - top) / 2, roundnessY);
        mPath.moveTo(left, top + roundnessY);
        mPath.quadTo(left, top, left + roundnessX, top);
        mPath.lineTo(right - roundnessX, top);
        mPath.quadTo(right, top, right, top + roundnessY);
        mPath.lineTo(right, bottom - roundnessY);
        mPath.quadTo(right, bottom, right - roundnessX, bottom);
        mPath.lineTo(left + roundnessX, bottom);
        mPath.quadTo(left, bottom, left, bottom - roundnessY);
        mPath.close();
        return mPath;
    }

    public void recycle() {
        MessagingMessage.super.recycle();
        setImageBitmap(null);
        mDrawable = null;
        sInstancePool.release(this);
    }

    public static void dropCache() {
        sInstancePool = new Pools.SynchronizedPool<>(10);
    }

    @Override
    public int getMeasuredType() {
        int measuredHeight = getMeasuredHeight();
        int minImageHeight;
        if (mIsIsolated) {
            minImageHeight = mIsolatedSize;
        } else {
            minImageHeight = mMinImageHeight;
        }
        boolean measuredTooSmall = measuredHeight < minImageHeight
                && measuredHeight != mDrawable.getIntrinsicHeight();
        if (measuredTooSmall) {
            return MEASURED_TOO_SMALL;
        } else {
            if (!mIsIsolated && measuredHeight != mDrawable.getIntrinsicHeight()) {
                return MEASURED_SHORTENED;
            } else {
                return MEASURED_NORMAL;
            }
        }
    }

    @Override
    public void setMaxDisplayedLines(int lines) {
        // Nothing to do, this should be handled automatically.
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mIsIsolated) {
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                    MeasureSpec.getSize(heightMeasureSpec));
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // TODO: ensure that this isn't called when transforming
        setActualWidth(getStaticWidth());
        setActualHeight(getHeight());
    }

    @Override
    public int getConsumedLines() {
        return 3;
    }

    public void setActualWidth(int actualWidth) {
        mActualWidth = actualWidth;
        invalidate();
    }

    public int getActualWidth() {
        return mActualWidth;
    }

    public void setActualHeight(int actualHeight) {
        mActualHeight = actualHeight;
        invalidate();
    }

    public int getActualHeight() {
        return mActualHeight;
    }

    public int getStaticWidth() {
        if (mIsIsolated) {
            return getWidth();
        }
        return (int) (getHeight() * mAspectRatio);
    }

    public void setIsolated(boolean isolated) {
        if (mIsIsolated != isolated) {
            mIsIsolated = isolated;
            // update the layout params not to have margins
            ViewGroup.MarginLayoutParams layoutParams =
                    (ViewGroup.MarginLayoutParams) getLayoutParams();
            layoutParams.topMargin = isolated ? 0 : mExtraSpacing;
            setLayoutParams(layoutParams);
        }
    }

    @Override
    public int getExtraSpacing() {
        return mExtraSpacing;
    }
}
