package com.wasu.widgets.tools;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;

public class UIUtil {

	public static float getPixelFromDpi(Context context, float dpi) {
		DisplayMetrics mDisplayMetrics = context.getResources().getDisplayMetrics();
		return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpi, mDisplayMetrics);
	}
	/**
	 * 根据给出的画布、矩形区域和图片画出焦点框
	 * @author
	 * @Title: drawDrawableAt
	 * @Description: 在窗口中绘制UI
	 * @param @param canvas
	 * @param @param position
	 * @param @param drawable
	 * @return void
	 * @throws
	 * 
	 * @param canvas
	 * @param position
	 * @param drawable
	 */
	public static void drawDrawableAt(Canvas canvas, Rect position, Drawable drawable, boolean doPadding) {
		if (null == canvas || null == position || null == drawable) {
			return;
		}

		Rect padding = new Rect();
		drawable.getPadding(padding);
		if (doPadding) {
			Rect bounds = new Rect();
			bounds.left = position.left - padding.left;
			bounds.top = position.top - padding.top;
			bounds.right = position.right + padding.right;
			bounds.bottom = position.bottom + padding.bottom;
			drawable.setBounds(bounds);
		} else {
			drawable.setBounds(position);
		}
		drawable.draw(canvas);
	}

	/**
	 * 
	 * @author
	 * @Title: createViewRect
	 * @Description: 根据容器View(parent), 和子View计算并生成Rect
	 * @param @param parent
	 * @param @param child
	 * @param @param offset
	 * @param @return
	 * @return Rect
	 * @throws
	 * 
	 * @param parent
	 * @param child
	 * @param offset
	 * @return
	 */
	public static Rect createViewRect(View parent, View child, int offset) {

		if (null == child || !isDescentantOf(parent, child)) {
			return null;
		}

		Rect rect = new Rect();

		int[] l1 = new int[2];
		parent.getLocationInWindow(l1);
		int[] l2 = new int[2];
		child.getLocationInWindow(l2);
		child.getGlobalVisibleRect(rect, new Point(0, 0));

		int offsetX = l2[0] - l1[0];
		int offsetY = l2[1] - l1[1];

		int widthOrig = child.getWidth();
		int heightOrig = child.getHeight();
		int widthCurr = rect.width();
		int heightCurr = rect.height();

		float widthRatio = (float) widthCurr / (float) widthOrig;
		float heightRatio = (float) heightCurr / (float) heightOrig;

		int width = 0, height = 0;
		if (widthRatio > heightRatio) {
			width = widthCurr;
			height = (int) (heightOrig * widthRatio);
		} else {
			height = heightCurr;
			width = (int) (widthOrig * heightRatio);
		}

		rect.left = offsetX;
		rect.top = offsetY;
		rect.right = rect.left + width;
		rect.bottom = rect.top + height;

		rect.top += offset;
		rect.left += offset;
		rect.bottom -= offset;
		rect.right -= offset;

		return rect;
	}

	/**
	 *
	 * @Title: drawDrawableAt
	 * @Description: 在窗口中绘制UI
	 * @param @param canvas
	 * @param @param position
	 * @param @param drawable
	 * @return void
	 * @throws
	 *
	 * @param canvas
	 * @param position
	 * @param drawable
	 */
	public static void drawDrawableAt(Canvas canvas, Rect position, Drawable drawable) {
		if (null == canvas || null == position || null == drawable) {
			return;
		}

		Rect padding = new Rect();
		drawable.getPadding(padding);
		Rect bounds = new Rect();
		bounds.left = position.left - padding.left;
		bounds.top = position.top - padding.top;
		bounds.right = position.right + padding.right;
		bounds.bottom = position.bottom + padding.bottom;
		drawable.setBounds(bounds);
		drawable.draw(canvas);
	}

	/**
	 * 
	 * @author
	 * @Title: createViewRect
	 * @Description: 根据容器View(parent), 和子View计算并生成Rect
	 * @param @param parent
	 * @param @param focusView 实际响应焦点的view
	 * * @param @param mFoucsViewId 根据其大小画焦点的view,如果不传，默认根据focusView画焦点
	 * @param @param offset
	 * @param @return
	 * @return Rect
	 * @throws
	 * 
	 * @param parent
	 * @param focusView
	 * @param offset
	 * @return
	 */
	public static Rect createViewRect(View parent, View focusView, int mFoucsViewId, int offset) {

		View child = getDrawFoucsView(focusView, mFoucsViewId);

		if (null == child || !isDescentantOf(parent, child)) {
			return null;
		}

		Rect rect = new Rect();

		int[] l1 = new int[2];
		parent.getLocationInWindow(l1);
		int[] l2 = new int[2];
		child.getLocationInWindow(l2);
		child.getGlobalVisibleRect(rect, new Point(0, 0));

		int offsetX = l2[0] - l1[0];
		int offsetY = l2[1] - l1[1];

		int widthOrig = child.getWidth();
		int heightOrig = child.getHeight();
		int widthCurr = rect.width();
		int heightCurr = rect.height();

		float widthRatio = (float) widthCurr / (float) widthOrig;
		float heightRatio = (float) heightCurr / (float) heightOrig;

		int width = 0, height = 0;
		if (widthRatio > heightRatio) {
			width = widthCurr;
			height = (int) (heightOrig * widthRatio);
		} else {
			height = heightCurr;
			width = (int) (widthOrig * heightRatio);
		}

		rect.left = offsetX;
		rect.top = offsetY;
		rect.right = rect.left + width;
		rect.bottom = rect.top + height;

		rect.top += offset;
		rect.left += offset;
		rect.bottom -= offset;
		rect.right -= offset;

		return rect;
	}

	public static View getDrawFoucsView(View focusView, int mFoucsViewId) {
		View child = null;
		if (mFoucsViewId >= 0) {

			if (focusView.getTag(mFoucsViewId) != null) {
				child = (View) focusView.getTag(mFoucsViewId);
			} else {
				child = focusView.findViewById(mFoucsViewId);
			}

			if (child != null) {
				child.setTag(mFoucsViewId, child);

			} else {
				child = focusView;
			}
		} else {
			child = focusView;
		}
		return child;
	}

	public static boolean isDescentantOf(View parent, View child) {
		boolean isDescent = false;

		if (null == parent || null == child)
			return isDescent;

		View view = child;
		while (null != view.getParent()) {
			if (!(view.getParent() instanceof View))
				break;

			view = (View) view.getParent();

			if (view == parent) {
				isDescent = true;
				break;
			}
		}
		return isDescent;
	}

	public static void getViewRect(View view, View focusView, Rect rect) {
		if (null == view || null == rect) {
			return;
		}

		int offsetX = 0;
		int offsetY = 0;
		if (focusView != null) {
			View child = focusView;
			if (child != null) {
				offsetX = view.getLeft();
				offsetY = view.getTop();
				view = child;
			}
		}

		rect.left = view.getLeft();
		rect.top = view.getTop();
		rect.right = view.getRight();
		rect.bottom = view.getBottom();

		rect.offset(offsetX, offsetY);
	}

	public static void getViewRect(View view, int focusViewId, Rect rect) {
		if (null == view || null == rect) {
			return;
		}

		int offsetX = 0;
		int offsetY = 0;
		if (focusViewId >= 0) {
			View child = null;
			if (view.getTag(focusViewId) != null) {
				child = (View) view.getTag(focusViewId);
			} else {
				child = view.findViewById(focusViewId);
			}

			if (child != null) {
				view.setTag(focusViewId, child);
				offsetX = view.getLeft() + view.getPaddingLeft();
				offsetY = view.getTop() + view.getPaddingTop();
				view = child;
			}
		}

		rect.left = view.getLeft();
		rect.top = view.getTop();
		rect.right = view.getRight();
		rect.bottom = view.getBottom();

		rect.offset(offsetX, offsetY);

	}

	@SuppressLint("NewApi")
	public static void scaleView(View view, float scaleX, float scaleY, float progress) {
		if (null == view) {
			return;
		}
		view.setScaleX(1f + (scaleX - 1f) * (1f - progress));
		view.setScaleY(1f + (scaleY - 1f) * (1f - progress));
	}

	/**
	 * 获取大的画布
	 * @param rects
	 * @return
     */
	public static Rect combineRects(Rect... rects) {
		// quick initialize
		int minLeft = rects[0].left;
		int minTop = rects[0].top;
		int maxRight = rects[0].right;
		int maxBottom = rects[0].bottom;

		// find min/max values
		for (Rect rect : rects) {
			minLeft = Math.min(minLeft, rect.left);
			minTop = Math.min(minTop, rect.top);
			maxRight = Math.max(maxRight, rect.right);
			maxBottom = Math.max(maxBottom, rect.bottom);
		}

		return new Rect(minLeft, minTop, maxRight, maxBottom);
	}

	/**
	 * 添加padding
	 * @param bounds
	 * @param padding
     * @return
     */
	public static Rect includPadding(Rect bounds, Rect padding) {
		return new Rect(bounds.left - padding.left, bounds.top - padding.top, bounds.right + padding.right, bounds.bottom + padding.bottom);
	}

	/**
	 * 缩放矩形区域
	 * @param rect
	 * @param ratioX
	 * @param ratioY
     */
	public static void scaleRect(Rect rect, float ratioX, float ratioY) {
		if (null == rect) {
			return;
		}

		int offsetX = (int) ((float) (rect.right - rect.left) * (ratioX - 1f) / 2);
		int offsetY = (int) ((float) (rect.bottom - rect.top) * (ratioY - 1f) / 2);

		rect.left -= offsetX;
		rect.right += offsetX;
		rect.top -= offsetY;
		rect.bottom += offsetY;
	}

	/**
	 * 计算焦点位置
	 * @param focusRect
	 * @param fromRect
	 * @param toRect
     * @param progress
     */
	public static void calculateFocusPosition(Rect focusRect, Rect fromRect, Rect toRect, float progress) {
		focusRect.left = (int) ((float) (toRect.left - fromRect.left) * progress + fromRect.left);
		focusRect.top = (int) ((float) (toRect.top - fromRect.top) * progress + fromRect.top);
		focusRect.right = (int) ((float) (toRect.right - fromRect.right) * progress + fromRect.right);
		focusRect.bottom = (int) ((float) (toRect.bottom - fromRect.bottom) * progress + fromRect.bottom);
	}
	private static int ID_OFFSET = 0x100;

	/**
	 * 修改绘制顺序
	 * @param childCount
	 * @param i
	 * @param focusedIndex
     * @return
     */
	public static int getChildDrawingOrder(int childCount, int i, int focusedIndex) {

		if (focusedIndex < 0)
			return i;

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

		return i;
	}
}
