package com.wasu.cs.widget;

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

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import cn.com.wasu.main.AppUtil;
import cn.com.wasu.main.R;

import com.wasu.widget.util.UIUtil;

public class HorizontalListView extends FrameLayout {

	private Context context;

	public HorizontalListView(Context context) {
		super(context);
		init(context);
	}

	public HorizontalListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public HorizontalListView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context);
	}

	private void init(Context c) {
		context = c;
		setChildrenDrawingOrderEnabled(true);
		setClipChildren(false);
		setClipToPadding(false);
	}

	private Stack<ViewPackage> viewPackages = new Stack<ViewPackage>();
	private BaseAdapter adapter;
	private boolean isFirstLoad = true;
	private int showItemCount = 5;
	private int currentIndex = 0;

	public void setAdapter(BaseAdapter adapter) {
		this.viewPackages.clear();
		this.adapter = adapter;
		if (isFirstLoad) {
			firstLoadViews();
			isFirstLoad = false;
		} else {
			reloadAllView();
		}
	}

	private ViewPackage createViewPackage(int position, View preItem) {
		View view = adapter.getView(position, null, null);

		if (view == null)
			return null;

		LayoutParams lp = new FrameLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		lp.leftMargin = 0;
		view.setLayoutParams(lp);

		ViewPackage vp = new ViewPackage(view);
		vp.setPosition(position);
		vp.setId(AppUtil.createId());

		if (preItem != null) {
			preItem.setNextFocusRightId(view.getId());
			view.setNextFocusLeftId(preItem.getId());
		}

		return vp;
	}

	private void firstLoadViews() {
		if (adapter == null)
			return;

		removeAllViews();
		int count = adapter.getCount();
		int index = count;
		View preView = null;
		ViewPackage vp = null;
		if (count > showItemCount) {
			index = showItemCount;

			vp = createViewPackage(count - 1, preView);
			if (vp != null) {
				addView(vp.getView());
				viewPackages.add(vp);
				preView = vp.getView();
			}
		}

		for (int i = 0; i < index; i++) {
			vp = createViewPackage(i, preView);
			if (vp != null) {
				addView(vp.getView());
				viewPackages.add(vp);
				preView = vp.getView();
			}
		}

		if (count > showItemCount) {
			int position = 0;
			if (count > showItemCount + 1) {
				position = showItemCount;
			}

			vp = createViewPackage(position, preView);
			if (vp != null) {
				addView(vp.getView());
				viewPackages.add(vp);
				preView = vp.getView();
			}
		}

	}

	private void reloadAllView() {

	}

	private boolean isInitLayout = false;
	private int mSpacing = 46;

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		if (isInitLayout || this.adapter == null
				|| this.adapter.getCount() == 0)
			return;

		int i = 0;
		View child = null;
		int left = 0;
		int pHeight = b - t;

		if (adapter.getCount() > showItemCount) {
			child = viewPackages.get(i).getView();

			left = -child.getMeasuredWidth();
			int top = (pHeight - child.getMeasuredHeight()) / 2;
			int right = left + child.getMeasuredWidth();
			int bottom = top + child.getMeasuredHeight();
			child.layout(left, top, right, bottom);

			i++;
		}

		left = getPaddingLeft();

		while (i < viewPackages.size()) {
			child = viewPackages.get(i).getView();

			int top = (pHeight - child.getMeasuredHeight()) / 2;
			int right = left + child.getMeasuredWidth();
			int bottom = top + child.getMeasuredHeight();
			child.layout(left, top, right, bottom);

			left += child.getMeasuredWidth() + mSpacing;

			i++;
		}

		modifyPosition();

		isInitLayout = true;
	}

	private View newItem = null;

	private void fillLeft() {
		ViewPackage firstVp = viewPackages.firstElement();
		int firstPosition = firstVp.getPosition();
		View firstView = firstVp.getView();

		ViewPackage vp = viewPackages.pop();
		View view = vp.getView();
		int position = firstPosition - 1;
		if (position < 0) {
			position = adapter.getCount() - 1;
		}
		View newView = adapter.getView(position, view, null);

		if (newView == null)
			return;

//		newView.setVisibility(View.GONE);
		vp.setView(newView);
		vp.setPosition(position);

		viewPackages.insertElementAt(vp, 0);

		firstView.setNextFocusLeftId(newView.getId());
		newView.setNextFocusRightId(firstView.getId());

		int left = -newView.getMeasuredWidth();
		int top = newView.getTop();
		int right = left + newView.getMeasuredWidth();
		int bottom = newView.getBottom();
		newView.layout(left, top, right, bottom);
		newView.setX(left);
//		newView.setVisibility(View.VISIBLE);
		newView.setFocusable(false);
		newItem = newView;

		modifyPosition();
	}

	private void fillRight() {
		ViewPackage lastVp = viewPackages.lastElement();
		int lastPosition = lastVp.getPosition();
		View lastView = lastVp.getView();

		ViewPackage vp = viewPackages.get(0);
		View view = vp.getView();
		viewPackages.remove(0);
		int position = lastPosition + 1;
		if (position + 1 > adapter.getCount()) {
			position = 0;
		}
		View newView = adapter.getView(position, view, null);

		if (newView == null)
			return;

//		newView.setVisibility(View.GONE);
		vp.setView(newView);
		vp.setPosition(position);

		viewPackages.add(vp);

		lastView.setNextFocusRightId(newView.getId());
		newView.setNextFocusLeftId(lastView.getId());

		int left = (int) (lastView.getLeft() + lastView.getMeasuredWidth())
				+ mSpacing;
		int top = newView.getTop();
		int right = left + newView.getMeasuredWidth();
		int bottom = newView.getBottom();
		newView.layout(left, top, right, bottom);
		newView.setX(left);
//		newView.setVisibility(View.VISIBLE);
		newView.setFocusable(false);
		newItem = newView;

		modifyPosition();
	}

	private void scrollPreItem() {
		fillLeft();
		animViews(false);
	}

	private void scrollNextItem() {
		fillRight();
		animViews(true);
	}

	private int anim_duration = 200;

	private void animViews(boolean scrollLeft) {
		int count = viewPackages.size();
		if (count > showItemCount) {
			List<Animator> animators = new ArrayList<Animator>();
			AnimatorSet animatorSet = new AnimatorSet();

			int i = 0;
			View child = viewPackages.get(i).getView();
			ObjectAnimator viewAnim = null;
			if (scrollLeft) {
				viewAnim = ObjectAnimator.ofFloat(child, "X",
						-child.getMeasuredWidth());
				viewAnim.setDuration(anim_duration);
				viewAnim.setInterpolator(new AccelerateDecelerateInterpolator());
				animators.add(viewAnim);

			}

			i++;

			int x = 0;
			View tempView = null;
			for (; i < count; i++) {
				child = viewPackages.get(i).getView();
				if (tempView == null) {
					x = getPaddingLeft();
				} else {
					x += tempView.getMeasuredWidth() + mSpacing;
				}

				viewAnim = ObjectAnimator.ofFloat(child, "X", x);
				viewAnim.setDuration(anim_duration);
				viewAnim.setInterpolator(new AccelerateDecelerateInterpolator());
				animators.add(viewAnim);

				tempView = child;
			}

			animatorSet.playTogether(animators);
			animatorSet.addListener(new AnimatorListener() {

				@Override
				public void onAnimationStart(Animator animation) {
					// mIsScrolling = true;
					// selectedView(getSelectedView(), false);
				}

				@Override
				public void onAnimationRepeat(Animator animation) {

				}

				@Override
				public void onAnimationEnd(Animator animation) {
					isDrawFocusItem = true;
					postInvalidate();
					if (newItem != null) {
						newItem.setFocusable(true);
					}
				}

				@Override
				public void onAnimationCancel(Animator animation) {

				}
			});

			animatorSet.start();
		}
	}

	private void modifyPosition() {
		ViewPackage vp = null;
		for (int i = 0; i < viewPackages.size(); i++) {
			vp = viewPackages.get(i);
			FilmSpecialItem item = (FilmSpecialItem) vp.getView();
			item.setIndex(i);
		}
	}

	private int keyCode = 0;

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		this.keyCode = keyCode;
		return super.onKeyDown(keyCode, event);
	}

	private Drawable focusShadowDrawable;
	private boolean isDrawFocusItem = true;
	private int mFocusEdgeOffset = getResources().getDimensionPixelSize(R.dimen.d_0dp);

	@Override
	protected void dispatchDraw(Canvas canvas) {

		super.dispatchDraw(canvas);

		if (focusItem != null && isDrawFocusItem) {
			if (focusShadowDrawable == null)
				focusShadowDrawable = context.getResources().getDrawable(
						R.drawable.main_page_item_selected);

			Rect toFocusedViewRect = UIUtil.createViewRect(this, focusItem,
					mFocusEdgeOffset);

			UIUtil.drawDrawableAt(canvas, toFocusedViewRect,
					focusShadowDrawable,true);
		}
	}

	private int focusedItemIndex = -1;
	private FilmSpecialItem focusItem = null;

	/**
	 * 获取子控件dispatchDraw的次序
	 */
	@Override
	protected int getChildDrawingOrder(int childCount, int i) {
		if (focusedItemIndex < 0)
			return i;

		if (i < (childCount - 1)) {
			if (focusedItemIndex == i)
				i = childCount - 1;
		} else {
			if (focusedItemIndex < childCount)
				i = focusedItemIndex;
		}

		return i;
	}

	/**
	 * 
	 * @author 海迪
	 * @Title: setFocusedItemIndex
	 * @Description: 设置当前获取焦点的Item及Index
	 * @param @param focusItem 获取焦点的Item
	 * @param @param focusedItemIndex 获取焦点Item的Index
	 * @return void
	 * @throws
	 * 
	 * @param focusItem
	 * @param focusedItemIndex
	 */
	public void setFocusedItemIndex(FilmSpecialItem focusItem,
			int focusedItemIndex) {

		this.focusItem = focusItem;
		this.focusedItemIndex = focusedItemIndex;

		this.postInvalidate();

		if (focusItem == null) {
			return;
		}

		if (adapter == null || adapter.getCount() <= showItemCount) {
			return;
		}

		if (KeyEvent.KEYCODE_DPAD_RIGHT == keyCode) {
			if (currentIndex < 0)
				currentIndex = 0;
			if (currentIndex <= 4)
				currentIndex++;
		} else if (KeyEvent.KEYCODE_DPAD_LEFT == keyCode) {
			if (currentIndex > 4)
				currentIndex = 4;
			if (currentIndex >= 0)
				currentIndex--;
		}

		if (currentIndex < 0) {
			isDrawFocusItem = false;
			scrollPreItem();
		} else if (currentIndex > 4) {
			isDrawFocusItem = false;
			scrollNextItem();
		}

	}

}