using Microsoft.WindowsAPICodePack.Dialogs;
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Phihong_EVSE_UI_Tool
{
    /// <summary>
    /// ModifyIco.xaml 的互動邏輯
    /// </summary>
    public partial class ModifyIco : UserControl
    {
        private Properties.Settings mySettings = Properties.Settings.Default;
        private string logoCustomImgPath;
        private string compLogoCustomImgPath;
        private string urlCustomImgPath;
        private int bytesPerPixel = 2;

        public ModifyIco()
        {
            InitializeComponent();

            logoCustomImgPath = mySettings.LogoCustomImgPath;
            uxLogoDefaultRadioButton.IsChecked = mySettings.IsLogoDefault && !mySettings.IsLogoHide;
            uxLogoCustomRadioButton.IsChecked = !mySettings.IsLogoDefault && !mySettings.IsLogoHide;
            uxLogoHideRadioButton.IsChecked = mySettings.IsLogoHide;
            uxLogoBrowseTextBox.Text = mySettings.LogoCustomImgPath_org;

            compLogoCustomImgPath = mySettings.CompLogoCustomImgPath;
            uxCompLogoDefaultRadioButton.IsChecked = mySettings.IsCompLogoDefault && !mySettings.IsCompLogoHide;
            uxCompLogoCustomRadioButton.IsChecked = !mySettings.IsCompLogoDefault && !mySettings.IsCompLogoHide;
            uxCompLogoHideRadioButton.IsChecked = mySettings.IsCompLogoHide;
            uxCompLogoBrowseTextBox.Text = mySettings.CompLogoCustomImgPath_org;

            urlCustomImgPath = mySettings.UrlCustomImgPath;
            uxUrlDefaultRadioButton.IsChecked = mySettings.IsUrlDefault && !mySettings.IsUrlHide;
            uxUrlCustomRadioButton.IsChecked = !mySettings.IsUrlDefault && !mySettings.IsUrlHide;
            uxUrlHideRadioButton.IsChecked = mySettings.IsUrlHide;
            uxUrlBrowseTextBox.Text = mySettings.UrlCustomImgPath_org;
        }

        private void ModifyIcoContent(int index, string path, bool isHide = false)
        {
            string icoPath = Path.Combine(Utility.OUTPUT_DIRECTORY, Utility.ICO_NAME);
            if (!File.Exists(icoPath))
            {
                Uri srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_NAME), UriKind.Relative);
                Utility.CopyFileFromResource(srcPath, icoPath);
            }

            int width = 0, height = 0;
            byte[] pixels = null;

            if (String.IsNullOrEmpty(path) && !isHide)
            {
                //Default
                Uri resourcePath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, index.ToString() + ".bmp"), UriKind.Relative);
                Utility.ConvertResourceToBitmap565Array(resourcePath, out width, out height, out pixels);
            }
            else if (String.IsNullOrEmpty(path) && isHide)
            {
                //Hide
                Uri resourcePath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, index.ToString() + "_hide.bmp"), UriKind.Relative);
                Utility.ConvertResourceToBitmap565Array(resourcePath, out width, out height, out pixels);
            }
            else
            {
                Utility.ConvertFileToBitmap565Array(path, out width, out height, out pixels);
            }

            FileStream icoFile = new FileStream(Path.Combine(Utility.OUTPUT_DIRECTORY, Utility.ICO_NAME), 
                                                FileMode.OpenOrCreate, FileAccess.ReadWrite);

            byte[] array = new byte[4 * bytesPerPixel];
            icoFile.Position = index * 4 * bytesPerPixel;
            icoFile.Read(array, 0, 4 * bytesPerPixel);
            long offset = ((array[2] << 24) + (array[3] << 16) + (array[4] << 8) + array[5]) * bytesPerPixel;

            array[6] = pixels[0];
            array[7] = pixels[1];

            //Modify Header
            icoFile.Position = index * 4 * bytesPerPixel; //header offset
            icoFile.Write(array, 0, 4 * bytesPerPixel);

            //Modify Content
            icoFile.Position = offset;
            icoFile.Write(pixels, 0, width * height * bytesPerPixel);

            icoFile.Close();
        }

        private void DisplayDWIcoContent()
        {
            FileStream fs = new FileStream(Path.Combine(Utility.OUTPUT_DIRECTORY, Utility.ICO_NAME), 
                                           FileMode.OpenOrCreate, FileAccess.ReadWrite);

            if (fs.Length > 131072 * bytesPerPixel)
            {
                for (int i = 0; i <= 32767; i++)
                {
                    byte[] array = new byte[4 * bytesPerPixel];
                    fs.Position = i * 4 * bytesPerPixel;
                    fs.Read(array, 0, 4 * bytesPerPixel);
                    int width = array[0];
                    int height = array[1];
                    long offset = ((array[2] << 24) + (array[3] << 16) + (array[4] << 8) + array[5]) * bytesPerPixel;
                    if (offset <= 0)
                    {
                        continue;
                    }
                    if (offset >= 131072 * bytesPerPixel)
                    {
                        DisPlayIco(fs, width, height, offset);

                        Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() => { }));
                    }
                }
            }

            fs.Close();
        }

        public void DisPlayIco(FileStream fs, int width, int height, long offset)
        {
            WriteableBitmap wbitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr565, null);
            byte[,,] pixels = new byte[width, height, 2];
            byte[] pixels1d = new byte[height * width * bytesPerPixel];

            fs.Position = offset;
            byte[] array = new byte[bytesPerPixel];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    fs.Read(array, 0, bytesPerPixel);
                    pixels[j, i, 0] = array[1];
                    pixels[j, i, 1] = array[0];
                }
            }

            int index = 0;
            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    for (int i = 0; i < bytesPerPixel; i++)
                    {
                        pixels1d[index++] = pixels[col, row, i];
                    }
                }
            }

            Int32Rect rect = new Int32Rect(0, 0, width, height);
            int stride = (width * wbitmap.Format.BitsPerPixel + 7) / 8;
            wbitmap.WritePixels(rect, pixels1d, stride, 0);

            Image image = new Image()
            {
                Width = 270,
                Height = 270,
                Stretch = Stretch.None,
                Margin = new Thickness(0),
                Source = wbitmap
            };
            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality);

            uxIcoUniformGrid.Children.Add(image);
        }

        private void uxDefaultRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            Uri srcPath;
            RadioButton rb = e.Source as RadioButton;
            if (rb is null)
            {
                return;
            }

            switch (rb.Tag.ToString())
            {
                case "Logo":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_MAINLOGO), UriKind.Relative);
                    uxLogoImage.Source = new BitmapImage(srcPath);
                    mySettings.IsLogoDefault = true;
                    mySettings.IsLogoHide = false;
                    ModifyIcoContent((int)IcoElement.Logo, String.Empty);
                    break;
                case "CompLogo":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_COMPLETELOGO), UriKind.Relative);
                    uxCompLogoImage.Source = new BitmapImage(srcPath);
                    mySettings.IsCompLogoDefault = true;
                    mySettings.IsCompLogoHide = false;
                    ModifyIcoContent((int)IcoElement.LogoComplete, String.Empty);
                    break;
                case "Url":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_URL), UriKind.Relative);
                    uxUrlImage.Source = new BitmapImage(srcPath);
                    mySettings.IsUrlDefault = true;
                    mySettings.IsUrlHide = false;
                    ModifyIcoContent((int)IcoElement.URL, String.Empty);
                    break;
                default:
                    return;
            }
            Utility.ChangedFiles[Utility.ICO_NAME] = true;
            mySettings.Save();

            //Display Ico
            uxIcoUniformGrid.Children.Clear();
            DisplayDWIcoContent();
        }

        private void uxCustomRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            RadioButton rb = e.Source as RadioButton;
            if (rb is null)
            {
                return;
            }

            switch (rb.Tag.ToString())
            {
                case "Logo":
                    if (File.Exists(logoCustomImgPath))
                    {
                        Utility.LoadImageFromPath(uxLogoImage, logoCustomImgPath);
                        mySettings.IsLogoDefault = false;
                        mySettings.IsLogoHide = false;
                        ModifyIcoContent((int)IcoElement.Logo, logoCustomImgPath);
                    }
                    break;
                case "CompLogo":
                    if (File.Exists(compLogoCustomImgPath))
                    {
                        Utility.LoadImageFromPath(uxCompLogoImage, compLogoCustomImgPath);
                        mySettings.IsCompLogoDefault = false;
                        mySettings.IsCompLogoHide = false;
                        ModifyIcoContent((int)IcoElement.LogoComplete, compLogoCustomImgPath);
                    }
                    break;
                case "Url":
                    if (File.Exists(urlCustomImgPath))
                    {
                        Utility.LoadImageFromPath(uxUrlImage, urlCustomImgPath);
                        mySettings.IsUrlDefault = false;
                        mySettings.IsUrlHide = false;
                        ModifyIcoContent((int)IcoElement.URL, urlCustomImgPath);
                    }
                    break;
                default:
                    return;
            }
            Utility.ChangedFiles[Utility.ICO_NAME] = true;
            mySettings.Save();

            //Display Ico
            uxIcoUniformGrid.Children.Clear();
            DisplayDWIcoContent();
        }

        private void uxHideRadioButton_Checked(object sender, RoutedEventArgs e)
        {
            Uri srcPath;
            RadioButton rb = e.Source as RadioButton;
            if (rb is null)
            {
                return;
            }

            switch (rb.Tag.ToString())
            {
                case "Logo":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_MAINLOGO_HIDE), UriKind.Relative);
                    uxLogoImage.Source = new BitmapImage(srcPath);
                    mySettings.IsLogoDefault = false;
                    mySettings.IsLogoHide = true;
                    ModifyIcoContent((int)IcoElement.Logo, String.Empty, true);
                    break;
                case "CompLogo":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_COMPLETELOGO_HIDE), UriKind.Relative);
                    uxCompLogoImage.Source = new BitmapImage(srcPath);
                    mySettings.IsCompLogoDefault = false;
                    mySettings.IsCompLogoHide = true;
                    ModifyIcoContent((int)IcoElement.LogoComplete, String.Empty, true);
                    break;
                case "Url":
                    srcPath = new Uri(Path.Combine(Utility.ICO_PARENTFOLDER, Utility.ICO_URL_HIDE), UriKind.Relative);
                    uxUrlImage.Source = new BitmapImage(srcPath);
                    mySettings.IsUrlDefault = false;
                    mySettings.IsUrlHide = true;
                    ModifyIcoContent((int)IcoElement.URL, String.Empty, true);
                    break;
                default:
                    return;
            }
            Utility.ChangedFiles[Utility.ICO_NAME] = true;
            mySettings.Save();

            //Display Ico
            uxIcoUniformGrid.Children.Clear();
            DisplayDWIcoContent();
        }

        private void uxBrowseButton_Click(object sender, RoutedEventArgs e)
        {
            Button btn = e.Source as Button;
            if (btn is null)
            {
                return;
            }

            var dlg = new CommonOpenFileDialog()
            {
                EnsureFileExists = true,
                Title = "Select an image file",
            };
            dlg.Filters.Add(new CommonFileDialogFilter("BMP images", "*.bmp"));

            if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
            {
                switch (btn.Tag.ToString())
                {
                    case "Logo":
                        if (!Utility.IsIcoLogoSizeQualified(dlg.FileName))
                        {
                            MessageBox.Show(dlg.FileName + "\r\n" + "The resolution of the image must be 255x34",
                                            "Incorrect Resolution", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        uxLogoBrowseTextBox.Text = dlg.FileName;
                        logoCustomImgPath = Path.Combine(Utility.CUSTOM_DIRECTORY, Utility.ICO_MAINLOGO);
                        File.Copy(dlg.FileName, logoCustomImgPath, true);
                        Utility.LoadImageFromPath(uxLogoImage, logoCustomImgPath);
                        mySettings.IsLogoDefault = false;
                        mySettings.LogoCustomImgPath = logoCustomImgPath;
                        mySettings.LogoCustomImgPath_org = uxLogoBrowseTextBox.Text;

                        ModifyIcoContent((int)IcoElement.Logo, logoCustomImgPath);
                        break;
                    case "CompLogo":
                        if (!Utility.IsIcoLogoSizeQualified(dlg.FileName))
                        {
                            MessageBox.Show(dlg.FileName + "\r\n" + "The resolution of the image must be 255x34",
                                            "Incorrect Resolution", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        uxCompLogoBrowseTextBox.Text = dlg.FileName;
                        compLogoCustomImgPath = Path.Combine(Utility.CUSTOM_DIRECTORY, Utility.ICO_COMPLETELOGO);
                        File.Copy(dlg.FileName, compLogoCustomImgPath, true);
                        Utility.LoadImageFromPath(uxCompLogoImage, compLogoCustomImgPath);
                        mySettings.IsCompLogoDefault = false;
                        mySettings.CompLogoCustomImgPath = compLogoCustomImgPath;
                        mySettings.CompLogoCustomImgPath_org = uxCompLogoBrowseTextBox.Text;

                        ModifyIcoContent((int)IcoElement.LogoComplete, compLogoCustomImgPath);
                        break;
                    case "Url":
                        if (!Utility.IsIcoUrlSizeQualified(dlg.FileName))
                        {
                            MessageBox.Show(dlg.FileName + "\r\n" + "The resolution of the image must be 233x28",
                                            "Incorrect Resolution", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                        uxUrlBrowseTextBox.Text = dlg.FileName;
                        urlCustomImgPath = Path.Combine(Utility.CUSTOM_DIRECTORY, Utility.ICO_URL);
                        File.Copy(dlg.FileName, urlCustomImgPath, true);
                        Utility.LoadImageFromPath(uxUrlImage, urlCustomImgPath);
                        mySettings.IsUrlDefault = false;
                        mySettings.UrlCustomImgPath = urlCustomImgPath;
                        mySettings.UrlCustomImgPath_org = uxUrlBrowseTextBox.Text;

                        ModifyIcoContent((int)IcoElement.URL, urlCustomImgPath);
                        break;
                    default:
                        break;
                }

                Utility.ChangedFiles[Utility.ICO_NAME] = true;
                mySettings.Save();

                //Display Ico
                uxIcoUniformGrid.Children.Clear();
                DisplayDWIcoContent();
            }
        }
    }
}