using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace HD_Picture_Converter_CE
{
    public partial class ConvertBox : Form
    {
        public ConvertBox()
        {
            InitializeComponent();
        }

        private Image Img;
        private Size OriginalImageSize;
        private Size ModifiedImageSize;
        private Settings SettingsForum;

        int imagesToConvert=0;
        int imagesConverted=0;
        int cropWidth;
        int cropHeight;
        int errorCode = 0;
        int highQualityCrop=1;
        int conversionFail = 0;
        double AspectRatio;
        

        //double ratioX;
        //double ratioY;
        
        string AppDir;
        string path;
        string[] iniLines;
        string Filename;
        string FilenameFive;
        string FilenameEight;
        public Pen cropPen;

        public DashStyle cropDashStyle = DashStyle.DashDot;
        public bool Makeselection = false;
        public bool SettingsExpandCheck;

        private void Form1_Load(object sender, EventArgs e)
        {
            //InitializeOpenFileDialog();
            LogBox.Text = "Open an image to convert!";
        }

        private void InitializeOpenFileDialog()
        {
            progressBar1.Value = 0;
            //filters out all images but png
            this.openFileDialog1.Filter = "Images (*.PNG)|*.PNG|" +
                                            "All files (*.*)|*.*";
            this.openFileDialog1.Title = "Select image";

            //  Allow the user to select multiple images.
            this.openFileDialog1.Multiselect = true;
            //                   ^  ^  ^  ^  ^  ^  ^
            
        }

        private void OpenButton_Click(object sender, EventArgs e)
        {
            InitializeOpenFileDialog();
            DialogResult Dlg = this.openFileDialog1.ShowDialog();

            //OpenFileDialog Dlg = new InitializeOpenFileDialog();
            if (Dlg == System.Windows.Forms.DialogResult.OK)
            {
                progressBar1.Value = 25;
                //resets images to convert statistics 
                imagesToConvert = 0;
                imagesConverted = 0;

                //loops through each image that was selected
                foreach (String File in openFileDialog1.FileNames)
                {
                    
                    imagesToConvert++;
                    Img = Image.FromFile(File);
                    Filename = Path.GetFileName(File);
                    //checks if the filename has a number as the first character
                    if (char.IsDigit(Filename[0]))
                    {
                        LogBox.Text = "\""+Filename+ "\" Is not a valid name. Your image file name MUST start with a letter. Please rename the file and try again!";
                        MessageBox.Show("Error: Invalid file name!");
                    }
                    else
                    {
                        //loads the current image to be converted
                        LoadImage();
                        //detects if the image is the correct size
                        ResizeImage();
                        //does *something* important
                        Crop();
                        //saves the image as an appvar.
                        SaveCreate();
                        //increments sucessful images converted 
                        imagesConverted++;
                    }

                    
                }
                
            }
            else if (Dlg != System.Windows.Forms.DialogResult.Cancel)
            {
                LogBox.Text = "Something is wrong with your image. Perhaps it is not a valid PNG or may be corrupted.";
                MessageBox.Show("Error: Problem opening image!");
                return;
            }
            

            /*LogBox.Text = "Resizing image...";
            progressBar1.Increment(25);
            if (OriginalImageSize.Width > 320 || OriginalImageSize.Height > 240)
            {
                MessageBox.Show("Error: Image too big!");
                LogBox.Text = "Your image is either too tall or too wide. \nMake sure your image is at most 320 pixels wide and 240 pixels tall.\n Try resizing the image using a software such as Paint. \nAuto-resizing may come in a future update!";
                return;
            }else
            {
                ResizeImage();
                
            }
            
            LogBox.Text = "Cropping image...";
            progressBar1.Increment(25);
            highQualityCrop = 1;
            Crop();
            LogBox.Text = "Saving and running convPNG.exe";
            progressBar1.Increment(25);
            //saves images, creates new ini
            SaveCreate();*/
           

            if (conversionFail == 0)
            {
                progressBar1.Value = 100;
                LogBox.Text = "Finished! Sucessfuly converted "+imagesConverted+ " out of "+imagesToConvert+" selected images!\n Each converted image has been saved into 3 app vars. \nSend all " + 3*imagesConverted+" .8xv files to your TI-84 Plus CE and view the image with the HDpic program! \nYou can now open another image to convert!";
                AdditionalLog.Text = "Image width: " + ModifiedImageSize.Width + " Image height: " + ModifiedImageSize.Height + " \nConverted "+imagesConverted+" image"+(imagesConverted==1 ? ".":"s.");
            }
            else
            {
                LogBox.Text = "Error, image could not be converted! \nIf you can't fix it yourself, please contact TheLastMillennial on Cemetech \nHere: www.ceme.tech/t14498";
                AdditionalLog.Text = "Error code: " + errorCode;
                conversionFail = 0;
            }
        }


        private void LoadImage()
        {
            errorCode = 10;
            //we set the picturebox size according to image, we can get image width and height with the help of Image.Width and Image.height properties.
            int imgWidth = Img.Width;
            int imgHeight = Img.Height;
            LeftPictureBox.Width = imgWidth;
            LeftPictureBox.Height = imgHeight;
            LeftPictureBox.Image = Img;

            OriginalImageSize = new Size(imgWidth, imgHeight);
            errorCode = 19;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            errorCode = 20;
            Bitmap bm_source = new Bitmap(LeftPictureBox.Image);
            // Make a bitmap for the result.
            Bitmap bm_dest = new Bitmap(Convert.ToInt32(ModifiedImageSize.Width), Convert.ToInt32(ModifiedImageSize.Height));
            // Make a Graphics object for the result Bitmap.
            Graphics gr_dest = Graphics.FromImage(bm_dest);
            // Copy the source image into the destination bitmap.
            gr_dest.DrawImage(bm_source, 0, 0, bm_dest.Width + 1, bm_dest.Height + 1);
            // Display the result.
            LeftPictureBox.Image = bm_dest;
            LeftPictureBox.Width = bm_dest.Width;
            LeftPictureBox.Height = bm_dest.Height;

            errorCode = 29;
        }

        private void ResizeImage()
        {

            try
            {
                ModifiedImageSize.Width = OriginalImageSize.Width;
                ModifiedImageSize.Height = OriginalImageSize.Height;

            }
            catch (Exception)
            {
                
                MessageBox.Show("Error! Code: "+errorCode);
                return;
            }
           
    }
        private void Crop()
        {
            //this makes the image the correct dimensions by chopping off part of it? I didn't comment this very good. :(
            errorCode = 40;
            cropWidth = ModifiedImageSize.Width / 2;
            cropHeight = ModifiedImageSize.Height;
            Rectangle Lrect = new Rectangle(0, 0, cropWidth, ModifiedImageSize.Height);
            Rectangle Rrect = new Rectangle(cropWidth, 0, cropWidth, ModifiedImageSize.Height);
            Console.WriteLine("MFW: "+(ModifiedImageSize.Width / 2).ToString());

            Bitmap OriginalImage = new Bitmap(LeftPictureBox.Image, LeftPictureBox.Width, LeftPictureBox.Height);
            //Original image

            Bitmap _Limg = new Bitmap(cropWidth, cropHeight);
            Bitmap _Rimg = new Bitmap(cropWidth, cropHeight);


            using (Graphics g = Graphics.FromImage(_Limg))
            {
                g.DrawImage(OriginalImage, new Rectangle(0, 0, _Limg.Width, _Limg.Height),Lrect,GraphicsUnit.Pixel);
            }

            using (Graphics g = Graphics.FromImage(_Rimg))
            {
                g.DrawImage(OriginalImage, new Rectangle(0, 0, _Rimg.Width, _Rimg.Height), Rrect, GraphicsUnit.Pixel);
            }
            LeftPictureBox.Image = _Limg;
            RightPictureBox.Image = _Rimg;

            BoxLocations();
            LeftPictureBox.Refresh();
            RightPictureBox.Refresh();
            errorCode = 49;
        }

        private void BoxLocations()
        {
            LeftPictureBox.Location=new Point(50,120);
            RightPictureBox.Location = new Point(250, 120);
        }

        private void SaveCreate()
        {
            errorCode = 50;
            //gets directory of this program
            AppDir = AppDomain.CurrentDomain.BaseDirectory;
            //debugging, doesn't effect the program
            Console.WriteLine("Dir: "+AppDir);
            errorCode = 52;
            //saves the pictures as pngs
            LeftPictureBox.Image.Save(AppDir + @"Left.png", ImageFormat.Png);
            long length= new System.IO.FileInfo(AppDir + @"Left.png").Length;

            RightPictureBox.Image.Save(AppDir + @"Right.png", ImageFormat.Png);
            //makes sure file name is correct length 
            FilenameEight = Filename;
            FilenameFive = Filename;
            //I have this as 7 for the app var name allowing a L or R to be placed at the end
            if (Filename.Length > 7)
                Filename = Filename.Substring(0, 7);
            
            //I have this as 8 for the header
            if (FilenameEight.Length > 8)
            {
                FilenameEight = FilenameEight.Substring(0, 8);
            }
            else
            {
                //This loops until the header is 8 chars long
                while (Filename.Length < 8)
                {
                    Filename = Filename + " ";
                }
            }
            errorCode = 54;
            //Detects if the images were previously created, if so, it deletes them to be overwritten.
            if (File.Exists(AppDir + Filename + "L.8xv"))
            {
                Console.WriteLine("Deleting L!");
                File.Delete(AppDir + Filename + "L.8xv");
            }
                
            if (File.Exists(AppDir + Filename + "R.8xv"))
            {
                Console.WriteLine("Deleting R!");
                File.Delete(AppDir + Filename + "R.8xv");
            }

            errorCode = 55;
           
            //both picture's ini file
            string[] iniLines = {"/Leave this alone",
"#GroupPalette      : image_palette.png",
"#FixedIndexColor   : 0,0,0,0",
"#FixedIndexColor   : 1,255,255,255",
"/put your image names here",
"#PNGImages         :",
 "Left",
 "Right",

"/Leave the next 4 lines alone",
"#GroupICE          : gfx",
"#Palette           : image_palette.png",
"#FixedIndexColor   : 0,0,0,0",
"#FixedIndexColor   : 1,255,255,255",
"/Put your image names here (same as above)",
"#PNGImages         :",
 "Left",
 "Right",

"/name of your output app var (maximum of 8 characters)",
"#AppvarICE         :" +Filename+"L",
"/This will be at the very beginning of the app var (add underscores to the end to make the whole header 16 chars long)",
"/Never change the FIRST 8 characters. The LAST 8 characters will be used as the image name in the program.",
"#OutputHeader      : HDPICV3L"+FilenameEight,
"#OutputPalettes    : gfx",
"/Image name of LEFT image",
"#PNGImages         :",
 "Left",

"/name of your output app var (maximum of 8 characters) (does not need to be the same as above)",
"#AppvarICE         : "+Filename+"R",
"/This will be at the very beginning of the app var (add underscores to the end to make the whole header 16 chars long)",
"/Never change the FIRST 8 characters. The LAST 8 characters will be used as the image name in the program. (make sure it's the same as above)",
"#OutputHeader      : HDPICV3R"+FilenameEight,
"#OutputPalettes    : gfx",
"/image name of RIGHT image",
"#PNGImages         :",
 "Right",

"#AppvarICE         : "+Filename+"P",
"#OutputHeader      : HDPALV1B"+FilenameEight,
"#OutputPalettes    : gfx",
"#PNGImages         :",
"  image_palette.png"};



            
            //saves the ini text and runs convpng
            try
            {
                errorCode = 56;
                System.IO.File.WriteAllLines(AppDir + @"convpng.ini", iniLines);
                errorCode = 57;
                //starts the converter application and allows it 30 seconds to convert before erroring out
                var convPNGrunning=Process.Start(AppDir + @"windows_convpng.exe");
                convPNGrunning.WaitForExit(30000);
            }
            catch (Exception e)
            {
                conversionFail = 1;
                MessageBox.Show("Error! code: "+errorCode+ "\nMake sure you have windows_convpng.exe at the following directory: \n" + AppDir);
                imagesConverted--;
                return;
            }
                       
        }


        private void button1_Click(object sender, EventArgs e)
        {
            Process.Start(AppDomain.CurrentDomain.BaseDirectory);
        }

        private void SettingsButton_Click(object sender, EventArgs e)
        {
            //SettingsForum.Show();
            return;
        }

        private void ContactLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://www.cemetech.net/forum/viewtopic.php?t=14498");
        }
    }
    
}