using System;
using System.Collections.Generic;
using System.Windows;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpDX.Mathematics.Interop;

namespace VIZ.Framework.Core
{
    /// <summary>
    /// 图片辅助类
    /// </summary>
    public partial class ImageHelper
    {
        /// <summary>
        /// 获取自适应宽度域高度
        /// </summary>
        /// <param name="spcWidth">源宽度</param>
        /// <param name="spcHeight">源高度</param>
        /// <param name="orgWidth">目标宽度</param>
        /// <param name="orgHeight">目标高度</param>
        /// <param name="width">自适应后的宽度</param>
        /// <param name="height">自适应后的高度</param>
        public static void AdjustSize(int spcWidth, int spcHeight, int orgWidth, int orgHeight, out int width, out int height)
        {
            if (orgWidth <= spcWidth && orgHeight <= spcHeight)
            {
                // 取得比例系数 
                float w = spcWidth / (float)orgWidth;
                float h = spcHeight / (float)orgHeight;
                if (w > h)
                {
                    height = spcHeight;
                    width = (int)(Math.Round(orgWidth * h));
                }
                else if (w < h)
                {
                    width = spcWidth;
                    height = (int)(Math.Round(orgHeight * w));
                }
                else
                {
                    width = spcWidth;
                    height = spcWidth;
                }
            }
            else
            {
                // 取得比例系数 
                float w = orgWidth / (float)spcWidth;
                float h = orgHeight / (float)spcHeight;
                // 宽度比大于高度比 
                if (w > h)
                {
                    width = spcWidth;
                    height = (int)(w >= 1 ? Math.Round(orgHeight / w) : Math.Round(orgHeight * w));
                }
                // 宽度比小于高度比 
                else if (w < h)
                {
                    height = spcHeight;
                    width = (int)(h >= 1 ? Math.Round(orgWidth / h) : Math.Round(orgWidth * h));
                }
                // 宽度比等于高度比 
                else
                {
                    width = spcWidth;
                    height = spcHeight;
                }
            }
        }

        /// <summary>
        /// 缩放，dstWidth 和 dstHeight 只能有一个有值
        /// </summary>
        /// <param name="srcWidth">源宽度</param>
        /// <param name="srcHeight">源高度</param>
        /// <param name="dstWidth">目标宽度，高度会根据宽度值计算得出，</param>
        /// <param name="dstHeight">目标高度，宽度会根据高度计算得出</param>
        /// <returns></returns>
        public static Rect Resize(int srcWidth, int srcHeight, int? dstWidth, int? dstHeight)
        {
            if (dstWidth != null && dstHeight != null)
                throw new Exception("dstWidth is not null and dstHeight is not null.");

            if (dstWidth == null && dstHeight == null)
                throw new Exception("dstWidth is null and dstHeight is null.");

            Rect result = new Rect();
            float p = (float)srcWidth / srcHeight;

            if (dstWidth != null)
            {
                result.Width = dstWidth.Value;
                result.Height = dstWidth.Value / p;
            }
            else if (dstHeight != null)
            {
                result.Height = dstHeight.Value;
                result.Width = dstHeight.Value * p;
            }

            return result;
        }

        /// <summary>
        /// 将UI坐标点转化为图片坐标点
        /// </summary>
        /// <param name="imgWidth">图片宽度</param>
        /// <param name="imgHeight">图片高度</param>
        /// <param name="uiDrawRect">图片在UI的绘制区域</param>
        /// <param name="uiPoint">UI坐标点</param>
        /// <returns>图片坐标点</returns>
        public static Point ConvertUiPointToImagePoint(int imgWidth, int imgHeight, Rect uiDrawRect, Point uiPoint)
        {
            double xp = uiDrawRect.Width / imgWidth;
            double yp = uiDrawRect.Height / imgHeight;

            double destX = (uiPoint.X - uiDrawRect.X) / xp;
            double destY = (uiPoint.Y - uiDrawRect.Y) / yp;

            return new Point(destX, destY);
        }

        /// <summary>
        /// 将UI矩形区域转化为图片矩形区域
        /// </summary>
        /// <param name="imgWidth">图片宽度</param>
        /// <param name="imgHeight">图片高度</param>
        /// <param name="uiDrawRect">图片在UI的绘制区域</param>
        /// <param name="uiRect">UI矩形区域</param>
        /// <returns>图片矩形区域</returns>
        public static Rect ConvertUiRectToImageRect(int imgWidth, int imgHeight, Rect uiDrawRect, Rect uiRect)
        {
            Rect uiRectClip = CutRectangle(uiRect, uiDrawRect);

            double xp = uiDrawRect.Width / imgWidth;
            double yp = uiDrawRect.Height / imgHeight;

            double destX = (uiRectClip.X - uiDrawRect.Left) / xp;
            double destY = (uiRectClip.Y - uiDrawRect.Top) / yp;
            double destW = uiRectClip.Width / xp;
            double destH = uiRectClip.Height / yp;

            return new Rect(destX, destY, destW, destH);
        }

        /// <summary>
        /// 将图片坐标点转化为UI坐标点
        /// </summary>
        /// <param name="imgWidth">图片宽度</param>
        /// <param name="imgHeight">图片高度</param>
        /// <param name="uiDrawRect">图片在UI的绘制区域</param>
        /// <param name="imgPoint">图片坐标点</param>
        /// <returns>UI坐标点</returns>
        public static RawVector2 ConvertImagePointToUiPoint(int imgWidth, int imgHeight, Rect uiDrawRect, RawVector2 imgPoint)
        {
            double xp = uiDrawRect.Width / imgWidth;
            double yp = uiDrawRect.Height / imgHeight;

            double destX = uiDrawRect.X + imgPoint.X * xp;
            double destY = uiDrawRect.Y + imgPoint.Y * yp;

            return new RawVector2((float)destX, (float)destY);
        }

        /// <summary>
        /// 将图片矩形区域转化为UI矩形区域
        /// </summary>
        /// <param name="imgWidth">图片宽度</param>
        /// <param name="imgHeight">图片高度</param>
        /// <param name="uiDrawRect">图片在UI的绘制区域</param>
        /// <param name="imgRect">图片矩形区域</param>
        /// <returns>UI矩形区域</returns>
        public static Rect ConvertImageRectToUiRect(int imgWidth, int imgHeight, Rect uiDrawRect, Rect imgRect)
        {
            double xp = uiDrawRect.Width / imgWidth;
            double yp = uiDrawRect.Height / imgHeight;

            double destX = uiDrawRect.X + imgRect.X * xp;
            double destY = uiDrawRect.Y + imgRect.Y * yp;
            double destW = imgRect.Width * xp;
            double destH = imgRect.Height * yp;

            return new Rect(destX, destY, destW, destH);
        }

        /// <summary>
        /// 使用bottom矩形区域裁剪top矩形区域，使top矩形区域包括在bottom矩形区域内
        /// </summary>
        /// <param name="topRect">top矩形区域</param>
        /// <param name="bottomRect">bottom矩形区域</param>
        /// <returns>裁剪后的矩形区域</returns>
        public static Rect CutRectangle(Rect topRect, Rect bottomRect)
        {
            double left = topRect.Left;
            double right = topRect.Right;
            double top = topRect.Top;
            double bottom = topRect.Bottom;

            // 左
            if (topRect.Left < bottomRect.Left)
            {
                left = bottomRect.Left;
            }
            if (topRect.Left > bottomRect.Right)
            {
                left = bottomRect.Right;
            }
            // 上
            if (topRect.Top < bottomRect.Top)
            {
                top = bottomRect.Top;
            }
            if (topRect.Top > bottomRect.Bottom)
            {
                top = bottomRect.Bottom;
            }
            // 右
            if (topRect.Right > bottomRect.Right)
            {
                right = bottomRect.Right;
            }
            if (topRect.Right < bottomRect.Left)
            {
                right = bottomRect.Left;
            }
            // 下
            if (topRect.Bottom < bottomRect.Top)
            {
                bottom = bottomRect.Top;
            }
            if (topRect.Bottom > bottomRect.Bottom)
            {
                bottom = bottomRect.Bottom;
            }

            return new Rect(left, top, right - left, bottom - top);
        }

    }
}
