package com.kdanmobile.reader.view;

import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * @类名:HorizontalView
 * @类描述:自定义线性布局，实现布局整个滑动功能
 * @作者:zhouguifang
 * @创建时间:2015-7-6-下午5:59:49
 * @修改人:
 * @修改时间:
 * @修改备注:
 * @版本:
 * @Copyright:(c)-2015kdan mobile
 */
@SuppressWarnings("ALL")
public class HorizontalView extends LinearLayout implements
		GestureDetector.OnGestureListener {
	// private static final String TAG = "Scroller";
	private final GestureDetector mGestureDetector;

	private Scroller mScroller;

	private float last_position = 0;
	private float start_position = 0;

	private float x1, x2, y1, y2;
	private boolean isFirst = true;
	private boolean isResult = false;

	private int moveDistance = 266;
	public boolean isOpen = false;
	private boolean isOk = false;
	private boolean isScroll = true;

	private boolean isFirstPager = true;

	private static final int MOVING_DIAGONALLY = 0;
	private static final int MOVING_LEFT = 1;
	private static final int MOVING_RIGHT = 2;
	private static final int MOVING_UP = 3;
	private static final int MOVING_DOWN = 4;

	public HorizontalView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mScroller = new Scroller(context);
		mGestureDetector = new GestureDetector(this);
	}

	public void setScroll(boolean isScroll) {
		this.isScroll = isScroll;
	}

	public void setFirstPager(boolean isFirstPager) {
		this.isFirstPager = isFirstPager;
	}

	@Override
	public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
		// Out.println("dispatchTouchEvent...");
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// Out.println("ACTION_DOWN...");
			x1 = ev.getX();
			y1 = ev.getY();
			break;
		case MotionEvent.ACTION_MOVE:
			// Out.println("ACTION_MOVE...");
			if (isFirst) {
				x2 = ev.getX();
				y2 = ev.getY();
				float x = Math.abs(x1 - x2);
				float y = Math.abs(y1 - y2);
				float distance = (x * x) + (y * y);
				// Out.println("isFirst...dis:" + distance);
				DisplayMetrics displayMetrics = new DisplayMetrics();
                Activity activity = (Activity) getContext();
                activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
                float density = displayMetrics.density;
				if (distance > (density * 5)) {
					isFirst = false;
					if (x > y) {
						// 第一页向右滑动||第一页向左滑动且控件是打开的
						if ((((x1 - x2) < 0) && isFirstPager)
                                || (((x1 - x2) > 0) && isFirstPager && isOpen)) {
							isResult = true;
							start_position = ev.getX();
							last_position = ev.getX();
						}
					}
				}
			}
			break;
		case MotionEvent.ACTION_UP:
			// LogUtil.print_i(HorizontalView.class,"ACTION_UP...");
			isFirst = true;
			isResult = false;
			break;
		}
		return super.dispatchTouchEvent(ev);
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
        return isScroll && isResult || super.onInterceptTouchEvent(ev);
    }

	@Override
	public boolean onTouchEvent(@NonNull MotionEvent event) {
		mGestureDetector.onTouchEvent(event);
		int action = event.getAction();
		float x = event.getX();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			start_position = event.getX();
			last_position = event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			// LogUtil.print_i(HorizontalView.class,"onTouchEvent...ACTION_MOVE");
			float distant = x - start_position;
			if (!isOpen) {
				if (distant > moveDistance) {
					distant = moveDistance;
				}
				if (distant < 0) {
					distant = 0;
				}
				x = distant + start_position;
			} else {
				if (distant > 0) {
					distant = 0;
				}
				if (distant < -moveDistance) {
					distant = -moveDistance;
				}
			}
			x = distant + start_position;
			smoothScrollBy((int) (last_position - x), 0, 0);
			last_position = x;
			break;
		case MotionEvent.ACTION_UP:
			if (!isOk) {
				if (isOpen) {
					if ((mScroller.getFinalX() + ((moveDistance * 7) / 8)) > 0) {
						smoothScrollTo(0, 0);
						isOpen = false;
					} else {
						smoothScrollTo(0 - moveDistance, 0);
						isOpen = true;
					}
				} else {
					if ((mScroller.getFinalX() + ((moveDistance) / 8)) > 0) {
						smoothScrollTo(0, 0);
						isOpen = false;
					} else {
						smoothScrollTo(0 - moveDistance, 0);
						isOpen = true;
					}
				}
			}
			isOk = false;
			return false;
		}
		return super.onTouchEvent(event);
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
		switch (directionOfTravel(velocityX, velocityY)) {
		case MOVING_LEFT:
			smoothScrollTo(0, 0);
			isOpen = false;
			break;
		case MOVING_RIGHT:
			smoothScrollTo(0 - moveDistance, 0);
			isOpen = true;
			break;
		default:
			// LogUtil.print_i(HorizontalView.class,"x:" + mScroller.getFinalX() + "  Y:"
			// + mScroller.getFinalY());
			if (isOpen) {
				if ((mScroller.getFinalX() + ((moveDistance * 7) / 8)) > 0) {
					smoothScrollTo(0, 0);
					isOpen = false;
				} else {
					smoothScrollTo(0 - moveDistance, 0);
					isOpen = true;
				}
			} else {
				if ((mScroller.getFinalX() + ((moveDistance) / 8)) > 0) {
					smoothScrollTo(0, 0);
					isOpen = false;
				} else {
					smoothScrollTo(0 - moveDistance, 0);
					isOpen = true;
				}
			}
			break;
		}
		isOk = true;
		return true;
	}

	public void animateToggle() {
		if (isOpen) {
			smoothScrollTo(0, 0);
		} else {
			smoothScrollTo(0 - moveDistance, 0);
		}
		isOpen = !isOpen;
	}
	
	/**
	 * @方法说明:计算移动方向
	 * @方法名称:directionOfTravel
	 * @param vx
	 * @param vy
	 * @return
	 * @返回值:int
	 */
	private static int directionOfTravel(float vx, float vy) {
		if (Math.abs(vx) > (2 * Math.abs(vy)))
			return (vx > 0) ? MOVING_RIGHT : MOVING_LEFT;
		else if (Math.abs(vy) > (2 * Math.abs(vx)))
			return (vy > 0) ? MOVING_DOWN : MOVING_UP;
		else
			return MOVING_DIAGONALLY;
	}

	/**
	 * @方法说明:调用此方法滚动到目标位置
	 * @方法名称:smoothScrollTo
	 * @param fx
	 * @param fy
	 * @返回值:void
	 */
	public void smoothScrollTo(int fx, int fy) {
		int dx = fx - mScroller.getFinalX();
		int dy = fy - mScroller.getFinalY();
		smoothScrollBy(dx, dy);
	}

	/**
	 * @方法说明:调用此方法滚动到目标位置
	 * @方法名称:smoothScrollTo
	 * @param fx
	 * @param fy
	 * @param drution
	 * @返回值:void
	 */
	public void smoothScrollTo(int fx, int fy, int drution) {
		int dx = fx - mScroller.getFinalX();
		int dy = fy - mScroller.getFinalY();
		mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx,
				dy, drution);
		invalidate();
	}

	/**
	 * @方法说明:调用此方法设置滚动的相对偏移
	 * @方法名称:smoothScrollBy
	 * @param dx
	 * @param dy
	 * @返回值:void
	 */
	public void smoothScrollBy(int dx, int dy) {
		// 设置mScroller的滚动偏移量
		mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx,
				dy, 500);
		invalidate();// 这里必须调用invalidate()才能保证computeScroll()会被调用，否则不一定会刷新界面，看不到滚动效果
	}

	public void smoothScrollBy(int dx, int dy, int drution) {
		// 设置mScroller的滚动偏移量
		mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx,
				dy, drution);
		invalidate();// 这里必须调用invalidate()才能保证computeScroll()会被调用，否则不一定会刷新界面，看不到滚动效果
	}

	@Override
	public void computeScroll() {
		// 先判断mScroller滚动是否完成
		if (mScroller.computeScrollOffset()) {
			// 这里调用View的scrollTo()完成实际的滚动
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

			// 必须调用该方法，否则不一定能看到滚动效果
			postInvalidate();
		}
		super.computeScroll();
	}

	public void setMoveDistance(int distance) {
		moveDistance = distance;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                            float distanceY) {
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {

	}
}
