/*
 * 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.videoeditor.widgets;

import java.util.ArrayList;
import java.util.List;

import com.android.videoeditor.R;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

/**
 * The timeline scroll view
 */
public class TimelineHorizontalScrollView extends HorizontalScrollView {
    public final static int PLAYHEAD_NORMAL = 1;
    public final static int PLAYHEAD_MOVE_OK = 2;
    public final static int PLAYHEAD_MOVE_NOT_OK = 3;

    // Instance variables
    private final List<ScrollViewListener> mScrollListenerList;
    private final Handler mHandler;
    private final int mPlayheadMarginTop;
    private final int mPlayheadMarginTopOk;
    private final int mPlayheadMarginTopNotOk;
    private final int mPlayheadMarginBottom;
    private final Drawable mNormalPlayheadDrawable;
    private final Drawable mMoveOkPlayheadDrawable;
    private final Drawable mMoveNotOkPlayheadDrawable;
    private final int mHalfParentWidth;
    private ScaleGestureDetector mScaleDetector;
    private int mLastScrollX;
    private boolean mIsScrolling;
    private boolean mAppScroll;
    private boolean mEnableUserScrolling;

    // The runnable which executes when the scrolling ends
    private Runnable mScrollEndedRunnable = new Runnable() {
        @Override
        public void run() {
            mIsScrolling = false;

            for (ScrollViewListener listener : mScrollListenerList) {
                listener.onScrollEnd(TimelineHorizontalScrollView.this, getScrollX(),
                        getScrollY(), mAppScroll);
            }

            mAppScroll = false;
        }
    };

    public TimelineHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mEnableUserScrolling = true;
        mScrollListenerList = new ArrayList<ScrollViewListener>();
        mHandler = new Handler();

        // Compute half the width of the screen (and therefore the parent view)
        final Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
        mHalfParentWidth = display.getWidth() / 2;

        // This value is shared by all children. It represents the width of
        // the left empty view.
        setTag(R.id.left_view_width, mHalfParentWidth);
        setTag(R.id.playhead_offset, -1);
        setTag(R.id.playhead_type, PLAYHEAD_NORMAL);

        final Resources resources = context.getResources();

        // Get the playhead margins
        mPlayheadMarginTop = (int)resources.getDimension(R.dimen.playhead_margin_top);
        mPlayheadMarginBottom = (int)resources.getDimension(R.dimen.playhead_margin_bottom);
        mPlayheadMarginTopOk = (int)resources.getDimension(R.dimen.playhead_margin_top_ok);
        mPlayheadMarginTopNotOk = (int)resources.getDimension(R.dimen.playhead_margin_top_not_ok);

        // Prepare the playhead drawable
        mNormalPlayheadDrawable = resources.getDrawable(R.drawable.ic_playhead);
        mMoveOkPlayheadDrawable = resources.getDrawable(R.drawable.playhead_move_ok);
        mMoveNotOkPlayheadDrawable = resources.getDrawable(R.drawable.playhead_move_not_ok);
    }

    public TimelineHorizontalScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TimelineHorizontalScrollView(Context context) {
        this(context, null, 0);
    }

    /**
     * Invoked to enable/disable user scrolling (as opposed to programmatic scrolling)
     * @param enable true to enable user scrolling
     */
    public void enableUserScrolling(boolean enable) {
        mEnableUserScrolling = enable;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mScaleDetector.onTouchEvent(ev);
        return mScaleDetector.isInProgress() || super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mEnableUserScrolling) {
            mScaleDetector.onTouchEvent(ev);

            if (!mScaleDetector.isInProgress()) {
                return super.onTouchEvent(ev);
            } else {
                return true;
            }
        } else {
            if (mScaleDetector.isInProgress()) {
                final MotionEvent cancelEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),
                        SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0);
                mScaleDetector.onTouchEvent(cancelEvent);
                cancelEvent.recycle();
            }
            return true;
        }
    }

    /**
     * @param listener The scale listener
     */
    public void setScaleListener(ScaleGestureDetector.SimpleOnScaleGestureListener listener) {
        mScaleDetector = new ScaleGestureDetector(getContext(), listener);
    }

    /**
     * @param listener The listener
     */
    public void addScrollListener(ScrollViewListener listener) {
        mScrollListenerList.add(listener);
    }

    /**
     * @param listener The listener
     */
    public void removeScrollListener(ScrollViewListener listener) {
        mScrollListenerList.remove(listener);
    }

    /**
     * @return true if scrolling is in progress
     */
    public boolean isScrolling() {
        return mIsScrolling;
    }

    /**
     * The app wants to scroll (as opposed to the user)
     *
     * @param scrollX Horizontal scroll position
     * @param smooth true to scroll smoothly
     */
    public void appScrollTo(int scrollX, boolean smooth) {
        if (getScrollX() == scrollX) {
            return;
        }

        mAppScroll = true;

        if (smooth) {
            smoothScrollTo(scrollX, 0);
        } else {
            scrollTo(scrollX, 0);
        }
    }

    /**
     * The app wants to scroll (as opposed to the user)
     *
     * @param scrollX Horizontal scroll offset
     * @param smooth true to scroll smoothly
     */
    public void appScrollBy(int scrollX, boolean smooth) {
        mAppScroll = true;

        if (smooth) {
            smoothScrollBy(scrollX, 0);
        } else {
            scrollBy(scrollX, 0);
        }
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        final int scrollX = getScrollX();
        if (mLastScrollX != scrollX) {
            mLastScrollX = scrollX;

            // Cancel the previous event
            mHandler.removeCallbacks(mScrollEndedRunnable);

            // Post a new event
            mHandler.postDelayed(mScrollEndedRunnable, 300);

            final int scrollY = getScrollY();
            if (mIsScrolling) {
                for (ScrollViewListener listener : mScrollListenerList) {
                    listener.onScrollProgress(this, scrollX, scrollY, mAppScroll);
                }
            } else {
                mIsScrolling = true;

                for (ScrollViewListener listener : mScrollListenerList) {
                    listener.onScrollBegin(this, scrollX, scrollY, mAppScroll);
                }
            }
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        final int playheadOffset = (Integer)getTag(R.id.playhead_offset);
        final int startX;
        if (playheadOffset < 0) {
            // Draw the playhead in the middle of the screen
            startX = mHalfParentWidth + getScrollX();
        } else {
            // Draw the playhead at the specified position (during trimming)
            startX = playheadOffset;
        }

        final int playheadType = (Integer)getTag(R.id.playhead_type);
        final int halfPlayheadWidth = mNormalPlayheadDrawable.getIntrinsicWidth() / 2;
        switch (playheadType) {
            case PLAYHEAD_NORMAL: {
                // Draw the normal playhead
                mNormalPlayheadDrawable.setBounds(
                        startX - halfPlayheadWidth,
                        mPlayheadMarginTop,
                        startX + halfPlayheadWidth,
                        getHeight() - mPlayheadMarginBottom);
                mNormalPlayheadDrawable.draw(canvas);
                break;
            }

            case PLAYHEAD_MOVE_OK: {
                // Draw the move playhead
                mMoveOkPlayheadDrawable.setBounds(
                        startX - halfPlayheadWidth,
                        mPlayheadMarginTopOk,
                        startX + halfPlayheadWidth,
                        mPlayheadMarginTopOk + mMoveOkPlayheadDrawable.getIntrinsicHeight());
                mMoveOkPlayheadDrawable.draw(canvas);
                break;
            }

            case PLAYHEAD_MOVE_NOT_OK: {
                // Draw the move playhead
                mMoveNotOkPlayheadDrawable.setBounds(
                        startX - halfPlayheadWidth,
                        mPlayheadMarginTopNotOk,
                        startX + halfPlayheadWidth,
                        mPlayheadMarginTopNotOk + mMoveNotOkPlayheadDrawable.getIntrinsicHeight());
                mMoveNotOkPlayheadDrawable.draw(canvas);
                break;
            }

            default: {
                break;
            }
        }
    }
}
