/*
 * Copyright (C) 2016 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.settings.display;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.settings.R;

/**
 * The view for a single entry in a conversation. This is a simplified version of
 * com.android.messaging.ui.conversation.ConversationMessageView class.
 */
public class ConversationMessageView extends FrameLayout {
    private final boolean mIncoming;
    private final CharSequence mMessageText;
    private final CharSequence mTimestampText;
    private final CharSequence mIconText;
    private final int mIconTextColor;
    private final int mIconBackgroundColor;

    private LinearLayout mMessageBubble;
    private ViewGroup mMessageTextAndInfoView;
    private TextView mMessageTextView;
    private TextView mStatusTextView;
    private TextView mContactIconView;

    public ConversationMessageView(Context context) {
        this(context, null);
    }

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

    public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public ConversationMessageView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ConversationMessageView);

        mIncoming = a.getBoolean(R.styleable.ConversationMessageView_incoming, true);
        mMessageText = a.getString(R.styleable.ConversationMessageView_messageText);
        mTimestampText = a.getString(R.styleable.ConversationMessageView_timestampText);
        mIconText = a.getString(R.styleable.ConversationMessageView_iconText);
        mIconTextColor = a.getColor(R.styleable.ConversationMessageView_iconTextColor, 0);
        mIconBackgroundColor = a.getColor(R.styleable.ConversationMessageView_iconBackgroundColor,
                0);
        a.recycle();
        LayoutInflater.from(context).inflate(R.layout.conversation_message_icon, this);
        LayoutInflater.from(context).inflate(R.layout.conversation_message_content, this);
    }

    @Override
    protected void onFinishInflate() {
        mMessageBubble = (LinearLayout) findViewById(R.id.message_content);
        mMessageTextAndInfoView = (ViewGroup) findViewById(R.id.message_text_and_info);
        mMessageTextView = (TextView) findViewById(R.id.message_text);
        mStatusTextView = (TextView) findViewById(R.id.message_status);
        mContactIconView = (TextView) findViewById(R.id.conversation_icon);
        updateViewContent();
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        updateViewAppearance();

        final int horizontalSpace = MeasureSpec.getSize(widthMeasureSpec);

        final int unspecifiedMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        int iconMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

        mContactIconView.measure(iconMeasureSpec, iconMeasureSpec);
        iconMeasureSpec = MeasureSpec.makeMeasureSpec(
                Math.max(mContactIconView.getMeasuredWidth(), mContactIconView.getMeasuredHeight()),
                MeasureSpec.EXACTLY);
        mContactIconView.measure(iconMeasureSpec, iconMeasureSpec);

        final int arrowWidth =
                getResources().getDimensionPixelSize(R.dimen.message_bubble_arrow_width);

        // We need to subtract contact icon width twice from the horizontal space to get
        // the max leftover space because we want the message bubble to extend no further than the
        // starting position of the message bubble in the opposite direction.
        final int maxLeftoverSpace = horizontalSpace - mContactIconView.getMeasuredWidth() * 2
                - arrowWidth - getPaddingLeft() - getPaddingRight();
        final int messageContentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(maxLeftoverSpace,
                MeasureSpec.AT_MOST);

        mMessageBubble.measure(messageContentWidthMeasureSpec, unspecifiedMeasureSpec);

        final int maxHeight = Math.max(mContactIconView.getMeasuredHeight(),
                mMessageBubble.getMeasuredHeight());
        setMeasuredDimension(horizontalSpace, maxHeight + getPaddingBottom() + getPaddingTop());
    }

    @Override
    protected void onLayout(final boolean changed, final int left, final int top, final int right,
            final int bottom) {
        final boolean isRtl = isLayoutRtl(this);

        final int iconWidth = mContactIconView.getMeasuredWidth();
        final int iconHeight = mContactIconView.getMeasuredHeight();
        final int iconTop = getPaddingTop();
        final int contentWidth = (right -left) - iconWidth - getPaddingLeft() - getPaddingRight();
        final int contentHeight = mMessageBubble.getMeasuredHeight();
        final int contentTop = iconTop;

        final int iconLeft;
        final int contentLeft;

        if (mIncoming) {
            if (isRtl) {
                iconLeft = (right - left) - getPaddingRight() - iconWidth;
                contentLeft = iconLeft - contentWidth;
            } else {
                iconLeft = getPaddingLeft();
                contentLeft = iconLeft + iconWidth;
            }
        } else {
            if (isRtl) {
                iconLeft = getPaddingLeft();
                contentLeft = iconLeft + iconWidth;
            } else {
                iconLeft = (right - left) - getPaddingRight() - iconWidth;
                contentLeft = iconLeft - contentWidth;
            }
        }

        mContactIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight);

        mMessageBubble.layout(contentLeft, contentTop, contentLeft + contentWidth,
                contentTop + contentHeight);
    }

    private static boolean isLayoutRtl(final View view) {
        return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection();
    }

    private void updateViewContent() {
        mMessageTextView.setText(mMessageText);
        mStatusTextView.setText(mTimestampText);
        mContactIconView.setText(mIconText);

        mContactIconView.setTextColor(mIconTextColor);
        final Drawable iconBase = getContext().getDrawable(R.drawable.conversation_message_icon);
        mContactIconView
                .setBackground(getTintedDrawable(getContext(), iconBase, mIconBackgroundColor));
    }

    private void updateViewAppearance() {
        final Resources res = getResources();

        final int arrowWidth = res.getDimensionPixelOffset(
                R.dimen.message_bubble_arrow_width);
        final int messageTextLeftRightPadding = res.getDimensionPixelOffset(
                R.dimen.message_text_left_right_padding);
        final int textTopPadding = res.getDimensionPixelOffset(
                R.dimen.message_text_top_padding);
        final int textBottomPadding = res.getDimensionPixelOffset(
                R.dimen.message_text_bottom_padding);

        final int textLeftPadding, textRightPadding;

        if (mIncoming) {
            textLeftPadding = messageTextLeftRightPadding + arrowWidth;
            textRightPadding = messageTextLeftRightPadding;
        } else {
            textLeftPadding = messageTextLeftRightPadding;
            textRightPadding = messageTextLeftRightPadding + arrowWidth;
        }

        // These values do not depend on whether the message includes attachments
        final int gravity = mIncoming ? (Gravity.START | Gravity.CENTER_VERTICAL) :
                (Gravity.END | Gravity.CENTER_VERTICAL);
        final int messageTopPadding = res.getDimensionPixelSize(
                R.dimen.message_padding_default);
        final int metadataTopPadding =  res.getDimensionPixelOffset(
                R.dimen.message_metadata_top_padding);

        // Update the message text/info views
        final int bubbleDrawableResId = mIncoming ? R.drawable.msg_bubble_incoming
                : R.drawable.msg_bubble_outgoing;
        final int bubbleColorResId = mIncoming ? R.color.message_bubble_incoming
                : R.color.message_bubble_outgoing;
        final Context context = getContext();

        final Drawable textBackgroundDrawable = getTintedDrawable(context,
                context.getDrawable(bubbleDrawableResId),
                context.getColor(bubbleColorResId));
        mMessageTextAndInfoView.setBackground(textBackgroundDrawable);

        if (isLayoutRtl(this)) {
            // Need to switch right and left padding in RtL mode
            mMessageTextAndInfoView.setPadding(textRightPadding,
                    textTopPadding + metadataTopPadding,
                    textLeftPadding, textBottomPadding);
        } else {
            mMessageTextAndInfoView.setPadding(textLeftPadding,
                    textTopPadding + metadataTopPadding,
                    textRightPadding, textBottomPadding);
        }

        // Update the message row and message bubble views
        setPadding(getPaddingLeft(), messageTopPadding, getPaddingRight(), 0);
        mMessageBubble.setGravity(gravity);

        updateTextAppearance();
    }

    private void updateTextAppearance() {
        final int messageColorResId = (mIncoming ? R.color.message_text_incoming
                : R.color.message_text_outgoing);
        final int timestampColorResId = mIncoming ? R.color.timestamp_text_incoming
                : R.color.timestamp_text_outgoing;
        final int messageColor = getContext().getColor(messageColorResId);

        mMessageTextView.setTextColor(messageColor);
        mMessageTextView.setLinkTextColor(messageColor);
        mStatusTextView.setTextColor(timestampColorResId);
    }

    private static Drawable getTintedDrawable(final Context context, final Drawable drawable,
            final int color) {
        // For some reason occasionally drawables on JB has a null constant state
        final Drawable.ConstantState constantStateDrawable = drawable.getConstantState();
        final Drawable retDrawable = (constantStateDrawable != null)
                ? constantStateDrawable.newDrawable(context.getResources()).mutate()
                : drawable;
        retDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
        return retDrawable;
    }
}
