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

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;

class PanelSwitcher extends FrameLayout implements AnimationListener {
    private static final int MAJOR_MOVE = 60;
    private static final int ANIM_DURATION = 400;

    private GestureDetector mGestureDetector;
    private int mCurrentView;
    private View mChildren[] = new View[0];

    private int mWidth;
    private TranslateAnimation inLeft;
    private TranslateAnimation outLeft;

    private TranslateAnimation inRight;
    private TranslateAnimation outRight;

    private static final int LEFT  = 1;
    private static final int RIGHT = 2;
    private int mPreviousMove;

    public interface Listener {
        void onChange();
    }

    private Listener mListener;

    public PanelSwitcher(Context context, AttributeSet attrs) {
        super(context, attrs);
        mCurrentView = 0;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    int dx = (int) (e2.getX() - e1.getX());

                    // don't accept the fling if it's too short
                    // as it may conflict with a button push
                    if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) {
                        if (velocityX > 0) {
                            moveRight();
                        } else {
                            moveLeft();
                        }
                        return true;
                    } else {
                        return false;
                    }
                }
            });
    }

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

    void setCurrentIndex(int current) {
        boolean changed = mCurrentView != current;
        mCurrentView = current;
        updateCurrentView();
        if (changed && mListener != null) {
            mListener.onChange();
        }
    }

    private void updateCurrentView() {
        for (int i = mChildren.length-1; i >= 0 ; --i) {
            mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE);
        }
    }

    @Override
    public void onSizeChanged(int w, int h, int oldW, int oldH) {
        mWidth = w;
        inLeft   = new TranslateAnimation(mWidth, 0, 0, 0);
        inLeft.setAnimationListener(this);
        outLeft  = new TranslateAnimation(0, -mWidth, 0, 0);
        inRight  = new TranslateAnimation(-mWidth, 0, 0, 0);
        inRight.setAnimationListener(this);
        outRight = new TranslateAnimation(0, mWidth, 0, 0);

        inLeft.setDuration(ANIM_DURATION);
        outLeft.setDuration(ANIM_DURATION);
        inRight.setDuration(ANIM_DURATION);
        outRight.setDuration(ANIM_DURATION);
    }

    @Override
    protected void onFinishInflate() {
        int count = getChildCount();
        mChildren = new View[count];
        for (int i = 0; i < count; ++i) {
            mChildren[i] = getChildAt(i);
        }
        updateCurrentView();
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    void moveLeft() {
        //  <--
        if (mCurrentView < mChildren.length - 1 && mPreviousMove != LEFT) {
            mChildren[mCurrentView+1].setVisibility(View.VISIBLE);
            mChildren[mCurrentView+1].startAnimation(inLeft);
            mChildren[mCurrentView].startAnimation(outLeft);
            mChildren[mCurrentView].setVisibility(View.GONE);

            mCurrentView++;
            mPreviousMove = LEFT;
        }
    }

    void moveRight() {
        //  -->
        if (mCurrentView > 0 && mPreviousMove != RIGHT) {
            mChildren[mCurrentView-1].setVisibility(View.VISIBLE);
            mChildren[mCurrentView-1].startAnimation(inRight);
            mChildren[mCurrentView].startAnimation(outRight);
            mChildren[mCurrentView].setVisibility(View.GONE);

            mCurrentView--;
            mPreviousMove = RIGHT;
        }
    }

    int getCurrentIndex() {
        return mCurrentView;
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        if (mListener != null) {
            mListener.onChange();
        }
    }
}
