/*
 * Copyright (C) 2011 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.browser;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;

import com.android.browser.view.ScrollerView;

/**
 * custom view for displaying tabs in the nav screen
 */
public class NavTabScroller extends ScrollerView {

    static final int INVALID_POSITION = -1;
    static final float[] PULL_FACTOR = { 2.5f, 0.9f };

    interface OnRemoveListener {
        public void onRemovePosition(int position);
    }

    interface OnLayoutListener {
        public void onLayout(int l, int t, int r, int b);
    }

    private ContentLayout mContentView;
    private BaseAdapter mAdapter;
    private OnRemoveListener mRemoveListener;
    private OnLayoutListener mLayoutListener;
    private int mGap;
    private int mGapPosition;
    private ObjectAnimator mGapAnimator;

    // after drag animation velocity in pixels/sec
    private static final float MIN_VELOCITY = 1500;
    private AnimatorSet mAnimator;

    private float mFlingVelocity;
    private boolean mNeedsScroll;
    private int mScrollPosition;

    DecelerateInterpolator mCubic;
    int mPullValue;

    public NavTabScroller(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public NavTabScroller(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public NavTabScroller(Context context) {
        super(context);
        init(context);
    }

    private void init(Context ctx) {
        mCubic = new DecelerateInterpolator(1.5f);
        mGapPosition = INVALID_POSITION;
        setHorizontalScrollBarEnabled(false);
        setVerticalScrollBarEnabled(false);
        mContentView = new ContentLayout(ctx, this);
        mContentView.setOrientation(LinearLayout.HORIZONTAL);
        addView(mContentView);
        mContentView.setLayoutParams(
                new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
        // ProGuard !
        setGap(getGap());
        mFlingVelocity = getContext().getResources().getDisplayMetrics().density
                * MIN_VELOCITY;
    }

    protected int getScrollValue() {
        return mHorizontal ? mScrollX : mScrollY;
    }

    protected void setScrollValue(int value) {
        scrollTo(mHorizontal ? value : 0, mHorizontal ? 0 : value);
    }

    protected NavTabView getTabView(int pos) {
        return (NavTabView) mContentView.getChildAt(pos);
    }

    protected boolean isHorizontal() {
        return mHorizontal;
    }

    public void setOrientation(int orientation) {
        mContentView.setOrientation(orientation);
        if (orientation == LinearLayout.HORIZONTAL) {
            mContentView.setLayoutParams(
                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
        } else {
            mContentView.setLayoutParams(
                    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
        }
        super.setOrientation(orientation);
    }

    @Override
    protected void onMeasure(int wspec, int hspec) {
        super.onMeasure(wspec, hspec);
        calcPadding();
    }

    private void calcPadding() {
        if (mAdapter.getCount() > 0) {
            View v = mContentView.getChildAt(0);
            if (mHorizontal) {
                int pad = (getMeasuredWidth() - v.getMeasuredWidth()) / 2 + 2;
                mContentView.setPadding(pad, 0, pad, 0);
            } else {
                int pad = (getMeasuredHeight() - v.getMeasuredHeight()) / 2 + 2;
                mContentView.setPadding(0, pad, 0, pad);
            }
        }
    }

    public void setAdapter(BaseAdapter adapter) {
        setAdapter(adapter, 0);
    }


    public void setOnRemoveListener(OnRemoveListener l) {
        mRemoveListener = l;
    }

    public void setOnLayoutListener(OnLayoutListener l) {
        mLayoutListener = l;
    }

    protected void setAdapter(BaseAdapter adapter, int selection) {
        mAdapter = adapter;
        mAdapter.registerDataSetObserver(new DataSetObserver() {

            @Override
            public void onChanged() {
                super.onChanged();
                handleDataChanged();
            }

            @Override
            public void onInvalidated() {
                super.onInvalidated();
            }
        });
        handleDataChanged(selection);
    }

    protected ViewGroup getContentView() {
        return mContentView;
    }

    protected int getRelativeChildTop(int ix) {
        return mContentView.getChildAt(ix).getTop() - mScrollY;
    }

    protected void handleDataChanged() {
        handleDataChanged(INVALID_POSITION);
    }

    void handleDataChanged(int newscroll) {
        int scroll = getScrollValue();
        if (mGapAnimator != null) {
            mGapAnimator.cancel();
        }
        mContentView.removeAllViews();
        for (int i = 0; i < mAdapter.getCount(); i++) {
            View v = mAdapter.getView(i, null, mContentView);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            lp.gravity = (mHorizontal ? Gravity.CENTER_VERTICAL : Gravity.CENTER_HORIZONTAL);
            mContentView.addView(v, lp);
            if (mGapPosition > INVALID_POSITION){
                adjustViewGap(v, i);
            }
        }
        if (newscroll > INVALID_POSITION) {
            newscroll = Math.min(mAdapter.getCount() - 1, newscroll);
            mNeedsScroll = true;
            mScrollPosition = newscroll;
            requestLayout();
        } else {
            setScrollValue(scroll);
        }
    }

    protected void finishScroller() {
        mScroller.forceFinished(true);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (mNeedsScroll) {
            mScroller.forceFinished(true);
            snapToSelected(mScrollPosition, false);
            mNeedsScroll = false;
        }
        if (mLayoutListener != null) {
            mLayoutListener.onLayout(l, t, r, b);
            mLayoutListener = null;
        }
    }

    void clearTabs() {
        mContentView.removeAllViews();
    }

    void snapToSelected(int pos, boolean smooth) {
        if (pos < 0) return;
        View v = mContentView.getChildAt(pos);
        if (v == null) return;
        int sx = 0;
        int sy = 0;
        if (mHorizontal) {
            sx = (v.getLeft() + v.getRight() - getWidth()) / 2;
        } else {
            sy = (v.getTop() + v.getBottom() - getHeight()) / 2;
        }
        if ((sx != mScrollX) || (sy != mScrollY)) {
            if (smooth) {
                smoothScrollTo(sx,sy);
            } else {
                scrollTo(sx, sy);
            }
        }
    }

    protected void animateOut(View v) {
        if (v == null) return;
        animateOut(v, -mFlingVelocity);
    }

    private void animateOut(final View v, float velocity) {
        float start = mHorizontal ? v.getTranslationY() : v.getTranslationX();
        animateOut(v, velocity, start);
    }

    private void animateOut(final View v, float velocity, float start) {
        if ((v == null) || (mAnimator != null)) return;
        final int position = mContentView.indexOfChild(v);
        int target = 0;
        if (velocity < 0) {
            target = mHorizontal ? -getHeight() :  -getWidth();
        } else {
            target = mHorizontal ? getHeight() : getWidth();
        }
        int distance = target - (mHorizontal ? v.getTop() : v.getLeft());
        long duration = (long) (Math.abs(distance) * 1000 / Math.abs(velocity));
        int scroll = 0;
        int translate = 0;
        int gap = mHorizontal ? v.getWidth() : v.getHeight();
        int centerView = getViewCenter(v);
        int centerScreen = getScreenCenter();
        int newpos = INVALID_POSITION;
        if (centerView < centerScreen - gap / 2) {
            // top view
            scroll = - (centerScreen - centerView - gap);
            translate = (position > 0) ? gap : 0;
            newpos = position;
        } else if (centerView > centerScreen + gap / 2) {
            // bottom view
            scroll = - (centerScreen + gap - centerView);
            if (position < mAdapter.getCount() - 1) {
                translate = -gap;
            }
        } else {
            // center view
            scroll = - (centerScreen - centerView);
            if (position < mAdapter.getCount() - 1) {
                translate = -gap;
            } else {
                scroll -= gap;
            }
        }
        mGapPosition = position;
        final int pos = newpos;
        ObjectAnimator trans = ObjectAnimator.ofFloat(v,
                (mHorizontal ? TRANSLATION_Y : TRANSLATION_X), start, target);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(v, ALPHA, getAlpha(v,start),
                getAlpha(v,target));
        AnimatorSet set1 = new AnimatorSet();
        set1.playTogether(trans, alpha);
        set1.setDuration(duration);
        mAnimator = new AnimatorSet();
        ObjectAnimator trans2 = null;
        ObjectAnimator scroll1 = null;
        if (scroll != 0) {
            if (mHorizontal) {
                scroll1 = ObjectAnimator.ofInt(this, "scrollX", getScrollX(), getScrollX() + scroll);
            } else {
                scroll1 = ObjectAnimator.ofInt(this, "scrollY", getScrollY(), getScrollY() + scroll);
            }
        }
        if (translate != 0) {
            trans2 = ObjectAnimator.ofInt(this, "gap", 0, translate);
        }
        final int duration2 = 200;
        if (scroll1 != null) {
            if (trans2 != null) {
                AnimatorSet set2 = new AnimatorSet();
                set2.playTogether(scroll1, trans2);
                set2.setDuration(duration2);
                mAnimator.playSequentially(set1, set2);
            } else {
                scroll1.setDuration(duration2);
                mAnimator.playSequentially(set1, scroll1);
            }
        } else {
            if (trans2 != null) {
                trans2.setDuration(duration2);
                mAnimator.playSequentially(set1, trans2);
            }
        }
        mAnimator.addListener(new AnimatorListenerAdapter() {
            public void onAnimationEnd(Animator a) {
                if (mRemoveListener !=  null) {
                    mRemoveListener.onRemovePosition(position);
                    mAnimator = null;
                    mGapPosition = INVALID_POSITION;
                    mGap = 0;
                    handleDataChanged(pos);
                }
            }
        });
        mAnimator.start();
    }

    public void setGap(int gap) {
        if (mGapPosition != INVALID_POSITION) {
            mGap = gap;
            postInvalidate();
        }
    }

    public int getGap() {
        return mGap;
    }

    void adjustGap() {
        for (int i = 0; i < mContentView.getChildCount(); i++) {
            final View child = mContentView.getChildAt(i);
            adjustViewGap(child, i);
        }
    }

    private void adjustViewGap(View view, int pos) {
        if ((mGap < 0 && pos > mGapPosition)
                || (mGap > 0 && pos < mGapPosition)) {
            if (mHorizontal) {
                view.setTranslationX(mGap);
            } else {
                view.setTranslationY(mGap);
            }
        }
    }

    private int getViewCenter(View v) {
        if (mHorizontal) {
            return v.getLeft() + v.getWidth() / 2;
        } else {
            return v.getTop() + v.getHeight() / 2;
        }
    }

    private int getScreenCenter() {
        if (mHorizontal) {
            return getScrollX() + getWidth() / 2;
        } else {
            return getScrollY() + getHeight() / 2;
        }
    }

    @Override
    public void draw(Canvas canvas) {
        if (mGapPosition > INVALID_POSITION) {
            adjustGap();
        }
        super.draw(canvas);
    }

    @Override
    protected View findViewAt(int x, int y) {
        x += mScrollX;
        y += mScrollY;
        final int count = mContentView.getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            View child = mContentView.getChildAt(i);
            if (child.getVisibility() == View.VISIBLE) {
                if ((x >= child.getLeft()) && (x < child.getRight())
                        && (y >= child.getTop()) && (y < child.getBottom())) {
                    return child;
                }
            }
        }
        return null;
    }

    @Override
    protected void onOrthoDrag(View v, float distance) {
        if ((v != null) && (mAnimator == null)) {
            offsetView(v, distance);
        }
    }

    @Override
    protected void onOrthoDragFinished(View downView) {
        if (mAnimator != null) return;
        if (mIsOrthoDragged && downView != null) {
            // offset
            float diff = mHorizontal ? downView.getTranslationY() : downView.getTranslationX();
            if (Math.abs(diff) > (mHorizontal ? downView.getHeight() : downView.getWidth()) / 2) {
                // remove it
                animateOut(downView, Math.signum(diff) * mFlingVelocity, diff);
            } else {
                // snap back
                offsetView(downView, 0);
            }
        }
    }

    @Override
    protected void onOrthoFling(View v, float velocity) {
        if (v == null) return;
        if (mAnimator == null && Math.abs(velocity) > mFlingVelocity / 2) {
            animateOut(v, velocity);
        } else {
            offsetView(v, 0);
        }
    }

    private void offsetView(View v, float distance) {
        v.setAlpha(getAlpha(v, distance));
        if (mHorizontal) {
            v.setTranslationY(distance);
        } else {
            v.setTranslationX(distance);
        }
    }

    private float getAlpha(View v, float distance) {
        return 1 - (float) Math.abs(distance) / (mHorizontal ? v.getHeight() : v.getWidth());
    }

    private float ease(DecelerateInterpolator inter, float value, float start,
            float dist, float duration) {
        return start + dist * inter.getInterpolation(value / duration);
    }

    @Override
    protected void onPull(int delta) {
        boolean layer = false;
        int count = 2;
        if (delta == 0 && mPullValue == 0) return;
        if (delta == 0 && mPullValue != 0) {
            // reset
            for (int i = 0; i < count; i++) {
                View child = mContentView.getChildAt((mPullValue < 0)
                        ? i
                        : mContentView.getChildCount() - 1 - i);
                if (child == null) break;
                ObjectAnimator trans = ObjectAnimator.ofFloat(child,
                        mHorizontal ? "translationX" : "translationY",
                                mHorizontal ? getTranslationX() : getTranslationY(),
                                0);
                ObjectAnimator rot = ObjectAnimator.ofFloat(child,
                        mHorizontal ? "rotationY" : "rotationX",
                                mHorizontal ? getRotationY() : getRotationX(),
                                0);
                AnimatorSet set = new AnimatorSet();
                set.playTogether(trans, rot);
                set.setDuration(100);
                set.start();
            }
            mPullValue = 0;
        } else {
            if (mPullValue == 0) {
                layer = true;
            }
            mPullValue += delta;
        }
        final int height = mHorizontal ? getWidth() : getHeight();
        int oscroll = Math.abs(mPullValue);
        int factor = (mPullValue <= 0) ? 1 : -1;
        for (int i = 0; i < count; i++) {
            View child = mContentView.getChildAt((mPullValue < 0)
                    ? i
                    : mContentView.getChildCount() - 1 - i);
            if (child == null) break;
            if (layer) {
            }
            float k = PULL_FACTOR[i];
            float rot = -factor * ease(mCubic, oscroll, 0, k * 2, height);
            int y =  factor * (int) ease(mCubic, oscroll, 0, k*20, height);
            if (mHorizontal) {
                child.setTranslationX(y);
            } else {
                child.setTranslationY(y);
            }
            if (mHorizontal) {
                child.setRotationY(-rot);
            } else {
                child.setRotationX(rot);
            }
        }
    }

    static class ContentLayout extends LinearLayout {

        NavTabScroller mScroller;

        public ContentLayout(Context context, NavTabScroller scroller) {
            super(context);
            mScroller = scroller;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (mScroller.getGap() != 0) {
                View v = getChildAt(0);
                if (v != null) {
                    if (mScroller.isHorizontal()) {
                        int total = v.getMeasuredWidth() + getMeasuredWidth();
                        setMeasuredDimension(total, getMeasuredHeight());
                    } else {
                        int total = v.getMeasuredHeight() + getMeasuredHeight();
                        setMeasuredDimension(getMeasuredWidth(), total);
                    }
                }

            }
        }

    }

}