package com.inuker.bluetooth.view;

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import com.inuker.bluetooth.R;

public class PullRefreshListView extends ListView implements OnScrollListener, PullHeadView.OnStateListerer {
	private static final int STATE_NORMAL = 0;
	private static final int STATE_READY = 1;
	private static final int STATE_PULL = 2;
	private static final int STATE_UPDATING = 3;
	private static final int INVALID_POINTER_ID = -1;
	protected PullHeadView mListHeaderView;
	private int mActivePointerId;
	private float mLastY;
	private int mState;
	private int mTouchSlop;
	private Context mContext;
	private PullHeadView mHeadView;
	private int mHeaderHeight = 0;
	protected boolean hasHeader;
	protected boolean hasMoreData = true;
	protected boolean isCanLoadMore = true;
	protected boolean isNeedRetry = false;
	protected boolean isAutoLoading = true;
	protected boolean isBusy = false;
	protected OnRefreshListener mOnRefreshListener;
	protected startListener mListener;
	protected OnClickFootViewListener mFootViewListener;
	protected OnScrollPositionListener mScrollPositionListener;

	public PullRefreshListView(Context context) {
		super(context);
		this.mContext = context;
	}

	public PullRefreshListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.mContext = context;
	}

	public PullRefreshListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
	}

	public void initView() {
		if (hasHeader) {
			mListHeaderView = new PullHeadView(mContext);
			mListHeaderView.setStateListener(this);
			setHeaderDividersEnabled(false);
			setFooterDividersEnabled(false);
			addHeaderView(mListHeaderView, null, false);
			mState = STATE_NORMAL;
			final ViewConfiguration configuration = ViewConfiguration
					.get(mContext);
			mTouchSlop = configuration.getScaledTouchSlop();
		}
		
		super.setOnScrollListener(this);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		if (hasHeader) {
			if (mState == STATE_UPDATING) {
				return super.dispatchTouchEvent(ev);
			}
			final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
				mLastY = ev.getY();
				isFirstViewTop();
				break;
			case MotionEvent.ACTION_MOVE:
				if (mActivePointerId == INVALID_POINTER_ID) {
					break;
				}

				if (mState == STATE_NORMAL) {
					isFirstViewTop();
				}

				if (mState == STATE_READY) {
					final int activePointerId = mActivePointerId;
					final int activePointerIndex = MotionEventCompat
							.findPointerIndex(ev, activePointerId);
					final float y = MotionEventCompat.getY(ev,
							activePointerIndex);
					final int deltaY = (int) (y - mLastY);
					if (deltaY <= 0 || Math.abs(deltaY) < mTouchSlop) {
						mState = STATE_NORMAL;
					} else {
						mLastY = y;
						mState = STATE_PULL;
						ev.setAction(MotionEvent.ACTION_CANCEL);
						super.dispatchTouchEvent(ev);
					}
				}

				if (mState == STATE_PULL) {
					final int activePointerId = mActivePointerId;
					final int activePointerIndex = MotionEventCompat
							.findPointerIndex(ev, activePointerId);
					final float y = MotionEventCompat.getY(ev,
							activePointerIndex);
					final int deltaY = (int)(y - mLastY);
					mLastY = y;
					mHeaderHeight += deltaY;
					setHeaderHeight(mHeaderHeight * 4 / 9);
//					final int headerHeight = mListHeaderView.getHeight();
//					setHeaderHeight(headerHeight + deltaY * 4 / 9);
					return true;
				}

				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				mActivePointerId = INVALID_POINTER_ID;
				if (mState == STATE_PULL) {
					update();
				}
				break;
			case MotionEventCompat.ACTION_POINTER_DOWN:
				final int index = MotionEventCompat.getActionIndex(ev);
				final float y = MotionEventCompat.getY(ev, index);
				mLastY = y;
				mActivePointerId = MotionEventCompat.getPointerId(ev, index);
				break;
			case MotionEventCompat.ACTION_POINTER_UP:
				onSecondaryPointerUp(ev);
				break;
			}
		}
		return super.dispatchTouchEvent(ev);
	}

	private void onSecondaryPointerUp(MotionEvent ev) {
		final int pointerIndex = MotionEventCompat.getActionIndex(ev);
		final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
		if (pointerId == mActivePointerId) {
			final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
			mLastY = MotionEventCompat.getY(ev, newPointerIndex);
			mActivePointerId = MotionEventCompat.getPointerId(ev,
					newPointerIndex);
		}
	}

	private void setHeaderHeight(int height) {
		mListHeaderView.setHeaderHeight(height);
	}

	private boolean isFirstViewTop() {
		final int count = getChildCount();
		if (count == 0) {
			return true;
		}
		final int firstVisiblePosition = this.getFirstVisiblePosition();
		final View firstChildView = getChildAt(0);
		boolean needs = firstChildView.getTop() == 0
				&& (firstVisiblePosition == 0);
		if (needs) {
			mState = STATE_READY;
		}

		return needs;
	}

	/**
	 * 在下拉刷新完成后更换状态
	 * 
	 * @param refreshSuccess
	 *            是否获取数据成功
	 */
	public void onRefreshComplete(boolean refreshSuccess) {
		if (mListHeaderView != null) {
			if (mState == STATE_UPDATING) {
				mListHeaderView.reset(STATE_NORMAL);
			}
			if(refreshSuccess){
				mListHeaderView.updateLastTimeLable();
			}
		}
	}

	public void setState(int state) {
		mState = state;
	}

	private void update() {
		if (mListHeaderView.isUpdateNeeded()) {
	          mListHeaderView.startUpdate();
	            mState = STATE_UPDATING;
			if (mOnRefreshListener != null) {
				mOnRefreshListener.onRefresh();
			}

		} else {
			mListHeaderView.reset(STATE_NORMAL);
		}
	}

	@Override
	public void onReset() {
		mState = STATE_NORMAL;
		mHeaderHeight = 0;
	}
	
	public boolean canHandleItemClick() {
	    return mState == STATE_NORMAL || mState == STATE_READY;
	}
	
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		
		if (mScrollPositionListener != null) {
			mScrollPositionListener.onScroll(view, firstVisibleItem,
					visibleItemCount, totalItemCount);
		}
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {

		switch (scrollState) {
		case OnScrollListener.SCROLL_STATE_IDLE:
			isBusy = false;
			int first = getFirstVisiblePosition();
			int count = getChildCount();
			int nHeadCount = getHeaderViewsCount();
			int currPosition;
			for (int i = 0; i < count; i++) {
				currPosition = first - nHeadCount + i;
				if (currPosition == -nHeadCount) {
					continue;// 下拉刷新标题栏
				}
				if (currPosition >= getCount()) {// 加载更多布局显示的时候
					return;
				}
				if (mListener != null) {
					mListener.serListViewBusy(currPosition, i);
				}
			}
			break;
		case OnScrollListener.SCROLL_STATE_FLING:
			isBusy = true;
			break;
		case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
			isBusy = true;
			break;
		default:
			break;
		}

		if (mScrollPositionListener != null) {
			mScrollPositionListener.onScrollStateChanged(view, scrollState);
		}
	}

	public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
		mOnRefreshListener = onRefreshListener;
	}

	public void setOnClickFootViewListener(OnClickFootViewListener listener) {
		mFootViewListener = listener;
	}

	public void setPullTimeTag(String ptg) {
		mListHeaderView.setTimeTag(ptg);
	}

	public boolean isHasMoreData() {
		return hasMoreData;
	}

	public void setHasMoreData(boolean hasMoreData) {
		this.hasMoreData = hasMoreData;
	}

	public boolean isHasHeader() {
		return hasHeader;
	}

	public void setHasHeader(boolean hasHeader) {
		this.hasHeader = hasHeader;
	}

	public boolean isBusy() {
		return this.isBusy;
	}

	public void onRefresh() {
		if (mOnRefreshListener != null) {
			if (hasHeader) {
				mOnRefreshListener.onRefresh();
			}
		}
	}

	public interface OnRefreshListener {
		public void onRefresh();
	}

	public interface OnScrollPositionListener {
		public void onScrollStateChanged(AbsListView view, int scrollState);

		public void onScroll(AbsListView view, int firstVisibleItem,
							 int visibleItemCount, int totalItemCount);
	}

	public interface OnClickFootViewListener {

		public void onClickFootView();
	}

	public interface startListener {
		public void serListViewBusy(int currPosition, int tag);
	}

	public void setSartListener(startListener listener) {
		this.mListener = listener;
	}

	@Override
	public boolean onTrackballEvent(MotionEvent event) {
		return true;
	}

	public boolean isAutoLoading() {
		return isAutoLoading;
	}

	public void startUpdateImmediate() {
		if (mState == STATE_UPDATING) {
			return;
		}
		setSelectionFromTop(0, 0);
		mListHeaderView.moveToUpdateHeight();
		update();
	}

	public OnScrollPositionListener getOnScrollPositionListener() {
		return mScrollPositionListener;
	}

	public void setOnScrollPositionListener(
			OnScrollPositionListener mScrollPositionListener) {
		this.mScrollPositionListener = mScrollPositionListener;
	}

	public void Clear() {
		if (mHeadView != null) {
			removeHeaderView(mHeadView);
		}
		removeAllViewsInLayout();
	}
    
	public void applyPullRefreshViewTheme(){
		if(mContext!=null){
			this.setBackgroundColor(mContext.getResources().getColor(R.color.timeline_home_bg_color));
		}
		if(mListHeaderView!=null){
			mListHeaderView.applyPullHeadViewTheme();
		}
		if(mHeadView!=null){
			mHeadView.applyPullHeadViewTheme();
		}
	}
}