/*
 * Copyright (C) 2015 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.contacts.editor;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.ContactsContract;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.android.contacts.R;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.model.ValuesDelta;
import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
import com.android.contacts.util.SchedulingUtils;
import com.android.contacts.widget.QuickContactImageView;

/**
 * Displays a photo and calls the host back when the user clicks it.
 */
public class PhotoEditorView extends RelativeLayout implements View.OnClickListener {

    /**
     * Callbacks for the host of this view.
     */
    public interface Listener {

        /**
         * Invoked when the user wants to change their photo.
         */
        void onPhotoEditorViewClicked();
    }

    private Listener mListener;

    private final float mLandscapePhotoRatio;
    private final float mPortraitPhotoRatio;
    private final boolean mIsTwoPanel;

    private final int mActionBarHeight;
    private final int mStatusBarHeight;

    private QuickContactImageView mPhotoImageView;
    private View mPhotoIcon;
    private View mPhotoIconOverlay;
    private View mPhotoTouchInterceptOverlay;
    private MaterialPalette mMaterialPalette;

    private boolean mReadOnly;
    private boolean mIsNonDefaultPhotoBound;

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

    public PhotoEditorView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mLandscapePhotoRatio = getTypedFloat(R.dimen.quickcontact_landscape_photo_ratio);
        mPortraitPhotoRatio = getTypedFloat(R.dimen.editor_portrait_photo_ratio);
        mIsTwoPanel = getResources().getBoolean(R.bool.contacteditor_two_panel);

        final TypedArray styledAttributes = getContext().getTheme().obtainStyledAttributes(
                new int[] { android.R.attr.actionBarSize });
        mActionBarHeight = (int) styledAttributes.getDimension(0, 0);
        styledAttributes.recycle();

        final int resourceId = getResources().getIdentifier(
                "status_bar_height", "dimen", "android");
        mStatusBarHeight = resourceId > 0 ? getResources().getDimensionPixelSize(resourceId) : 0;
    }

    private float getTypedFloat(int resourceId) {
        final TypedValue typedValue = new TypedValue();
        getResources().getValue(resourceId, typedValue, /* resolveRefs =*/ true);
        return typedValue.getFloat();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mPhotoImageView = (QuickContactImageView) findViewById(R.id.photo);
        mPhotoIcon = findViewById(R.id.photo_icon);
        mPhotoIconOverlay = findViewById(R.id.photo_icon_overlay);
        mPhotoTouchInterceptOverlay = findViewById(R.id.photo_touch_intercept_overlay);
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    public void setReadOnly(boolean readOnly) {
        mReadOnly = readOnly;
        if (mReadOnly) {
            mPhotoIcon.setVisibility(View.GONE);
            mPhotoIconOverlay.setVisibility(View.GONE);
            mPhotoTouchInterceptOverlay.setClickable(false);
            mPhotoTouchInterceptOverlay.setContentDescription(getContext().getString(
                    R.string.editor_contact_photo_content_description));
        } else {
            mPhotoIcon.setVisibility(View.VISIBLE);
            mPhotoIconOverlay.setVisibility(View.VISIBLE);
            mPhotoTouchInterceptOverlay.setOnClickListener(this);
            updatePhotoDescription();
        }
    }

    public void setPalette(MaterialPalette palette) {
        mMaterialPalette = palette;
    }

    /**
     * Tries to bind a full size photo or a bitmap loaded from the given ValuesDelta,
     * and falls back to the default avatar, tinted using the given MaterialPalette (if it's not
     * null);
     */
    public void setPhoto(ValuesDelta valuesDelta) {
        // Check if we can update to the full size photo immediately
        final Long photoFileId = EditorUiUtils.getPhotoFileId(valuesDelta);
        if (photoFileId != null) {
            final Uri photoUri = ContactsContract.DisplayPhoto.CONTENT_URI.buildUpon()
                    .appendPath(photoFileId.toString()).build();
            setFullSizedPhoto(photoUri);
            adjustDimensions();
            return;
        }

        // Use the bitmap image from the values delta
        final Bitmap bitmap = EditorUiUtils.getPhotoBitmap(valuesDelta);
        if (bitmap != null) {
            setPhoto(bitmap);
            adjustDimensions();
            return;
        }

        setDefaultPhoto(mMaterialPalette);
        adjustDimensions();
    }

    private void adjustDimensions() {
        // Follow the same logic as MultiShrinkScroll.initialize
        SchedulingUtils.doOnPreDraw(this, /* drawNextFrame =*/ false, new Runnable() {
            @Override
            public void run() {
                final int photoHeight, photoWidth;
                if (mIsTwoPanel) {
                    photoHeight = getContentViewHeight();
                    photoWidth = (int) (photoHeight * mLandscapePhotoRatio);
                } else {
                    // Make the photo slightly shorter that it is wide
                    photoWidth = getContentViewWidth();
                    photoHeight = (int) (photoWidth / mPortraitPhotoRatio);
                }
                final ViewGroup.LayoutParams layoutParams = getLayoutParams();
                layoutParams.height = photoHeight;
                layoutParams.width = photoWidth;
                setLayoutParams(layoutParams);
            }
        });
    }

    private int getContentViewWidth() {
        final Activity activity = (Activity) getContext();
        final DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

    // We're calculating the height the hard way because using the height of the content view
    // (found using android.view.Window.ID_ANDROID_CONTENT) with the soft keyboard up when
    // going from portrait to landscape mode results in a very small height value.
    // See b/20526470
    private int getContentViewHeight() {
        final Activity activity = (Activity) getContext();
        final DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.heightPixels - mActionBarHeight - mStatusBarHeight;
    }

    /**
     * Whether a removable, non-default photo is bound to this view.
     */
    public boolean isWritablePhotoSet() {
        return !mReadOnly && mIsNonDefaultPhotoBound;
    }

    /**
     * Binds the given bitmap.
     */
    private void setPhoto(Bitmap bitmap) {
        mPhotoImageView.setImageBitmap(bitmap);
        mIsNonDefaultPhotoBound = true;
        updatePhotoDescription();
    }

    private void setDefaultPhoto(MaterialPalette materialPalette) {
        mIsNonDefaultPhotoBound = false;
        updatePhotoDescription();
        EditorUiUtils.setDefaultPhoto(mPhotoImageView, getResources(), materialPalette);
    }

    private void updatePhotoDescription() {
        mPhotoTouchInterceptOverlay.setContentDescription(getContext().getString(
                mIsNonDefaultPhotoBound
                        ? R.string.editor_change_photo_content_description
                        : R.string.editor_add_photo_content_description));
    }
    /**
     * Binds a full size photo loaded from the given Uri.
     */
    public void setFullSizedPhoto(Uri photoUri) {
        EditorUiUtils.loadPhoto(ContactPhotoManager.getInstance(getContext()),
                mPhotoImageView, photoUri);
        mIsNonDefaultPhotoBound = true;
        updatePhotoDescription();
    }

    /**
     * Removes the current bound photo bitmap.
     */
    public void removePhoto() {
        setDefaultPhoto(mMaterialPalette);
    }

    @Override
    public void onClick(View view) {
        if (mListener != null) {
            mListener.onPhotoEditorViewClicked();
        }
    }
}
