using AutoUpdaterDotNET;
using DeviceRepair.Models;
using DeviceRepairAndOptimization;
using DeviceRepairAndOptimization.Common;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace DeviceRepairAndOptimization
{
    /// <summary>
    /// 用户登录窗体
    /// </summary>
    public partial class frm_Login : Form
    {
        #region ctor

        public frm_Login()
        {
            InitializeComponent();
            InstanceControl();

            // 设置窗体双缓冲，可以提高绘制效率
            this.DoubleBuffered = true;
            // 设置圆角
            SetRoundRegion(this, 6);
        }

        #endregion

        #region method

        /// <summary>
        /// 设置窗体的圆角区域
        /// </summary>
        /// <param name="form"></param>
        /// <param name="radius"></param>
        private void SetRoundRegion(Form form, int radius)
        {
            IntPtr handle = CreateRoundRectRgn(0, 0, form.Width, form.Height, radius * 2, radius * 2);
            if (handle != IntPtr.Zero)
            {
                Region region = Region.FromHrgn(handle);
                form.Region = region;
                DeleteObject(handle);
            }
        }

        /// <summary>
        /// 控件初始化 - 部分控件居中样式处理
        /// </summary>
        public void InstanceControl()
        {
            SelectButton(btn_Close);
        }

        #endregion

        #region Win32

        [DllImport("Gdi32.dll", EntryPoint = "DeleteObject")]
        private static extern bool DeleteObject(IntPtr hObject);

        private const int WM_SysCommand = 0x0112;
        private const int OneMsgNum = 0xf017;

        [DllImport("user32")]
        private static extern bool ReleaseCapture();

        [DllImport("user32")]
        private static extern bool PostMessage(int hWnd, int Mwg, int wParam, int lParam);

        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr
            CreateRoundRectRgn(int left, int top, int right, int bottom, int width, int height);

        #endregion

        #region event

        /// <summary>
        /// 鼠标拖动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pnl_Caption_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                PostMessage((int)this.Handle, WM_SysCommand, OneMsgNum, 0);
            }
        }

        /// <summary>
        /// 登录按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Login_Click(object sender, EventArgs e)
        {
            EnableOrDisableControl(false);
            splashScreenManager1.ShowWaitForm();

            try
            {
                if (string.IsNullOrEmpty(txt_UserCode.Text.Trim()))
                    throw new Exception("您输入的账户错误，请重试。");

                if (string.IsNullOrEmpty(txt_UserPass.Text.Trim()))
                    throw new Exception("您输入的密码错误，请重试。");

                var responseData = DeviceRepairAndOptimization.Biz.UserManager.Instance.GetDataByCodeAndPwd(new UserInfoModel
                {
                    LoginCode = txt_UserCode.Text.Trim(),
                    PassWord = DeviceRepair.Utils.Security.EncryptionHelper.EncryptByMD5(txt_UserPass.Text)
                });

                if (responseData.Code != 1)
                    throw new Exception(responseData.Message);

                UserInfoModel us = responseData.ToDeserializeObject<UserInfoModel>();
                if (us != null)
                {
                    if (!us.Status)
                        throw new Exception($"用户被锁定,无法登录！");

                    if (!string.IsNullOrEmpty(responseData.Token))
                    {
                        splashScreenManager1.TryCloseWait();
                        GlobalInfo.CurrentUser = us;
                        GlobalInfo.token = responseData.Token;

                        this.DialogResult = DialogResult.OK;
                        this.Close();
                        return;
                    }
                }

                EnableOrDisableControl(true);
                splashScreenManager1.TryCloseWait();
                XtraMessageBoxHelper.Error(responseData.Message);
            }
            catch (Exception ex)
            {
                EnableOrDisableControl(true);
                splashScreenManager1.TryCloseWait();
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 启用或禁用窗体控件
        /// </summary>
        /// <param name="sw"></param>
        void EnableOrDisableControl(bool sw)
        {
            btn_Login.Enabled = sw;
            txt_UserCode.Enabled = sw;
            txt_UserPass.Enabled = sw;
        }

        /// <summary>
        /// 退出按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Close_Click(object sender, EventArgs e) => this.Close();

        /// <summary>
        /// 关闭按钮 鼠标获取焦点事件 -- 做获取焦点样式处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Close_MouseMove(object sender, MouseEventArgs e)
        {
            Button btn = sender as Button;
            btn.BackColor = Color.Red;
            btn.ForeColor = Color.White;
        }

        /// <summary>
        /// 关闭按钮 鼠标失去焦点事件 -- 做失去焦点样式处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Close_MouseLeave(object sender, EventArgs e)
        {
            Button btn = sender as Button;
            btn.BackColor = Color.White;
            btn.ForeColor = Color.Black;
        }

        /// <summary>
        /// 取消获得焦点
        /// </summary>
        /// <param name="button"></param>
        public static void SelectButton(Button button)
        {
            MethodInfo methodinfo =
                button.GetType().GetMethod("SetStyle", BindingFlags.NonPublic | BindingFlags.Instance);
            methodinfo.Invoke(button, BindingFlags.NonPublic, null, new object[] { ControlStyles.Selectable, false },
                null);
        }

        /// <summary>
        /// 窗体自绘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_Login_Paint(object sender, PaintEventArgs e)
        {
            Rectangle tang = this.ClientRectangle; //获取窗口矩形 为了下面得到窗口的宽高
            Graphics g3 = e.Graphics; //新建一个画布
            Color c3 = Color.FromArgb(183, 183, 183); //声明一个 颜色
            Pen p3 = new Pen(c3); //新建一支画笔
            g3.SmoothingMode = SmoothingMode.HighQuality; //抗锯齿 使得线条变柔顺  在画斜线或者曲线的时候使用
            g3.InterpolationMode = InterpolationMode.HighQualityBicubic; //使得画出来的效果高质量
            g3.CompositingQuality = CompositingQuality.HighQuality; //高质量画图
            g3.DrawLine(p3, 0, 0, 0, tang.Height - 1); //在（0，0）和（tang.Width - 1, 0）这两点间画一条直线
            g3.DrawLine(p3, 0, tang.Height - 1, tang.Width - 1,
                tang.Height -
                1); //注意必须减1 不然显示不出来  因为 如果假设窗口的高度是3像素 我们知道（0，0）位置代表 窗口最左上角的像素点  那么最左下角的像素点应该是（0，2） 而不是（0，3） 因为0，1，2 已经三个像素点了
            g3.DrawLine(p3, tang.Width - 1, tang.Height - 1, tang.Width - 1, 0);
            g3.DrawLine(p3, tang.Width - 1, 0, 0, 0);
        }

        #endregion

        private void frm_Login_Load(object sender, EventArgs e)
        {
            AutoUpdate();
        }

        public void AutoUpdate()
        {
            AutoUpdater.AppTitle = "Device Repair And Optimization";
            var vUpdateDir = Path.Combine(Application.StartupPath, "Update");
            if (!Directory.Exists(vUpdateDir))
            {
                Directory.CreateDirectory(vUpdateDir);
            }

            // 指定下载文件的存储目录
            AutoUpdater.DownloadPath = vUpdateDir;
            AutoUpdater.UpdateFormSize = new Size(800, 600);

            AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent;
            AutoUpdater.Synchronous = true;
            AutoUpdater.ShowSkipButton = false;
            AutoUpdater.ShowRemindLaterButton = false;
            AutoUpdater.Start($"http://{DeviceRepair.Utils.Config.Configurations.Properties.ServiceIP}/{DeviceRepair.Utils.Config.Configurations.Properties.ServiceName}/Update/DOAutoUpdater.xml");
        }

        private void AutoUpdater_ApplicationExitEvent()
        {
            Text = @"Closing application...";
            Thread.Sleep(5000);
            Application.Exit();
        }
    }
}