package com.socks.zlistview.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Scroller;

import com.socks.zlistview.R;

/**
 * 
 * @class: com.socks.zlistview.ZListView
 * @author zhaokaiqiang
 * @date 2015-1-4 下午10:37:06
 * 
 */
public class ZListView extends ListView {

	private final static int SCROLLBACK_HEADER = 0;
	private final static int SCROLLBACK_FOOTER = 1;
	// 滑动时长
	private final static int SCROLL_DURATION = 400;
	// 加载更多的距离
	private final static int PULL_LOAD_MORE_DELTA = 100;
	// 滑动比例
	private final static float OFFSET_RADIO = 2f;
	// 记录按下点的y坐标
	private float lastY;
	// 用来回滚
	private Scroller scroller;
	private IXListViewListener mListViewListener;
	private ZListViewHeader headerView;
	private RelativeLayout headerViewContent;
	// header的高度
	private int headerHeight;
	// 是否能够刷新
	private boolean enableRefresh = true;
	// 是否正在刷新
	private boolean isRefreashing = false;
	// footer
	private ZListViewFooter footerView;
	// 是否可以加载更多
	private boolean enableLoadMore;
	// 是否正在加载
	private boolean isLoadingMore;
	// 是否footer准备状态
	private boolean isFooterAdd = false;
	// item的总数
	private int totalItemCount;
	// 记录是从header还是footer返回
	private int mScrollBack;

	public ZListView(Context context) {
		super(context);
		initView(context);
	}

	public ZListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	public ZListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView(context);
	}

	private void initView(Context context) {

		scroller = new Scroller(context, new DecelerateInterpolator());

		headerView = new ZListViewHeader(context);
		footerView = new ZListViewFooter(context);

		headerViewContent = (RelativeLayout) headerView
				.findViewById(R.id.xlistview_header_content);
		headerView.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {
					@SuppressWarnings("deprecation")
					@Override
					public void onGlobalLayout() {
						headerHeight = headerViewContent.getHeight();
						getViewTreeObserver()
								.removeGlobalOnLayoutListener(this);
					}
				});
		addHeaderView(headerView);

	}

	@Override
	public void setAdapter(ListAdapter adapter) {
		// 确保footer最后添加并且只添加一次
		if (isFooterAdd == false) {
			isFooterAdd = true;
			addFooterView(footerView);
		}
		super.setAdapter(adapter);

	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {

		totalItemCount = getAdapter().getCount();
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 记录按下的坐标
			lastY = ev.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			// 计算移动距离
			float deltaY = ev.getRawY() - lastY;
			lastY = ev.getRawY();
			// 是第一项并且标题已经显示或者是在下拉
			if (getFirstVisiblePosition() == 0
					&& (headerView.getVisiableHeight() > 0 || deltaY > 0)) {
				updateHeaderHeight(deltaY / OFFSET_RADIO);
			} else if (getLastVisiblePosition() == totalItemCount - 1
					&& (footerView.getBottomMargin() > 0 || deltaY < 0)) {
				updateFooterHeight(-deltaY / OFFSET_RADIO);
			}
			break;

		case MotionEvent.ACTION_UP:

			if (getFirstVisiblePosition() == 0) {
				if (enableRefresh
						&& headerView.getVisiableHeight() > headerHeight) {
					isRefreashing = true;
					headerView.setState(ZListViewHeader.STATE_REFRESHING);
					if (mListViewListener != null) {
						mListViewListener.onRefresh();
					}
				}
				resetHeaderHeight();
			} else if (getLastVisiblePosition() == totalItemCount - 1) {
				if (enableLoadMore
						&& footerView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {
					startLoadMore();
				}
				resetFooterHeight();
			}
			break;
		}
		return super.onTouchEvent(ev);
	}

	@Override
	public void computeScroll() {

		// 松手之后调用
		if (scroller.computeScrollOffset()) {

			if (mScrollBack == SCROLLBACK_HEADER) {
				headerView.setVisiableHeight(scroller.getCurrY());
			} else {
				footerView.setBottomMargin(scroller.getCurrY());
			}
			postInvalidate();
		}
		super.computeScroll();

	}

	public void setPullRefreshEnable(boolean enable) {
		enableRefresh = enable;

		if (!enableRefresh) {
			headerView.hide();
		} else {
			headerView.show();
		}
	}

	public void setPullLoadEnable(boolean enable) {
		enableLoadMore = enable;
		if (!enableLoadMore) {
			footerView.hide();
			footerView.setOnClickListener(null);
		} else {
			isLoadingMore = false;
			footerView.show();
			footerView.setState(ZListViewFooter.STATE_NORMAL);
			footerView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					startLoadMore();
				}
			});
		}
	}

	public void stopRefresh() {
		if (isRefreashing == true) {
			isRefreashing = false;
			resetHeaderHeight();
		}
	}

	public void stopLoadMore() {
		if (isLoadingMore == true) {
			isLoadingMore = false;
			footerView.setState(ZListViewFooter.STATE_NORMAL);
		}
	}

	private void updateHeaderHeight(float delta) {
		headerView.setVisiableHeight((int) delta
				+ headerView.getVisiableHeight());
		// 未处于刷新状态,更新箭头
		if (enableRefresh && !isRefreashing) {
			if (headerView.getVisiableHeight() > headerHeight) {
				headerView.setState(ZListViewHeader.STATE_READY);
			} else {
				headerView.setState(ZListViewHeader.STATE_NORMAL);
			}
		}

	}

	private void resetHeaderHeight() {
		// 当前的可见高度
		int height = headerView.getVisiableHeight();
		// 如果正在刷新并且高度没有完全展示
		if ((isRefreashing && height <= headerHeight) || (height == 0)) {
			return;
		}
		// 默认会回滚到header的位置
		int finalHeight = 0;
		// 如果是正在刷新状态,则回滚到header的高度
		if (isRefreashing && height > headerHeight) {
			finalHeight = headerHeight;
		}
		mScrollBack = SCROLLBACK_HEADER;
		// 回滚到指定位置
		scroller.startScroll(0, height, 0, finalHeight - height,
				SCROLL_DURATION);
		// 触发computeScroll
		invalidate();
	}

	private void updateFooterHeight(float delta) {
		int height = footerView.getBottomMargin() + (int) delta;
		if (enableLoadMore && !isLoadingMore) {
			if (height > PULL_LOAD_MORE_DELTA) {
				footerView.setState(ZListViewFooter.STATE_READY);
			} else {
				footerView.setState(ZListViewFooter.STATE_NORMAL);
			}
		}
		footerView.setBottomMargin(height);

	}

	private void resetFooterHeight() {
		int bottomMargin = footerView.getBottomMargin();
		if (bottomMargin > 0) {
			mScrollBack = SCROLLBACK_FOOTER;
			scroller.startScroll(0, bottomMargin, 0, -bottomMargin,
					SCROLL_DURATION);
			invalidate();
		}
	}

	private void startLoadMore() {
		isLoadingMore = true;
		footerView.setState(ZListViewFooter.STATE_LOADING);
		if (mListViewListener != null) {
			mListViewListener.onLoadMore();
		}
	}

	public void setXListViewListener(IXListViewListener l) {
		mListViewListener = l;
	}

	public interface IXListViewListener {

		public void onRefresh();

		public void onLoadMore();
	}
}