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

import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;

import com.android.printspooler.R;

/**
 * This class is a layout manager for the print screen. It has a sliding
 * area that contains the print options. If the sliding area is open the
 * print options are visible and if it is closed a summary of the print
 * job is shown. Under the sliding area there is a place for putting
 * arbitrary content such as preview, error message, progress indicator,
 * etc. The sliding area is covering the content holder under it when
 * the former is opened.
 */
@SuppressWarnings("unused")
public final class PrintContentView extends ViewGroup implements View.OnClickListener {
    private static final int FIRST_POINTER_ID = 0;

    private static final int ALPHA_MASK = 0xff000000;
    private static final int ALPHA_SHIFT = 24;

    private static final int COLOR_MASK = 0xffffff;

    private final ViewDragHelper mDragger;

    private final int mScrimColor;

    private View mStaticContent;
    private ViewGroup mSummaryContent;
    private View mDynamicContent;

    private View mDraggableContent;
    private View mPrintButton;
    private View mMoreOptionsButton;
    private ViewGroup mOptionsContainer;

    private View mEmbeddedContentContainer;
    private View mEmbeddedContentScrim;

    private View mExpandCollapseHandle;
    private View mExpandCollapseIcon;

    private int mClosedOptionsOffsetY;
    private int mCurrentOptionsOffsetY = Integer.MIN_VALUE;

    private OptionsStateChangeListener mOptionsStateChangeListener;

    private OptionsStateController mOptionsStateController;

    private int mOldDraggableHeight;

    private float mDragProgress;

    public interface OptionsStateChangeListener {
        public void onOptionsOpened();
        public void onOptionsClosed();
    }

    public interface OptionsStateController {
        public boolean canOpenOptions();
        public boolean canCloseOptions();
    }

    public PrintContentView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mDragger = ViewDragHelper.create(this, new DragCallbacks());

        mScrimColor = context.getColor(R.color.print_preview_scrim_color);

        // The options view is sliding under the static header but appears
        // after it in the layout, so we will draw in opposite order.
        setChildrenDrawingOrderEnabled(true);
    }

    public void setOptionsStateChangeListener(OptionsStateChangeListener listener) {
        mOptionsStateChangeListener = listener;
    }

    public void setOpenOptionsController(OptionsStateController controller) {
        mOptionsStateController = controller;
    }

    public boolean isOptionsOpened() {
        return mCurrentOptionsOffsetY == 0;
    }

    private boolean isOptionsClosed() {
        return mCurrentOptionsOffsetY == mClosedOptionsOffsetY;
    }

    public void openOptions() {
        if (isOptionsOpened()) {
            return;
        }
        mDragger.smoothSlideViewTo(mDynamicContent, mDynamicContent.getLeft(),
                getOpenedOptionsY());
        invalidate();
    }

    public void closeOptions() {
        if (isOptionsClosed()) {
            return;
        }
        mDragger.smoothSlideViewTo(mDynamicContent, mDynamicContent.getLeft(),
                getClosedOptionsY());
        invalidate();
    }

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        return childCount - i - 1;
    }

    @Override
    protected void onFinishInflate() {
        mStaticContent = findViewById(R.id.static_content);
        mSummaryContent = findViewById(R.id.summary_content);
        mDynamicContent = findViewById(R.id.dynamic_content);
        mDraggableContent = findViewById(R.id.draggable_content);
        mPrintButton = findViewById(R.id.print_button);
        mMoreOptionsButton = findViewById(R.id.more_options_button);
        mOptionsContainer = findViewById(R.id.options_container);
        mEmbeddedContentContainer = findViewById(R.id.embedded_content_container);
        mEmbeddedContentScrim = findViewById(R.id.embedded_content_scrim);
        mExpandCollapseHandle = findViewById(R.id.expand_collapse_handle);
        mExpandCollapseIcon = findViewById(R.id.expand_collapse_icon);

        mExpandCollapseHandle.setOnClickListener(this);
        mSummaryContent.setOnClickListener(this);

        // Make sure we start in a closed options state.
        onDragProgress(1.0f);

        // The framework gives focus to the frist focusable and we
        // do not want that, hence we will take focus instead.
        setFocusableInTouchMode(true);
    }

    @Override
    public void focusableViewAvailable(View v) {
        // The framework gives focus to the frist focusable and we
        // do not want that, hence do not announce new focusables.
        return;
    }

    @Override
    public void onClick(View view) {
        if (view == mExpandCollapseHandle || view == mSummaryContent) {
            if (isOptionsClosed() && mOptionsStateController.canOpenOptions()) {
                openOptions();
            } else if (isOptionsOpened() && mOptionsStateController.canCloseOptions()) {
                closeOptions();
            } // else in open/close progress do nothing.
        } else if (view == mEmbeddedContentScrim) {
            if (isOptionsOpened() && mOptionsStateController.canCloseOptions()) {
                closeOptions();
            }
        }
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        /* do nothing */
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragger.processTouchEvent(event);
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return mDragger.shouldInterceptTouchEvent(event)
                || super.onInterceptTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        if (mDragger.continueSettling(true)) {
            postInvalidateOnAnimation();
        }
    }

    private int computeScrimColor() {
        final int baseAlpha = (mScrimColor & ALPHA_MASK) >>> ALPHA_SHIFT;
        final int adjustedAlpha = (int) (baseAlpha * (1 - mDragProgress));
        return adjustedAlpha << ALPHA_SHIFT | (mScrimColor & COLOR_MASK);
    }

    private int getOpenedOptionsY() {
        return mStaticContent.getBottom();
    }

    private int getClosedOptionsY() {
        return getOpenedOptionsY() + mClosedOptionsOffsetY;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final boolean wasOpened = isOptionsOpened();

        measureChild(mStaticContent, widthMeasureSpec, heightMeasureSpec);

        if (mSummaryContent.getVisibility() != View.GONE) {
            measureChild(mSummaryContent, widthMeasureSpec, heightMeasureSpec);
        }

        measureChild(mDynamicContent, widthMeasureSpec, heightMeasureSpec);

        measureChild(mPrintButton, widthMeasureSpec, heightMeasureSpec);

        // The height of the draggable content may change and if that happens
        // we have to adjust the sliding area closed state offset.
        mClosedOptionsOffsetY = mSummaryContent.getMeasuredHeight()
                - mDraggableContent.getMeasuredHeight();

        if (mCurrentOptionsOffsetY == Integer.MIN_VALUE) {
            mCurrentOptionsOffsetY = mClosedOptionsOffsetY;
        }

        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        // The content host must be maximally large size that fits entirely
        // on the screen when the options are collapsed.
        ViewGroup.LayoutParams params = mEmbeddedContentContainer.getLayoutParams();
        params.height = heightSize - mStaticContent.getMeasuredHeight()
                - mSummaryContent.getMeasuredHeight() - mDynamicContent.getMeasuredHeight()
                + mDraggableContent.getMeasuredHeight();

        // The height of the draggable content may change and if that happens
        // we have to adjust the current offset to ensure the sliding area is
        // at the correct position.
        if (mOldDraggableHeight != mDraggableContent.getMeasuredHeight()) {
            if (mOldDraggableHeight != 0) {
                mCurrentOptionsOffsetY = wasOpened ? 0 : mClosedOptionsOffsetY;
            }
            mOldDraggableHeight = mDraggableContent.getMeasuredHeight();
        }

        // The content host can grow vertically as much as needed - we will be covering it.
        final int hostHeightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
        measureChild(mEmbeddedContentContainer, widthMeasureSpec, hostHeightMeasureSpec);

        setMeasuredDimension(resolveSize(MeasureSpec.getSize(widthMeasureSpec), widthMeasureSpec),
                resolveSize(heightSize, heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mStaticContent.layout(left, top, right, mStaticContent.getMeasuredHeight());

        if (mSummaryContent.getVisibility() != View.GONE) {
            mSummaryContent.layout(left, mStaticContent.getMeasuredHeight(), right,
                    mStaticContent.getMeasuredHeight() + mSummaryContent.getMeasuredHeight());
        }

        final int dynContentTop = mStaticContent.getMeasuredHeight() + mCurrentOptionsOffsetY;
        final int dynContentBottom = dynContentTop + mDynamicContent.getMeasuredHeight();

        mDynamicContent.layout(left, dynContentTop, right, dynContentBottom);

        MarginLayoutParams params = (MarginLayoutParams) mPrintButton.getLayoutParams();

        final int printButtonLeft;
        if (getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
            printButtonLeft = right - mPrintButton.getMeasuredWidth() - params.getMarginStart();
        } else {
            printButtonLeft = left + params.getMarginStart();
        }
        final int printButtonTop = dynContentBottom - mPrintButton.getMeasuredHeight() / 2;
        final int printButtonRight = printButtonLeft + mPrintButton.getMeasuredWidth();
        final int printButtonBottom = printButtonTop + mPrintButton.getMeasuredHeight();

        mPrintButton.layout(printButtonLeft, printButtonTop, printButtonRight, printButtonBottom);

        final int embContentTop = mStaticContent.getMeasuredHeight() + mClosedOptionsOffsetY
                + mDynamicContent.getMeasuredHeight();
        final int embContentBottom = embContentTop + mEmbeddedContentContainer.getMeasuredHeight();

        mEmbeddedContentContainer.layout(left, embContentTop, right, embContentBottom);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new ViewGroup.MarginLayoutParams(getContext(), attrs);
    }

    private void onDragProgress(float progress) {
        if (Float.compare(mDragProgress, progress) == 0) {
            return;
        }

        if ((mDragProgress == 0 && progress > 0)
                || (mDragProgress == 1.0f && progress < 1.0f)) {
            mSummaryContent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            mDraggableContent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            mMoreOptionsButton.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            ensureImeClosedAndInputFocusCleared();
        }
        if ((mDragProgress > 0 && progress == 0)
                || (mDragProgress < 1.0f && progress == 1.0f)) {
            mSummaryContent.setLayerType(View.LAYER_TYPE_NONE, null);
            mDraggableContent.setLayerType(View.LAYER_TYPE_NONE, null);
            mMoreOptionsButton.setLayerType(View.LAYER_TYPE_NONE, null);
            mMoreOptionsButton.setLayerType(View.LAYER_TYPE_NONE, null);
        }

        mDragProgress = progress;

        mSummaryContent.setAlpha(progress);

        final float inverseAlpha = 1.0f - progress;
        mOptionsContainer.setAlpha(inverseAlpha);
        mMoreOptionsButton.setAlpha(inverseAlpha);

        mEmbeddedContentScrim.setBackgroundColor(computeScrimColor());
        if (progress == 0) {
            if (mOptionsStateChangeListener != null) {
                mOptionsStateChangeListener.onOptionsOpened();
            }
            mExpandCollapseHandle.setContentDescription(
                    mContext.getString(R.string.collapse_handle));
            announceForAccessibility(mContext.getString(R.string.print_options_expanded));
            mSummaryContent.setVisibility(View.GONE);
            mEmbeddedContentScrim.setOnClickListener(this);
            mExpandCollapseIcon.setBackgroundResource(R.drawable.ic_expand_less);
        } else {
            mSummaryContent.setVisibility(View.VISIBLE);
        }

        if (progress == 1.0f) {
            if (mOptionsStateChangeListener != null) {
                mOptionsStateChangeListener.onOptionsClosed();
            }
            mExpandCollapseHandle.setContentDescription(
                    mContext.getString(R.string.expand_handle));
            announceForAccessibility(mContext.getString(R.string.print_options_collapsed));
            if (mMoreOptionsButton.getVisibility() != View.GONE) {
                mMoreOptionsButton.setVisibility(View.INVISIBLE);
            }
            mDraggableContent.setVisibility(View.INVISIBLE);
            // If we change the scrim visibility the dimming is lagging
            // and is janky. Now it is there but transparent, doing nothing.
            mEmbeddedContentScrim.setOnClickListener(null);
            mEmbeddedContentScrim.setClickable(false);
            mExpandCollapseIcon.setBackgroundResource(
                    com.android.internal.R.drawable.ic_expand_more);
        } else {
            if (mMoreOptionsButton.getVisibility() != View.GONE) {
                mMoreOptionsButton.setVisibility(View.VISIBLE);
            }
            mDraggableContent.setVisibility(View.VISIBLE);
        }
    }

    private void ensureImeClosedAndInputFocusCleared() {
        View focused = findFocus();

        if (focused != null && focused.isFocused()) {
            InputMethodManager imm = (InputMethodManager) mContext.getSystemService(
                    Context.INPUT_METHOD_SERVICE);
            if (imm.isActive(focused)) {
                imm.hideSoftInputFromWindow(getWindowToken(), 0);
            }
            focused.clearFocus();
        }
    }

    private final class DragCallbacks extends ViewDragHelper.Callback {
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            if (isOptionsOpened() && !mOptionsStateController.canCloseOptions()
                    || isOptionsClosed() && !mOptionsStateController.canOpenOptions()) {
                return false;
            }
            return child == mDynamicContent && pointerId == FIRST_POINTER_ID;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            if ((isOptionsClosed() || isOptionsClosed()) && dy <= 0) {
                return;
            }

            mCurrentOptionsOffsetY += dy;
            final float progress = ((float) top - getOpenedOptionsY())
                    / (getClosedOptionsY() - getOpenedOptionsY());

            mPrintButton.offsetTopAndBottom(dy);

            mDraggableContent.notifySubtreeAccessibilityStateChangedIfNeeded();

            onDragProgress(progress);
        }

        @Override
        public void onViewReleased(View child, float velocityX, float velocityY) {
            final int childTop = child.getTop();

            final int openedOptionsY = getOpenedOptionsY();
            final int closedOptionsY = getClosedOptionsY();

            if (childTop == openedOptionsY || childTop == closedOptionsY) {
                return;
            }

            final int halfRange = closedOptionsY + (openedOptionsY - closedOptionsY) / 2;
            if (childTop < halfRange) {
                mDragger.smoothSlideViewTo(child, child.getLeft(), closedOptionsY);
            } else {
                mDragger.smoothSlideViewTo(child, child.getLeft(), openedOptionsY);
            }

            invalidate();
        }

        @Override
        public int getOrderedChildIndex(int index) {
            return getChildCount() - index - 1;
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            return mDraggableContent.getHeight();
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            final int staticOptionBottom = mStaticContent.getBottom();
            return Math.max(Math.min(top, getOpenedOptionsY()), getClosedOptionsY());
        }
    }
}
