/*
 * Copyright (C) 2010 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.common.list;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListAdapter;
import android.widget.TextView;

import com.android.contacts.common.util.ViewUtil;

/**
 * A ListView that maintains a header pinned at the top of the list. The
 * pinned header can be pushed up and dissolved as needed.
 */
public class PinnedHeaderListView extends AutoScrollListView
        implements OnScrollListener, OnItemSelectedListener {

    /**
     * Adapter interface.  The list adapter must implement this interface.
     */
    public interface PinnedHeaderAdapter {

        /**
         * Returns the overall number of pinned headers, visible or not.
         */
        int getPinnedHeaderCount();

        /**
         * Creates or updates the pinned header view.
         */
        View getPinnedHeaderView(int viewIndex, View convertView, ViewGroup parent);

        /**
         * Configures the pinned headers to match the visible list items. The
         * adapter should call {@link PinnedHeaderListView#setHeaderPinnedAtTop},
         * {@link PinnedHeaderListView#setHeaderPinnedAtBottom},
         * {@link PinnedHeaderListView#setFadingHeader} or
         * {@link PinnedHeaderListView#setHeaderInvisible}, for each header that
         * needs to change its position or visibility.
         */
        void configurePinnedHeaders(PinnedHeaderListView listView);

        /**
         * Returns the list position to scroll to if the pinned header is touched.
         * Return -1 if the list does not need to be scrolled.
         */
        int getScrollPositionForHeader(int viewIndex);
    }

    private static final int MAX_ALPHA = 255;
    private static final int TOP = 0;
    private static final int BOTTOM = 1;
    private static final int FADING = 2;

    private static final int DEFAULT_ANIMATION_DURATION = 20;

    private static final int DEFAULT_SMOOTH_SCROLL_DURATION = 100;

    private static final class PinnedHeader {
        View view;
        boolean visible;
        int y;
        int height;
        int alpha;
        int state;

        boolean animating;
        boolean targetVisible;
        int sourceY;
        int targetY;
        long targetTime;
    }

    private PinnedHeaderAdapter mAdapter;
    private int mSize;
    private PinnedHeader[] mHeaders;
    private RectF mBounds = new RectF();
    private OnScrollListener mOnScrollListener;
    private OnItemSelectedListener mOnItemSelectedListener;
    private int mScrollState;

    private boolean mScrollToSectionOnHeaderTouch = false;
    private boolean mHeaderTouched = false;

    private int mAnimationDuration = DEFAULT_ANIMATION_DURATION;
    private boolean mAnimating;
    private long mAnimationTargetTime;
    private int mHeaderPaddingStart;
    private int mHeaderWidth;

    public PinnedHeaderListView(Context context) {
        this(context, null, android.R.attr.listViewStyle);
    }

    public PinnedHeaderListView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.listViewStyle);
    }

    public PinnedHeaderListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        super.setOnScrollListener(this);
        super.setOnItemSelectedListener(this);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mHeaderPaddingStart = getPaddingStart();
        mHeaderWidth = r - l - mHeaderPaddingStart - getPaddingEnd();
    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        mAdapter = (PinnedHeaderAdapter)adapter;
        super.setAdapter(adapter);
    }

    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        mOnScrollListener = onScrollListener;
        super.setOnScrollListener(this);
    }

    @Override
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        mOnItemSelectedListener = listener;
        super.setOnItemSelectedListener(this);
    }

    public void setScrollToSectionOnHeaderTouch(boolean value) {
        mScrollToSectionOnHeaderTouch = value;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
        if (mAdapter != null) {
            int count = mAdapter.getPinnedHeaderCount();
            if (count != mSize) {
                mSize = count;
                if (mHeaders == null) {
                    mHeaders = new PinnedHeader[mSize];
                } else if (mHeaders.length < mSize) {
                    PinnedHeader[] headers = mHeaders;
                    mHeaders = new PinnedHeader[mSize];
                    System.arraycopy(headers, 0, mHeaders, 0, headers.length);
                }
            }

            for (int i = 0; i < mSize; i++) {
                if (mHeaders[i] == null) {
                    mHeaders[i] = new PinnedHeader();
                }
                mHeaders[i].view = mAdapter.getPinnedHeaderView(i, mHeaders[i].view, this);
            }

            mAnimationTargetTime = System.currentTimeMillis() + mAnimationDuration;
            mAdapter.configurePinnedHeaders(this);
            invalidateIfAnimating();
        }
        if (mOnScrollListener != null) {
            mOnScrollListener.onScroll(this, firstVisibleItem, visibleItemCount, totalItemCount);
        }
    }

    @Override
    protected float getTopFadingEdgeStrength() {
        // Disable vertical fading at the top when the pinned header is present
        return mSize > 0 ? 0 : super.getTopFadingEdgeStrength();
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        mScrollState = scrollState;
        if (mOnScrollListener != null) {
            mOnScrollListener.onScrollStateChanged(this, scrollState);
        }
    }

    /**
     * Ensures that the selected item is positioned below the top-pinned headers
     * and above the bottom-pinned ones.
     */
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        int height = getHeight();

        int windowTop = 0;
        int windowBottom = height;

        for (int i = 0; i < mSize; i++) {
            PinnedHeader header = mHeaders[i];
            if (header.visible) {
                if (header.state == TOP) {
                    windowTop = header.y + header.height;
                } else if (header.state == BOTTOM) {
                    windowBottom = header.y;
                    break;
                }
            }
        }

        View selectedView = getSelectedView();
        if (selectedView != null) {
            if (selectedView.getTop() < windowTop) {
                setSelectionFromTop(position, windowTop);
            } else if (selectedView.getBottom() > windowBottom) {
                setSelectionFromTop(position, windowBottom - selectedView.getHeight());
            }
        }

        if (mOnItemSelectedListener != null) {
            mOnItemSelectedListener.onItemSelected(parent, view, position, id);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        if (mOnItemSelectedListener != null) {
            mOnItemSelectedListener.onNothingSelected(parent);
        }
    }

    public int getPinnedHeaderHeight(int viewIndex) {
        ensurePinnedHeaderLayout(viewIndex);
        return mHeaders[viewIndex].view.getHeight();
    }

    /**
     * Set header to be pinned at the top.
     *
     * @param viewIndex index of the header view
     * @param y is position of the header in pixels.
     * @param animate true if the transition to the new coordinate should be animated
     */
    public void setHeaderPinnedAtTop(int viewIndex, int y, boolean animate) {
        ensurePinnedHeaderLayout(viewIndex);
        PinnedHeader header = mHeaders[viewIndex];
        header.visible = true;
        header.y = y;
        header.state = TOP;

        // TODO perhaps we should animate at the top as well
        header.animating = false;
    }

    /**
     * Set header to be pinned at the bottom.
     *
     * @param viewIndex index of the header view
     * @param y is position of the header in pixels.
     * @param animate true if the transition to the new coordinate should be animated
     */
    public void setHeaderPinnedAtBottom(int viewIndex, int y, boolean animate) {
        ensurePinnedHeaderLayout(viewIndex);
        PinnedHeader header = mHeaders[viewIndex];
        header.state = BOTTOM;
        if (header.animating) {
            header.targetTime = mAnimationTargetTime;
            header.sourceY = header.y;
            header.targetY = y;
        } else if (animate && (header.y != y || !header.visible)) {
            if (header.visible) {
                header.sourceY = header.y;
            } else {
                header.visible = true;
                header.sourceY = y + header.height;
            }
            header.animating = true;
            header.targetVisible = true;
            header.targetTime = mAnimationTargetTime;
            header.targetY = y;
        } else {
            header.visible = true;
            header.y = y;
        }
    }

    /**
     * Set header to be pinned at the top of the first visible item.
     *
     * @param viewIndex index of the header view
     * @param position is position of the header in pixels.
     */
    public void setFadingHeader(int viewIndex, int position, boolean fade) {
        ensurePinnedHeaderLayout(viewIndex);

        View child = getChildAt(position - getFirstVisiblePosition());
        if (child == null) return;

        PinnedHeader header = mHeaders[viewIndex];
        // Hide header when it's a star.
        // TODO: try showing the view even when it's a star;
        // if we have to hide the star view, then try hiding it in some higher layer.
        header.visible = !((TextView) header.view).getText().toString().isEmpty();
        header.state = FADING;
        header.alpha = MAX_ALPHA;
        header.animating = false;

        int top = getTotalTopPinnedHeaderHeight();
        header.y = top;
        if (fade) {
            int bottom = child.getBottom() - top;
            int headerHeight = header.height;
            if (bottom < headerHeight) {
                int portion = bottom - headerHeight;
                header.alpha = MAX_ALPHA * (headerHeight + portion) / headerHeight;
                header.y = top + portion;
            }
        }
    }

    /**
     * Makes header invisible.
     *
     * @param viewIndex index of the header view
     * @param animate true if the transition to the new coordinate should be animated
     */
    public void setHeaderInvisible(int viewIndex, boolean animate) {
        PinnedHeader header = mHeaders[viewIndex];
        if (header.visible && (animate || header.animating) && header.state == BOTTOM) {
            header.sourceY = header.y;
            if (!header.animating) {
                header.visible = true;
                header.targetY = getBottom() + header.height;
            }
            header.animating = true;
            header.targetTime = mAnimationTargetTime;
            header.targetVisible = false;
        } else {
            header.visible = false;
        }
    }

    private void ensurePinnedHeaderLayout(int viewIndex) {
        View view = mHeaders[viewIndex].view;
        if (view.isLayoutRequested()) {
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            int widthSpec;
            int heightSpec;

            if (layoutParams != null && layoutParams.width > 0) {
                widthSpec = View.MeasureSpec
                        .makeMeasureSpec(layoutParams.width, View.MeasureSpec.EXACTLY);
            } else {
                widthSpec = View.MeasureSpec
                        .makeMeasureSpec(mHeaderWidth, View.MeasureSpec.EXACTLY);
            }

            if (layoutParams != null && layoutParams.height > 0) {
                heightSpec = View.MeasureSpec
                        .makeMeasureSpec(layoutParams.height, View.MeasureSpec.EXACTLY);
            } else {
                heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            }
            view.measure(widthSpec, heightSpec);
            int height = view.getMeasuredHeight();
            mHeaders[viewIndex].height = height;
            view.layout(0, 0, view.getMeasuredWidth(), height);
        }
    }

    /**
     * Returns the sum of heights of headers pinned to the top.
     */
    public int getTotalTopPinnedHeaderHeight() {
        for (int i = mSize; --i >= 0;) {
            PinnedHeader header = mHeaders[i];
            if (header.visible && header.state == TOP) {
                return header.y + header.height;
            }
        }
        return 0;
    }

    /**
     * Returns the list item position at the specified y coordinate.
     */
    public int getPositionAt(int y) {
        do {
            int position = pointToPosition(getPaddingLeft() + 1, y);
            if (position != -1) {
                return position;
            }
            // If position == -1, we must have hit a separator. Let's examine
            // a nearby pixel
            y--;
        } while (y > 0);
        return 0;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mHeaderTouched = false;
        if (super.onInterceptTouchEvent(ev)) {
            return true;
        }

        if (mScrollState == SCROLL_STATE_IDLE) {
            final int y = (int)ev.getY();
            final int x = (int)ev.getX();
            for (int i = mSize; --i >= 0;) {
                PinnedHeader header = mHeaders[i];
                final int padding = ViewUtil.isViewLayoutRtl(this) ?
                        getWidth() - mHeaderPaddingStart - header.view.getWidth() :
                        mHeaderPaddingStart;
                if (header.visible && header.y <= y && header.y + header.height > y &&
                        x >= padding && padding + header.view.getWidth() >= x) {
                    mHeaderTouched = true;
                    if (mScrollToSectionOnHeaderTouch &&
                            ev.getAction() == MotionEvent.ACTION_DOWN) {
                        return smoothScrollToPartition(i);
                    } else {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mHeaderTouched) {
            if (ev.getAction() == MotionEvent.ACTION_UP) {
                mHeaderTouched = false;
            }
            return true;
        }
        return super.onTouchEvent(ev);
    }

    private boolean smoothScrollToPartition(int partition) {
        if (mAdapter == null) {
            return false;
        }
        final int position = mAdapter.getScrollPositionForHeader(partition);
        if (position == -1) {
            return false;
        }

        int offset = 0;
        for (int i = 0; i < partition; i++) {
            PinnedHeader header = mHeaders[i];
            if (header.visible) {
                offset += header.height;
            }
        }
        smoothScrollToPositionFromTop(position + getHeaderViewsCount(), offset,
                DEFAULT_SMOOTH_SCROLL_DURATION);
        return true;
    }

    private void invalidateIfAnimating() {
        mAnimating = false;
        for (int i = 0; i < mSize; i++) {
            if (mHeaders[i].animating) {
                mAnimating = true;
                invalidate();
                return;
            }
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        long currentTime = mAnimating ? System.currentTimeMillis() : 0;

        int top = 0;
        int right = 0;
        int bottom = getBottom();
        boolean hasVisibleHeaders = false;
        for (int i = 0; i < mSize; i++) {
            PinnedHeader header = mHeaders[i];
            if (header.visible) {
                hasVisibleHeaders = true;
                if (header.state == BOTTOM && header.y < bottom) {
                    bottom = header.y;
                } else if (header.state == TOP || header.state == FADING) {
                    int newTop = header.y + header.height;
                    if (newTop > top) {
                        top = newTop;
                    }
                }
            }
        }

        if (hasVisibleHeaders) {
            canvas.save();
        }

        super.dispatchDraw(canvas);

        if (hasVisibleHeaders) {
            canvas.restore();

            // If the first item is visible and if it has a positive top that is greater than the
            // first header's assigned y-value, use that for the first header's y value. This way,
            // the header inherits any padding applied to the list view.
            if (mSize > 0 && getFirstVisiblePosition() == 0) {
                View firstChild = getChildAt(0);
                PinnedHeader firstHeader = mHeaders[0];

                if (firstHeader != null) {
                    int firstHeaderTop = firstChild != null ? firstChild.getTop() : 0;
                    firstHeader.y = Math.max(firstHeader.y, firstHeaderTop);
                }
            }

            // First draw top headers, then the bottom ones to handle the Z axis correctly
            for (int i = mSize; --i >= 0;) {
                PinnedHeader header = mHeaders[i];
                if (header.visible && (header.state == TOP || header.state == FADING)) {
                    drawHeader(canvas, header, currentTime);
                }
            }

            for (int i = 0; i < mSize; i++) {
                PinnedHeader header = mHeaders[i];
                if (header.visible && header.state == BOTTOM) {
                    drawHeader(canvas, header, currentTime);
                }
            }
        }

        invalidateIfAnimating();
    }

    private void drawHeader(Canvas canvas, PinnedHeader header, long currentTime) {
        if (header.animating) {
            int timeLeft = (int)(header.targetTime - currentTime);
            if (timeLeft <= 0) {
                header.y = header.targetY;
                header.visible = header.targetVisible;
                header.animating = false;
            } else {
                header.y = header.targetY + (header.sourceY - header.targetY) * timeLeft
                        / mAnimationDuration;
            }
        }
        if (header.visible) {
            View view = header.view;
            int saveCount = canvas.save();
            int translateX = ViewUtil.isViewLayoutRtl(this) ?
                    getWidth() - mHeaderPaddingStart - view.getWidth() :
                    mHeaderPaddingStart;
            canvas.translate(translateX, header.y);
            if (header.state == FADING) {
                mBounds.set(0, 0, view.getWidth(), view.getHeight());
                canvas.saveLayerAlpha(mBounds, header.alpha, Canvas.ALL_SAVE_FLAG);
            }
            view.draw(canvas);
            canvas.restoreToCount(saveCount);
        }
    }
}
