/*
 * Copyright (C) 2012 Google Inc.
 * Licensed to 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.mail.browse;

import android.content.Context;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ListView;
import android.widget.ScrollView;

import com.android.mail.R;
import com.android.mail.browse.ScrollNotifier.ScrollListener;
import com.android.mail.providers.UIProvider;
import com.android.mail.ui.ConversationViewFragment;
import com.android.mail.utils.DequeMap;
import com.android.mail.utils.InputSmoother;
import com.android.mail.utils.LogUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import java.util.List;
import java.util.Set;

/**
 * A specialized ViewGroup container for conversation view. It is designed to contain a single
 * {@link WebView} and a number of overlay views that draw on top of the WebView. In the Mail app,
 * the WebView contains all HTML message bodies in a conversation, and the overlay views are the
 * subject view, message headers, and attachment views. The WebView does all scroll handling, and
 * this container manages scrolling of the overlay views so that they move in tandem.
 *
 * <h5>INPUT HANDLING</h5>
 * Placing the WebView in the same container as the overlay views means we don't have to do a lot of
 * manual manipulation of touch events. We do have a
 * {@link #forwardFakeMotionEvent(MotionEvent, int)} method that deals with one WebView
 * idiosyncrasy: it doesn't react well when touch MOVE events stream in without a preceding DOWN.
 *
 * <h5>VIEW RECYCLING</h5>
 * Normally, it would make sense to put all overlay views into a {@link ListView}. But this view
 * sandwich has unique characteristics: the list items are scrolled based on an external controller,
 * and we happen to know all of the overlay positions up front. So it didn't make sense to shoehorn
 * a ListView in and instead, we rolled our own view recycler by borrowing key details from
 * ListView and AbsListView.<br/><br/>
 *
 * There is one additional constraint with the recycling: since scroll
 * notifications happen during the WebView's draw, we do not remove and re-add views for recycling.
 * Instead, we simply move the views off-screen and add them to our recycle cache. When the views
 * are reused, they are simply moved back on screen instead of added. This practice
 * circumvents the issues found when views are added or removed during draw (which results in
 * elements not being drawn and other visual oddities). See b/10994303 for more details.
 */
public class ConversationContainer extends ViewGroup implements ScrollListener {
    private static final String TAG = ConversationViewFragment.LAYOUT_TAG;

    private static final int[] BOTTOM_LAYER_VIEW_IDS = {
        R.id.conversation_webview
    };

    private static final int[] TOP_LAYER_VIEW_IDS = {
        R.id.conversation_topmost_overlay
    };

    /**
     * Maximum scroll speed (in dp/sec) at which the snap header animation will draw.
     * Anything faster than that, and drawing it creates visual artifacting (wagon-wheel effect).
     */
    private static final float SNAP_HEADER_MAX_SCROLL_SPEED = 600f;

    private ConversationAccountController mAccountController;
    private ConversationViewAdapter mOverlayAdapter;
    private OverlayPosition[] mOverlayPositions;
    private ConversationWebView mWebView;
    private SnapHeader mSnapHeader;

    private final List<View> mNonScrollingChildren = Lists.newArrayList();

    /**
     * Current document zoom scale per {@link WebView#getScale()}. This is the ratio of actual
     * screen pixels to logical WebView HTML pixels. We use it to convert from one to the other.
     */
    private float mScale;
    /**
     * Set to true upon receiving the first touch event. Used to help reject invalid WebView scale
     * values.
     */
    private boolean mTouchInitialized;

    /**
     * System touch-slop distance per {@link ViewConfiguration#getScaledTouchSlop()}.
     */
    private final int mTouchSlop;
    /**
     * Current scroll position, as dictated by the background {@link WebView}.
     */
    private int mOffsetY;
    /**
     * Original pointer Y for slop calculation.
     */
    private float mLastMotionY;
    /**
     * Original pointer ID for slop calculation.
     */
    private int mActivePointerId;
    /**
     * Track pointer up/down state to know whether to send a make-up DOWN event to WebView.
     * WebView internal logic requires that a stream of {@link MotionEvent#ACTION_MOVE} events be
     * preceded by a {@link MotionEvent#ACTION_DOWN} event.
     */
    private boolean mTouchIsDown = false;
    /**
     * Remember if touch interception was triggered on a {@link MotionEvent#ACTION_POINTER_DOWN},
     * so we can send a make-up event in {@link #onTouchEvent(MotionEvent)}.
     */
    private boolean mMissedPointerDown;

    /**
     * A recycler that holds removed scrap views, organized by integer item view type. All views
     * in this data structure should be removed from their view parent prior to insertion.
     */
    private final DequeMap<Integer, View> mScrapViews = new DequeMap<Integer, View>();

    /**
     * The current set of overlay views in the view hierarchy. Looking through this map is faster
     * than traversing the view hierarchy.
     * <p>
     * WebView sometimes notifies of scroll changes during a draw (or display list generation), when
     * it's not safe to detach view children because ViewGroup is in the middle of iterating over
     * its child array. So we remove any child from this list immediately and queue up a task to
     * detach it later. Since nobody other than the detach task references that view in the
     * meantime, we don't need any further checks or synchronization.
     * <p>
     * We keep {@link OverlayView} wrappers instead of bare views so that when it's time to dispose
     * of all views (on data set or adapter change), we can at least recycle them into the typed
     * scrap piles for later reuse.
     */
    private final SparseArray<OverlayView> mOverlayViews;

    private int mWidthMeasureSpec;

    private boolean mDisableLayoutTracing;

    private final InputSmoother mVelocityTracker;

    private final DataSetObserver mAdapterObserver = new AdapterObserver();

    /**
     * The adapter index of the lowest overlay item that is above the top of the screen and reports
     * {@link ConversationOverlayItem#canPushSnapHeader()}. We calculate this after a pass through
     * {@link #positionOverlays}.
     *
     */
    private int mSnapIndex;

    private boolean mSnapEnabled;

    /**
     * A View that fills the remaining vertical space when the overlays do not take
     * up the entire container. Otherwise, a card-like bottom white space appears.
     */
    private View mAdditionalBottomBorder;

    /**
     * A flag denoting whether the fake bottom border has been added to the container.
     */
    private boolean mAdditionalBottomBorderAdded;

    /**
     * An int containing the potential top value for the additional bottom border.
     * If this value is less than the height of the scroll container, the additional
     * bottom border will be drawn.
     */
    private int mAdditionalBottomBorderOverlayTop;

    /**
     * Child views of this container should implement this interface to be notified when they are
     * being detached.
     */
    public interface DetachListener {
        /**
         * Called on a child view when it is removed from its parent as part of
         * {@link ConversationContainer} view recycling.
         */
        void onDetachedFromParent();
    }

    public static class OverlayPosition {
        public final int top;
        public final int bottom;

        public OverlayPosition(int top, int bottom) {
            this.top = top;
            this.bottom = bottom;
        }
    }

    private static class OverlayView {
        public View view;
        int itemType;

        public OverlayView(View view, int itemType) {
            this.view = view;
            this.itemType = itemType;
        }
    }

    public ConversationContainer(Context c) {
        this(c, null);
    }

    public ConversationContainer(Context c, AttributeSet attrs) {
        super(c, attrs);

        mOverlayViews = new SparseArray<OverlayView>();

        mVelocityTracker = new InputSmoother(c);

        mTouchSlop = ViewConfiguration.get(c).getScaledTouchSlop();

        // Disabling event splitting fixes pinch-zoom when the first pointer goes down on the
        // WebView and the second pointer goes down on an overlay view.
        // Intercepting ACTION_POINTER_DOWN events allows pinch-zoom to work when the first pointer
        // goes down on an overlay view.
        setMotionEventSplittingEnabled(false);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mWebView = (ConversationWebView) findViewById(R.id.conversation_webview);
        mWebView.addScrollListener(this);

        for (int id : BOTTOM_LAYER_VIEW_IDS) {
            mNonScrollingChildren.add(findViewById(id));
        }
        for (int id : TOP_LAYER_VIEW_IDS) {
            mNonScrollingChildren.add(findViewById(id));
        }
    }

    public void setupSnapHeader() {
        mSnapHeader = (SnapHeader) findViewById(R.id.snap_header);
        mSnapHeader.setSnappy();
    }

    public SnapHeader getSnapHeader() {
        return mSnapHeader;
    }

    public void setOverlayAdapter(ConversationViewAdapter a) {
        if (mOverlayAdapter != null) {
            mOverlayAdapter.unregisterDataSetObserver(mAdapterObserver);
            clearOverlays();
        }
        mOverlayAdapter = a;
        if (mOverlayAdapter != null) {
            mOverlayAdapter.registerDataSetObserver(mAdapterObserver);
        }
    }

    public void setAccountController(ConversationAccountController controller) {
        mAccountController = controller;

//        mSnapEnabled = isSnapEnabled();
        mSnapEnabled = false; // TODO - re-enable when dogfooders howl
    }

    /**
     * Re-bind any existing views that correspond to the given adapter positions.
     *
     */
    public void onOverlayModelUpdate(List<Integer> affectedAdapterPositions) {
        for (Integer i : affectedAdapterPositions) {
            final ConversationOverlayItem item = mOverlayAdapter.getItem(i);
            final OverlayView overlay = mOverlayViews.get(i);
            if (overlay != null && overlay.view != null && item != null) {
                item.onModelUpdated(overlay.view);
            }
            // update the snap header too, but only it's showing if the current item
            if (i == mSnapIndex && mSnapHeader.isBoundTo(item)) {
                mSnapHeader.refresh();
            }
        }
    }

    /**
     * Return an overlay view for the given adapter item, or null if no matching view is currently
     * visible. This can happen as you scroll away from an overlay view.
     *
     */
    public View getViewForItem(ConversationOverlayItem item) {
        if (mOverlayAdapter == null) {
            return null;
        }
        View result = null;
        int adapterPos = -1;
        for (int i = 0, len = mOverlayAdapter.getCount(); i < len; i++) {
            if (mOverlayAdapter.getItem(i) == item) {
                adapterPos = i;
                break;
            }
        }
        if (adapterPos != -1) {
            final OverlayView overlay = mOverlayViews.get(adapterPos);
            if (overlay != null) {
                result = overlay.view;
            }
        }
        return result;
    }

    private void clearOverlays() {
        for (int i = 0, len = mOverlayViews.size(); i < len; i++) {
            detachOverlay(mOverlayViews.valueAt(i), true /* removeFromContainer */);
        }
        mOverlayViews.clear();
    }

    private void onDataSetChanged() {
        // Recycle all views and re-bind them according to the current set of spacer coordinates.
        // This essentially resets the overlay views and re-renders them.
        // It's fast enough that it's okay to re-do all views on any small change, as long as
        // the change isn't too frequent (< ~1Hz).

        clearOverlays();
        // also unbind the snap header view, so this "reset" causes the snap header to re-create
        // its view, just like all other headers
        mSnapHeader.unbind();

        // also clear out the additional bottom border
        removeViewInLayout(mAdditionalBottomBorder);
        mAdditionalBottomBorderAdded = false;

//        mSnapEnabled = isSnapEnabled();
        mSnapEnabled = false; // TODO - re-enable when dogfooders howl
        positionOverlays(mOffsetY, false /* postAddView */);
    }

    private void forwardFakeMotionEvent(MotionEvent original, int newAction) {
        MotionEvent newEvent = MotionEvent.obtain(original);
        newEvent.setAction(newAction);
        mWebView.onTouchEvent(newEvent);
        LogUtils.v(TAG, "in Container.OnTouch. fake: action=%d x/y=%f/%f pointers=%d",
                newEvent.getActionMasked(), newEvent.getX(), newEvent.getY(),
                newEvent.getPointerCount());
    }

    /**
     * Touch slop code was copied from {@link ScrollView#onInterceptTouchEvent(MotionEvent)}.
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (!mTouchInitialized) {
            mTouchInitialized = true;
        }

        // no interception when WebView handles the first DOWN
        if (mWebView.isHandlingTouch()) {
            return false;
        }

        boolean intercept = false;
        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_POINTER_DOWN:
                LogUtils.d(TAG, "Container is intercepting non-primary touch!");
                intercept = true;
                mMissedPointerDown = true;
                requestDisallowInterceptTouchEvent(true);
                break;

            case MotionEvent.ACTION_DOWN:
                mLastMotionY = ev.getY();
                mActivePointerId = ev.getPointerId(0);
                break;

            case MotionEvent.ACTION_MOVE:
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float y = ev.getY(pointerIndex);
                final int yDiff = (int) Math.abs(y - mLastMotionY);
                if (yDiff > mTouchSlop) {
                    mLastMotionY = y;
                    intercept = true;
                }
                break;
        }

//        LogUtils.v(TAG, "in Container.InterceptTouch. action=%d x/y=%f/%f pointers=%d result=%s",
//                ev.getActionMasked(), ev.getX(), ev.getY(), ev.getPointerCount(), intercept);
        return intercept;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getActionMasked();

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            mTouchIsDown = false;
        } else if (!mTouchIsDown &&
                (action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_POINTER_DOWN)) {

            forwardFakeMotionEvent(ev, MotionEvent.ACTION_DOWN);
            if (mMissedPointerDown) {
                forwardFakeMotionEvent(ev, MotionEvent.ACTION_POINTER_DOWN);
                mMissedPointerDown = false;
            }

            mTouchIsDown = true;
        }

        final boolean webViewResult = mWebView.onTouchEvent(ev);

//        LogUtils.v(TAG, "in Container.OnTouch. action=%d x/y=%f/%f pointers=%d",
//                ev.getActionMasked(), ev.getX(), ev.getY(), ev.getPointerCount());
        return webViewResult;
    }

    @Override
    public void onNotifierScroll(final int y) {
        mVelocityTracker.onInput(y);
        mDisableLayoutTracing = true;
        positionOverlays(y, true /* postAddView */); // post the addView since we're in draw code
        mDisableLayoutTracing = false;
    }

    /**
     * Positions the overlays given an updated y position for the container.
     * @param y the current top position on screen
     * @param postAddView If {@code true}, posts all calls to
     *                    {@link #addViewInLayoutWrapper(android.view.View, boolean)}
     *                    to the UI thread rather than adding it immediately. If {@code false},
     *                    calls {@link #addViewInLayoutWrapper(android.view.View, boolean)}
     *                    immediately.
     */
    private void positionOverlays(int y, boolean postAddView) {
        mOffsetY = y;

        /*
         * The scale value that WebView reports is inaccurate when measured during WebView
         * initialization. This bug is present in ICS, so to work around it, we ignore all
         * reported values and use a calculated expected value from ConversationWebView instead.
         * Only when the user actually begins to touch the view (to, say, begin a zoom) do we begin
         * to pay attention to WebView-reported scale values.
         */
        if (mTouchInitialized) {
            mScale = mWebView.getScale();
        } else if (mScale == 0) {
            mScale = mWebView.getInitialScale();
        }
        traceLayout("in positionOverlays, raw scale=%f, effective scale=%f", mWebView.getScale(),
                mScale);

        if (mOverlayPositions == null || mOverlayAdapter == null) {
            return;
        }

        // recycle scrolled-off views and add newly visible views

        // we want consecutive spacers/overlays to stack towards the bottom
        // so iterate from the bottom of the conversation up
        // starting with the last spacer bottom and the last adapter item, position adapter views
        // in a single stack until you encounter a non-contiguous expanded message header,
        // then decrement to the next spacer.

        traceLayout("IN positionOverlays, spacerCount=%d overlayCount=%d", mOverlayPositions.length,
                mOverlayAdapter.getCount());

        mSnapIndex = -1;
        mAdditionalBottomBorderOverlayTop = 0;

        int adapterLoopIndex = mOverlayAdapter.getCount() - 1;
        int spacerIndex = mOverlayPositions.length - 1;
        while (spacerIndex >= 0 && adapterLoopIndex >= 0) {

            final int spacerTop = getOverlayTop(spacerIndex);
            final int spacerBottom = getOverlayBottom(spacerIndex);

            final boolean flip;
            final int flipOffset;
            final int forceGravity;
            // flip direction from bottom->top to top->bottom traversal on the very first spacer
            // to facilitate top-aligned headers at spacer index = 0
            if (spacerIndex == 0) {
                flip = true;
                flipOffset = adapterLoopIndex;
                forceGravity = Gravity.TOP;
            } else {
                flip = false;
                flipOffset = 0;
                forceGravity = Gravity.NO_GRAVITY;
            }

            int adapterIndex = flip ? flipOffset - adapterLoopIndex : adapterLoopIndex;

            // always place at least one overlay per spacer
            ConversationOverlayItem adapterItem = mOverlayAdapter.getItem(adapterIndex);

            OverlayPosition itemPos = calculatePosition(adapterItem, spacerTop, spacerBottom,
                    forceGravity);

            traceLayout("in loop, spacer=%d overlay=%d t/b=%d/%d (%s)", spacerIndex, adapterIndex,
                    itemPos.top, itemPos.bottom, adapterItem);
            positionOverlay(adapterIndex, itemPos.top, itemPos.bottom, postAddView);

            // and keep stacking overlays unconditionally if we are on the first spacer, or as long
            // as overlays are contiguous
            while (--adapterLoopIndex >= 0) {
                adapterIndex = flip ? flipOffset - adapterLoopIndex : adapterLoopIndex;
                adapterItem = mOverlayAdapter.getItem(adapterIndex);
                if (spacerIndex > 0 && !adapterItem.isContiguous()) {
                    // advance to the next spacer, but stay on this adapter item
                    break;
                }

                // place this overlay in the region of the spacer above or below the last item,
                // depending on direction of iteration
                final int regionTop = flip ? itemPos.bottom : spacerTop;
                final int regionBottom = flip ? spacerBottom : itemPos.top;
                itemPos = calculatePosition(adapterItem, regionTop, regionBottom, forceGravity);

                traceLayout("in contig loop, spacer=%d overlay=%d t/b=%d/%d (%s)", spacerIndex,
                        adapterIndex, itemPos.top, itemPos.bottom, adapterItem);
                positionOverlay(adapterIndex, itemPos.top, itemPos.bottom, postAddView);
            }

            spacerIndex--;
        }

        positionSnapHeader(mSnapIndex);
        positionAdditionalBottomBorder(postAddView);
    }

    /**
     * Adds an additional bottom border to the overlay views in case
     * the overlays do not fill the entire screen.
     */
    private void positionAdditionalBottomBorder(boolean postAddView) {
        final int lastBottom = mAdditionalBottomBorderOverlayTop;
        final int containerHeight = webPxToScreenPx(mWebView.getContentHeight());
        final int speculativeHeight = containerHeight - lastBottom;
        if (speculativeHeight > 0) {
            if (mAdditionalBottomBorder == null) {
                mAdditionalBottomBorder = mOverlayAdapter.getLayoutInflater().inflate(
                        R.layout.fake_bottom_border, this, false);
            }

            setAdditionalBottomBorderHeight(speculativeHeight);

            if (!mAdditionalBottomBorderAdded) {
                addViewInLayoutWrapper(mAdditionalBottomBorder, postAddView);
                mAdditionalBottomBorderAdded = true;
            }

            measureOverlayView(mAdditionalBottomBorder);
            layoutOverlay(mAdditionalBottomBorder, lastBottom, containerHeight);
        } else {
            if (mAdditionalBottomBorder != null && mAdditionalBottomBorderAdded) {
                if (postAddView) {
                    post(mRemoveBorderRunnable);
                } else {
                    mRemoveBorderRunnable.run();
                }
                mAdditionalBottomBorderAdded = false;
            }
        }
    }

    private final RemoveBorderRunnable mRemoveBorderRunnable = new RemoveBorderRunnable();

    private void setAdditionalBottomBorderHeight(int speculativeHeight) {
        LayoutParams params = mAdditionalBottomBorder.getLayoutParams();
        params.height = speculativeHeight;
        mAdditionalBottomBorder.setLayoutParams(params);
    }

    private static OverlayPosition calculatePosition(final ConversationOverlayItem adapterItem,
            final int withinTop, final int withinBottom, final int forceGravity) {
        if (adapterItem.getHeight() == 0) {
            // "place" invisible items at the bottom of their region to stay consistent with the
            // stacking algorithm in positionOverlays(), unless gravity is forced to the top
            final int y = (forceGravity == Gravity.TOP) ? withinTop : withinBottom;
            return new OverlayPosition(y, y);
        }

        final int v = ((forceGravity != Gravity.NO_GRAVITY) ?
                forceGravity : adapterItem.getGravity()) & Gravity.VERTICAL_GRAVITY_MASK;
        switch (v) {
            case Gravity.BOTTOM:
                return new OverlayPosition(withinBottom - adapterItem.getHeight(), withinBottom);
            case Gravity.TOP:
                return new OverlayPosition(withinTop, withinTop + adapterItem.getHeight());
            default:
                throw new UnsupportedOperationException("unsupported gravity: " + v);
        }
    }

    /**
     * Executes a measure pass over the specified child overlay view and returns the measured
     * height. The measurement uses whatever the current container's width measure spec is.
     * This method ignores view visibility and returns the height that the view would be if visible.
     *
     * @param overlayView an overlay view to measure. does not actually have to be attached yet.
     * @return height that the view would be if it was visible
     */
    public int measureOverlay(View overlayView) {
        measureOverlayView(overlayView);
        return overlayView.getMeasuredHeight();
    }

    /**
     * Copied/stolen from {@link ListView}.
     */
    private void measureOverlayView(View child) {
        MarginLayoutParams p = (MarginLayoutParams) child.getLayoutParams();
        if (p == null) {
            p = (MarginLayoutParams) generateDefaultLayoutParams();
        }

        int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
                getPaddingLeft() + getPaddingRight() + p.leftMargin + p.rightMargin, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    private void onOverlayScrolledOff(final int adapterIndex, final OverlayView overlay,
            int overlayTop, int overlayBottom) {
        // immediately remove this view from the view set so future lookups don't find it
        mOverlayViews.remove(adapterIndex);

        // detach but don't actually remove from the view
        detachOverlay(overlay, false /* removeFromContainer */);

        // push it out of view immediately
        // otherwise this scrolled-off header will continue to draw until the runnable runs
        layoutOverlay(overlay.view, overlayTop, overlayBottom);
    }

    /**
     * Returns an existing scrap view, if available. The view will already be removed from the view
     * hierarchy. This method will not remove the view from the scrap heap.
     *
     */
    public View getScrapView(int type) {
        return mScrapViews.peek(type);
    }

    public void addScrapView(int type, View v) {
        mScrapViews.add(type, v);
        addViewInLayoutWrapper(v, false /* postAddView */);
    }

    private void detachOverlay(OverlayView overlay, boolean removeFromContainer) {
        // Prefer removeViewInLayout over removeView. The typical followup layout pass is unneeded
        // because removing overlay views doesn't affect overall layout.
        if (removeFromContainer) {
            removeViewInLayout(overlay.view);
        }
        mScrapViews.add(overlay.itemType, overlay.view);
        if (overlay.view instanceof DetachListener) {
            ((DetachListener) overlay.view).onDetachedFromParent();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (LogUtils.isLoggable(TAG, LogUtils.DEBUG)) {
            LogUtils.d(TAG, "*** IN header container onMeasure spec for w/h=%s/%s",
                    MeasureSpec.toString(widthMeasureSpec),
                    MeasureSpec.toString(heightMeasureSpec));
        }

        for (View nonScrollingChild : mNonScrollingChildren) {
            if (nonScrollingChild.getVisibility() != GONE) {
                measureChildWithMargins(nonScrollingChild, widthMeasureSpec, 0 /* widthUsed */,
                        heightMeasureSpec, 0 /* heightUsed */);
            }
        }
        mWidthMeasureSpec = widthMeasureSpec;

        // onLayout will re-measure and re-position overlays for the new container size, but the
        // spacer offsets would still need to be updated to have them draw at their new locations.
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        LogUtils.d(TAG, "*** IN header container onLayout");

        for (View nonScrollingChild : mNonScrollingChildren) {
            if (nonScrollingChild.getVisibility() != GONE) {
                final int w = nonScrollingChild.getMeasuredWidth();
                final int h = nonScrollingChild.getMeasuredHeight();

                final MarginLayoutParams lp =
                        (MarginLayoutParams) nonScrollingChild.getLayoutParams();

                final int childLeft = lp.leftMargin;
                final int childTop = lp.topMargin;
                nonScrollingChild.layout(childLeft, childTop, childLeft + w, childTop + h);
            }
        }

        if (mOverlayAdapter != null) {
            // being in a layout pass means overlay children may require measurement,
            // so invalidate them
            for (int i = 0, len = mOverlayAdapter.getCount(); i < len; i++) {
                mOverlayAdapter.getItem(i).invalidateMeasurement();
            }
        }

        positionOverlays(mOffsetY, false /* postAddView */);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    }

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

    @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new MarginLayoutParams(p);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof MarginLayoutParams;
    }

    private int getOverlayTop(int spacerIndex) {
        return webPxToScreenPx(mOverlayPositions[spacerIndex].top);
    }

    private int getOverlayBottom(int spacerIndex) {
        return webPxToScreenPx(mOverlayPositions[spacerIndex].bottom);
    }

    private int webPxToScreenPx(int webPx) {
        // TODO: round or truncate?
        // TODO: refactor and unify with ConversationWebView.webPxToScreenPx()
        return (int) (webPx * mScale);
    }

    private void positionOverlay(
            int adapterIndex, int overlayTopY, int overlayBottomY, boolean postAddView) {
        final OverlayView overlay = mOverlayViews.get(adapterIndex);
        final ConversationOverlayItem item = mOverlayAdapter.getItem(adapterIndex);

        // save off the item's current top for later snap calculations
        item.setTop(overlayTopY);

        // is the overlay visible and does it have non-zero height?
        if (overlayTopY != overlayBottomY && overlayBottomY > mOffsetY
                && overlayTopY < mOffsetY + getHeight()) {
            View overlayView = overlay != null ? overlay.view : null;
            // show and/or move overlay
            if (overlayView == null) {
                overlayView = addOverlayView(adapterIndex, postAddView);
                ViewCompat.setLayoutDirection(overlayView, ViewCompat.getLayoutDirection(this));
                measureOverlayView(overlayView);
                item.markMeasurementValid();
                traceLayout("show/measure overlay %d", adapterIndex);
            } else {
                traceLayout("move overlay %d", adapterIndex);
                if (!item.isMeasurementValid()) {
                    item.rebindView(overlayView);
                    measureOverlayView(overlayView);
                    item.markMeasurementValid();
                    traceLayout("and (re)measure overlay %d, old/new heights=%d/%d", adapterIndex,
                            overlayView.getHeight(), overlayView.getMeasuredHeight());
                }
            }
            traceLayout("laying out overlay %d with h=%d", adapterIndex,
                    overlayView.getMeasuredHeight());
            final int childBottom = overlayTopY + overlayView.getMeasuredHeight();
            layoutOverlay(overlayView, overlayTopY, childBottom);
            mAdditionalBottomBorderOverlayTop = (childBottom > mAdditionalBottomBorderOverlayTop) ?
                    childBottom : mAdditionalBottomBorderOverlayTop;
        } else {
            // hide overlay
            if (overlay != null) {
                traceLayout("hide overlay %d", adapterIndex);
                onOverlayScrolledOff(adapterIndex, overlay, overlayTopY, overlayBottomY);
            } else {
                traceLayout("ignore non-visible overlay %d", adapterIndex);
            }
            mAdditionalBottomBorderOverlayTop = (overlayBottomY > mAdditionalBottomBorderOverlayTop)
                    ? overlayBottomY : mAdditionalBottomBorderOverlayTop;
        }

        if (overlayTopY <= mOffsetY && item.canPushSnapHeader()) {
            if (mSnapIndex == -1) {
                mSnapIndex = adapterIndex;
            } else if (adapterIndex > mSnapIndex) {
                mSnapIndex = adapterIndex;
            }
        }

    }

    // layout an existing view
    // need its top offset into the conversation, its height, and the scroll offset
    private void layoutOverlay(View child, int childTop, int childBottom) {
        final int top = childTop - mOffsetY;
        final int bottom = childBottom - mOffsetY;

        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
        final int childLeft = getPaddingLeft() + lp.leftMargin;

        child.layout(childLeft, top, childLeft + child.getMeasuredWidth(), bottom);
    }

    private View addOverlayView(int adapterIndex, boolean postAddView) {
        final int itemType = mOverlayAdapter.getItemViewType(adapterIndex);
        final View convertView = mScrapViews.poll(itemType);

        final View view = mOverlayAdapter.getView(adapterIndex, convertView, this);
        mOverlayViews.put(adapterIndex, new OverlayView(view, itemType));

        if (convertView == view) {
            LogUtils.d(TAG, "want to REUSE scrolled-in view: index=%d obj=%s", adapterIndex, view);
        } else {
            LogUtils.d(TAG, "want to CREATE scrolled-in view: index=%d obj=%s", adapterIndex, view);
        }

        if (view.getParent() == null) {
            addViewInLayoutWrapper(view, postAddView);
        } else {
            // Need to call postInvalidate since the view is being moved back on
            // screen and we want to force it to draw the view. Without doing this,
            // the view may not draw itself when it comes back on screen.
            view.postInvalidate();
        }

        return view;
    }

    private void addViewInLayoutWrapper(View view, boolean postAddView) {
        final AddViewRunnable addviewRunnable = new AddViewRunnable(view);
        if (postAddView) {
            post(addviewRunnable);
        } else {
            addviewRunnable.run();
        }
    }

    private class AddViewRunnable implements Runnable {
        private final View mView;

        public AddViewRunnable(View view) {
            mView = view;
        }

        @Override
        public void run() {
            final int index = BOTTOM_LAYER_VIEW_IDS.length;
            addViewInLayout(mView, index, mView.getLayoutParams(), true /* preventRequestLayout */);
        }
    };

    private class RemoveBorderRunnable implements Runnable {
        @Override
        public void run() {
            removeViewInLayout(mAdditionalBottomBorder);
        }
    }

    private boolean isSnapEnabled() {
        if (mAccountController == null || mAccountController.getAccount() == null
                || mAccountController.getAccount().settings == null) {
            return true;
        }
        final int snap = mAccountController.getAccount().settings.snapHeaders;
        return snap == UIProvider.SnapHeaderValue.ALWAYS ||
                (snap == UIProvider.SnapHeaderValue.PORTRAIT_ONLY && getResources()
                    .getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
    }

    // render and/or re-position snap header
    private void positionSnapHeader(int snapIndex) {
        ConversationOverlayItem snapItem = null;
        if (mSnapEnabled && snapIndex != -1) {
            final ConversationOverlayItem item = mOverlayAdapter.getItem(snapIndex);
            if (item.canBecomeSnapHeader()) {
                snapItem = item;
            }
        }
        if (snapItem == null) {
            mSnapHeader.setVisibility(GONE);
            mSnapHeader.unbind();
            return;
        }

        snapItem.bindView(mSnapHeader, false /* measureOnly */);
        mSnapHeader.setVisibility(VISIBLE);

        // overlap is negative or zero; bump the snap header upwards by that much
        int overlap = 0;

        final ConversationOverlayItem next = findNextPushingOverlay(snapIndex + 1);
        if (next != null) {
            overlap = Math.min(0, next.getTop() - mSnapHeader.getHeight() - mOffsetY);

            // disable overlap drawing past a certain speed
            if (overlap < 0) {
                final Float v = mVelocityTracker.getSmoothedVelocity();
                if (v != null && v > SNAP_HEADER_MAX_SCROLL_SPEED) {
                    overlap = 0;
                }
            }
        }

        mSnapHeader.setTranslationY(overlap);
    }

    // find the next header that can push the snap header up
    private ConversationOverlayItem findNextPushingOverlay(int start) {
        for (int i = start, len = mOverlayAdapter.getCount(); i < len; i++) {
            final ConversationOverlayItem next = mOverlayAdapter.getItem(i);
            if (next.canPushSnapHeader()) {
                return next;
            }
        }
        return null;
    }

    /**
     * Prevents any layouts from happening until the next time
     * {@link #onGeometryChange(OverlayPosition[])} is
     * called. Useful when you know the HTML spacer coordinates are inconsistent with adapter items.
     * <p>
     * If you call this, you must ensure that a followup call to
     * {@link #onGeometryChange(OverlayPosition[])}
     * is made later, when the HTML spacer coordinates are updated.
     *
     */
    public void invalidateSpacerGeometry() {
        mOverlayPositions = null;
    }

    public void onGeometryChange(OverlayPosition[] overlayPositions) {
        traceLayout("*** got overlay spacer positions:");
        for (OverlayPosition pos : overlayPositions) {
            traceLayout("top=%d bottom=%d", pos.top, pos.bottom);
        }

        mOverlayPositions = overlayPositions;
        positionOverlays(mOffsetY, false /* postAddView */);
    }

    /**
     * Remove the view that corresponds to the item in the {@link ConversationViewAdapter}
     * at the specified index.<p/>
     *
     * <b>Note:</b> the view is actually pushed off-screen and recycled
     * as though it were scrolled off.
     * @param adapterIndex The index for the view in the adapter.
     */
    public void removeViewAtAdapterIndex(int adapterIndex) {
        // need to temporarily set the offset to 0 so that we can ensure we're pushing off-screen.
        final int offsetY = mOffsetY;
        mOffsetY = 0;
        final OverlayView overlay = mOverlayViews.get(adapterIndex);
        if (overlay != null) {
            final int height = getHeight();
            onOverlayScrolledOff(adapterIndex, overlay, height, height + overlay.view.getHeight());
            LogUtils.i(TAG, "footer scrolled off. container height=%s, measuredHeight=%s",
                    height, getMeasuredHeight());
        } else {
            LogUtils.i(TAG, "footer not found with adapterIndex=%s", adapterIndex);
            for (int i = 0, size = mOverlayViews.size(); i < size; i++) {
                final int index = mOverlayViews.keyAt(i);
                final OverlayView overlayView = mOverlayViews.valueAt(i);
                LogUtils.i(TAG, "OverlayView: adapterIndex=%s, itemType=%s, view=%s",
                        index, overlayView.itemType, overlayView.view);
            }
            for (int i = 0, size = mOverlayAdapter.getCount(); i < size; i++) {
                final ConversationOverlayItem item = mOverlayAdapter.getItem(i);
                LogUtils.i(TAG, "adapter item: index=%s, item=%s", i, item);
            }
        }
        // restore the offset to its original value after the view has been moved off-screen.
        mOffsetY = offsetY;
    }

    private void traceLayout(String msg, Object... params) {
        if (mDisableLayoutTracing) {
            return;
        }
        LogUtils.d(TAG, msg, params);
    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
        if (mOverlayAdapter != null) {
            return mOverlayAdapter.focusFirstMessageHeader();
        }
        return false;
    }

    public void focusFirstMessageHeader() {
        mOverlayAdapter.focusFirstMessageHeader();
    }

    public View getNextOverlayView(View curr, boolean isDown) {
        // Find the scraps that we should avoid when fetching the next view.
        final Set<View> scraps = Sets.newHashSet();
        mScrapViews.visitAll(new DequeMap.Visitor<View>() {
            @Override
            public void visit(View item) {
                scraps.add(item);
            }
        });
        return mOverlayAdapter.getNextOverlayView(curr, isDown, scraps);
    }

    private class AdapterObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            onDataSetChanged();
        }
    }
}
