package com.android;

import com.high.R;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public final class HighingRefreshListView extends ListView implements
		OnScrollListener {
	// 下拉刷新状�?
	private enum RefreshState {
		Initial, // 可拉伸状�?		
		Refreshing// 刷新状�?
	}

	// 下拉刷新的接�?	
	public interface OnRefreshListener {
		void onRefresh();
	}

	private Context mContext;
	private OnScrollListener mOnScrollListener;// 滚动监听
	private OnRefreshListener mOnRefreshListener;// 下拉刷新监听

	private HeartView heartview;// 顶部水滴控件
	private View headerView;// 顶部加载控件
	TextView tv_refresh;

	private RefreshState refreshState = RefreshState.Initial;// 初始化为可拉伸状�?	
	private int headerViewHeight;// 顶部高度
	private int slimeViewHeight;// 水滴高度

	private float oldY = 0;// Y轴原来高�?
	private float LastY = 0;// Y轴原来高�?
	private int LastHeight;// 顶部视图原来高度
	boolean ishasrefresh = false;// 是否已经刷新过了

	private boolean mIsTop = true;
	private boolean mIsGoingtoRefresh = false;
	private boolean isInFrefresh = false;

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

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

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

	/**
	 * 初始�?	 * 
	 * @param context
	 */

	private void init(Context context) {
		headerView = LayoutInflater.from(context).inflate(R.layout.header_view,
				null);
		heartview = (HeartView) headerView.findViewById(R.id.heartview);
		tv_refresh = (TextView) headerView.findViewById(R.id.tv_refresh);
		addHeaderView(headerView);

		super.setOnScrollListener(this);
		measureView(headerView);
		measureView(tv_refresh);
		measureView(heartview);
		headerViewHeight = headerView.getMeasuredHeight();
		slimeViewHeight = heartview.getMeasuredHeight();
		Hidereset();
		tv_refresh.setText("往下拉,有更新");
	}

	/**
	 * 绘制子试�?	 * 
	 * @param child
	 */
	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}

		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		child.measure(childWidthSpec, childHeightSpec);
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (this.mOnScrollListener != null
				&& refreshState != RefreshState.Refreshing) {
			this.mOnScrollListener.onScrollStateChanged(view, scrollState);
		}
		switch (scrollState) {
		// 当不滚动�?		
		case OnScrollListener.SCROLL_STATE_IDLE:
			// 判断滚动到底�?			
			if (this.getLastVisiblePosition() == (this.getCount() - 1)) {
			}
			// 判断滚动到顶�?
			if (this.getFirstVisiblePosition() == 0) {
				mIsTop = true;
			} else {
				mIsTop = false;
			}

			break;
		}
	}

	@SuppressLint("NewApi")
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:// 手指按下时,记录初始高度为headerViewHeight

			Log.d("SlimeRefreshListView", "ACTION_DOWN");
			oldY = event.getY();
			LastY = event.getY();
			Log.d("LastHeight", LastHeight + "");
			LastHeight = headerViewHeight;
			break;
		case MotionEvent.ACTION_MOVE:// 手指移动过程中,更新头部高度和水滴形�?			Log.d("SlimeRefreshListView", "ACTION_MOVE");
			applyHeaderLayout(event);// 传�?事件处理
			break;
		case MotionEvent.ACTION_UP:// 手指抬起,headerview回复到原来的初始位置
			Log.d("SlimeRefreshListView", "ACTION_UP");
			if (mIsTop && mIsGoingtoRefresh) {
				tv_refresh.setText("嗯~啊~要出来了。。。");
				reset();
				refreshState = RefreshState.Refreshing;// 更改刷新状�?
				heartview.refresh();
				heartview.setRotation(0);
				isInFrefresh = true;
				onRefresh();// 触发刷新事件
				mIsGoingtoRefresh = false;

			} else{ 
				if (!isInFrefresh) {
					Hidereset();	
				}
			}
			break;
		default:
			break;
		}
		return super.onTouchEvent(event);
	}

	private void Hidereset() {
		// 复位后修复headerview的高度和padding
		LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
				headerViewHeight);
		headerView.setPadding(0, 50, 0, 0);
		headerView.setLayoutParams(params);

		ishasrefresh = false;

		// 复位后修复waterView的参�?		
		LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(45, 0);
		heartview.setLayoutParams(params2);

	}

	/**
	 * 初始化参�?	 */
	private void reset() {// headerview回复到原来的初始高度

		// 复位后修复headerview的高度和padding
		LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
				headerViewHeight + 240);
		headerView.setPadding(0, 240, 0, 0);
		headerView.setLayoutParams(params);

		ishasrefresh = false;

		// 复位后修复waterView的参�?		
		LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(45,
				slimeViewHeight);
		heartview.setLayoutParams(params2);

	}

	/**
	 * 移动过程�?在可拉动距离之内,更新水滴的形状 ,超过拉动的距离,�?��更新
	 * 
	 * @param ev
	 */
	@SuppressLint("NewApi")
	private void applyHeaderLayout(MotionEvent ev) {
		int historicalY = (int) ev.getY();
		if (!isInFrefresh) {
			if (historicalY != LastY) {
				if (mIsTop) {
					setSelection(0);
				}

				int h = (int) (LastHeight + historicalY - LastY);
				/* 绘制水滴效果 */
				LayoutParams params = new LayoutParams(
						LayoutParams.MATCH_PARENT, h);

				headerView.setLayoutParams(params);

				if (mIsGoingtoRefresh) {
					headerView.setPadding(0, h - 220, 0, 0);
				} else {
					headerView.setPadding(0, 140, 0, 0);
					int mH = (h - 220) > 0 ? (h - 220) : 0;

					LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(
							45, mH);
					params2.setMargins(0, 20, 0, 0);
					heartview.setLayoutParams(params2);
				}
				LastHeight = h;
				LastY = historicalY;
			}

		}

		if (refreshState == RefreshState.Initial && mIsTop) {

			if (historicalY - oldY < 220 && historicalY < 800) {// 在可拉动距离之内,更新水滴的形状

				Log.d("SlimeRefreshListView", "�?��绘制");

				// 未在刷新中,更改状�?
				ishasrefresh = false;
				mIsGoingtoRefresh = false;

			} else {// 超过拉动的距离,�?��更新
				if (!ishasrefresh && historicalY - oldY > 220// 触发刷新动画
						&& historicalY < 800) {// 避免�?��拉到头多次触发更新事�?					// 正在刷新中,更改状�?
					mIsGoingtoRefresh = true;
					ishasrefresh = true;

					// 震动
					Vibrator mVibrator01 = (Vibrator) mContext
							.getSystemService(Service.VIBRATOR_SERVICE);
					mVibrator01.vibrate(new long[] { 10, 10 }, -1);

					// 动画
					Animation rock = new RotateAnimation(0f, 180f,
							Animation.RELATIVE_TO_SELF, 0.5f,
							Animation.RELATIVE_TO_SELF, 0.5f);
					rock.setFillAfter(false);
					rock.setDuration(150);
					heartview.startAnimation(rock);
					heartview.setRotation(180);
					tv_refresh.setText("爱卿,快放开朕~");
				}
			}
		}
	}

	@Override
	public void setAdapter(ListAdapter adapter) {
		super.setAdapter(adapter);
		// setSelection(0);
	}

	@Override
	public void setOnScrollListener(AbsListView.OnScrollListener l) {
		this.mOnScrollListener = l;
	}

	public void onRefreshComplete() {
		tv_refresh.setText("往下拉,有更新");
		isInFrefresh = false;
		heartview.stopRefresh();
		refreshState = RefreshState.Initial;
		Hidereset();
	}

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

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