using System;
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.Windows.Forms;

using System.Media;

namespace CopyImagePart
{
    public partial class frm92CopyImagePart : Form
    {
        public frm92CopyImagePart()
        {
            InitializeComponent();
        }

        // The original image.
        private Bitmap OriginalImage;

        // True when we're selecting a rectangle.
        private bool IsSelecting = false;

        // The drags starting point.
        private Point StartPoint;

        // The selected rectangle.
        private Rectangle SelectedRect;
        private bool HaveSelection = false;

        // Save the original image.
        private void frm92CopyImagePart_Load(object sender, EventArgs e)
        {
            OriginalImage = new Bitmap(originalPictureBox.Image);
        }

        // Exit.
        private void exitMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        // Copy the selected area to the clipboard.
        private void copyMenuItem_Click(object sender, EventArgs e)
        {
            CopyToClipboard(SelectedRect);
            SystemSounds.Beep.Play();
        }

        // Copy the selected area to the clipboard and blank that area.
        private void cutMenuItem_Click(object sender, EventArgs e)
        {
            // Copy the selection to the clipboard.
            CopyToClipboard(SelectedRect);

            // Blank the selected area in the original image.
            using (Graphics gr = Graphics.FromImage(OriginalImage))
            {
                using (SolidBrush br = new SolidBrush(originalPictureBox.BackColor))
                {
                    gr.FillRectangle(br, SelectedRect);
                }
            }

            // Display the result.
            originalPictureBox.Image = OriginalImage;

            // Enable the menu items appropriately.
            EnableMenuItems();
            HaveSelection = false;

            SystemSounds.Beep.Play();
        }

        // Paste the image on the clipboard, centering it on the selected area.
        private void pasteCenteredMenuItem_Click(object sender, EventArgs e)
        {
            // Do nothing if the clipboard doesn't hold an image.
            if (!Clipboard.ContainsImage()) return;

            // Get the clipboard's image.
            Image clipboardImage = Clipboard.GetImage();

            // Figure out where to put it.
            int cx = SelectedRect.X + (SelectedRect.Width - clipboardImage.Width) / 2;
            int cy = SelectedRect.Y + (SelectedRect.Height - clipboardImage.Height) / 2;
            Rectangle destRect = new Rectangle(
                cx, cy,
                clipboardImage.Width,
                clipboardImage.Height);

            // Copy the new image into position.
            using (Graphics gr = Graphics.FromImage(OriginalImage))
            {
                gr.DrawImage(clipboardImage, destRect);
            }

            // Display the result.
            originalPictureBox.Image = OriginalImage;

            // Discard the selection.
            HaveSelection = false;
        }

        // Paste the image on the clipboard, stretching it to fit the selected area.
        private void pasteStretchedMenuItem_Click(object sender, EventArgs e)
        {
            // Do nothing if the clipboard doesn't hold an image.
            if (!Clipboard.ContainsImage()) return;

            // Get the clipboard's image.
            Image clipboardImage = Clipboard.GetImage();

            // Get the image's bounding Rectangle.
            Rectangle srcRect = new Rectangle(0, 0,
                clipboardImage.Width, clipboardImage.Height);

            // Copy the new image into position.
            using (Graphics gr = Graphics.FromImage(OriginalImage))
            {
                gr.DrawImage(clipboardImage, SelectedRect,
                    srcRect, GraphicsUnit.Pixel);
            }

            // Display the result.
            originalPictureBox.Image = OriginalImage;

            // Discard the selection.
            HaveSelection = false;
        }

        // Start selecting the rectangle.
        private void originalPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            IsSelecting = true;

            // Save the start point.
            StartPoint = ConvertPoint(originalPictureBox, e.Location);
        }

        // Continue selecting.
        private void originalPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            // Do nothing it we're not selecting an area.
            if (!IsSelecting) return;

            // Make a Bitmap to display the selection rectangle.
            Bitmap bm = new Bitmap(OriginalImage);
            using (Graphics gr = Graphics.FromImage(bm))
            {
                // Draw the rectangle.
                Point currentPoint = ConvertPoint(originalPictureBox, e.Location);
                Rectangle rect = GetRectangle(StartPoint, currentPoint);
                using (Pen pen = new Pen(Color.Red, 3))
                {
                    gr.DrawRectangle(pen, rect);
                }
            }

            // Display the temporary bitmap.
            originalPictureBox.Image = bm;
        }

        // Finish selecting the area.
        private void originalPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            // Do nothing it we're not selecting an area.
            if (!IsSelecting) return;
            IsSelecting = false;

            // Record the selected area.
            Point currentPoint = ConvertPoint(originalPictureBox, e.Location);
            SelectedRect = GetRectangle(StartPoint, currentPoint);
            HaveSelection = (
                (SelectedRect.Width > 0) &&
                (SelectedRect.Height > 0));

            // Enable the menu items appropriately.
            EnableMenuItems();
        }

        // Return a Rectangle with the two points as opposite corners.
        private Rectangle GetRectangle(Point point1, Point point2)
        {
            int x = Math.Min(point1.X, point2.X);
            int y = Math.Min(point1.Y, point2.Y);
            int width = Math.Abs(point2.X - point1.X);
            int height = Math.Abs(point2.Y - point1.Y);
            return new Rectangle(x, y, width, height);
        }

        // Return a piece of an image.
        private Bitmap ImagePiece(Bitmap bm, Rectangle sourceRect)
        {
            // Intersect the rectangle with the Bitmap's bounds.
            Rectangle bmRect = new Rectangle(0, 0, bm.Width, bm.Height);
            sourceRect.Intersect(bmRect);

            // Make sure the result has a positive size.
            if ((sourceRect.Width < 1) || (sourceRect.Height < 1)) return null;

            Bitmap piece = new Bitmap(sourceRect.Width, sourceRect.Height);
            using (Graphics gr = Graphics.FromImage(piece))
            {
                Rectangle destRect = new Rectangle(0, 0,
                    sourceRect.Width, sourceRect.Height);
                gr.DrawImage(OriginalImage, destRect,
                    sourceRect, GraphicsUnit.Pixel);
            }
            return piece;
        }

        // Convert the coordinates for the image's SizeMode.
        private Point ConvertPoint(PictureBox pic, Point point)
        {
            int picHgt = pic.ClientSize.Height;
            int picWid = pic.ClientSize.Width;
            int imgHgt = pic.Image.Height;
            int imgWid = pic.Image.Width;

            int x = point.X;
            int y = point.Y;
            switch (pic.SizeMode)
            {
                case PictureBoxSizeMode.AutoSize:
                case PictureBoxSizeMode.Normal:
                    // These are okay. Leave them alone.
                    break;
                case PictureBoxSizeMode.CenterImage:
                    x = point.X - (picWid - imgWid) / 2;
                    y = point.Y - (picHgt - imgHgt) / 2;
                    break;
                case PictureBoxSizeMode.StretchImage:
                    x = (int)(imgWid * point.X / (float)picWid);
                    y = (int)(imgHgt * point.Y / (float)picHgt);
                    break;
                case PictureBoxSizeMode.Zoom:
                    float picAspect = picWid / (float)picHgt;
                    float imgAspect = imgWid / (float)imgHgt;
                    if (picAspect > imgAspect)
                    {
                        // The PictureBox is wider/shorter than the image.
                        y = (int)(imgHgt * point.Y / (float)picHgt);

                        // The image fills the height of the PictureBox.
                        // Get its width.
                        float scaledWidth = imgWid * picHgt / imgHgt;
                        float dx = (picWid - scaledWidth) / 2;
                        x = (int)((point.X - dx) * imgHgt / (float)picHgt);
                    }
                    else
                    {
                        // The PictureBox is taller/thinner than the image.
                        x = (int)(imgWid * point.X / (float)picWid);

                        // The image fills the height of the PictureBox.
                        // Get its height.
                        float scaledHeight = imgHgt * picWid / imgWid;
                        float dy = (picHgt - scaledHeight) / 2;
                        y = (int)((point.Y - dy) * imgWid / picWid);
                    }
                    break;
            }

            return new Point(x, y);
        }

        // Copy the selected area to the clipboard.
        private void CopyToClipboard(Rectangle srcRect)
        {
            // Copy the selected piece of image to a bitmap.
            Bitmap bm = ImagePiece(OriginalImage, srcRect);

            // Copy the selection image to the clipboard.
            Clipboard.SetImage(bm);
        }

        // Enable or disable the menu items.
        private void EnableMenuItems()
        {
            copyMenuItem.Enabled = HaveSelection;
            cutMenuItem.Enabled = HaveSelection;
            pasteStretchedMenuItem.Enabled = HaveSelection;
            pasteCenteredMenuItem.Enabled = HaveSelection;
        }


        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.originalPictureBox = new System.Windows.Forms.PictureBox();
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
            this.mnuFileExit = new System.Windows.Forms.ToolStripMenuItem();
            this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.copyMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.cutMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.pasteCenteredMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.pasteStretchedMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            ((System.ComponentModel.ISupportInitialize)(this.originalPictureBox)).BeginInit();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // originalPictureBox
            // 
            this.originalPictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.originalPictureBox.Cursor = System.Windows.Forms.Cursors.Cross;
            this.originalPictureBox.Image = global::CopyImagePart.Properties.Resources.KenDriving;
            this.originalPictureBox.Location = new System.Drawing.Point(12, 27);
            this.originalPictureBox.Name = "originalPictureBox";
            this.originalPictureBox.Size = new System.Drawing.Size(308, 223);
            this.originalPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.originalPictureBox.TabIndex = 0;
            this.originalPictureBox.TabStop = false;
            this.originalPictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.originalPictureBox_MouseDown);
            this.originalPictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.originalPictureBox_MouseMove);
            this.originalPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.originalPictureBox_MouseUp);
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.toolStripMenuItem1,
            this.editToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(334, 24);
            this.menuStrip1.TabIndex = 5;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // toolStripMenuItem1
            // 
            this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.mnuFileExit});
            this.toolStripMenuItem1.Name = "toolStripMenuItem1";
            this.toolStripMenuItem1.Size = new System.Drawing.Size(37, 20);
            this.toolStripMenuItem1.Text = "&File";
            // 
            // mnuFileExit
            // 
            this.mnuFileExit.Name = "mnuFileExit";
            this.mnuFileExit.Size = new System.Drawing.Size(92, 22);
            this.mnuFileExit.Text = "E&xit";
            this.mnuFileExit.Click += new System.EventHandler(this.exitMenuItem_Click);
            // 
            // editToolStripMenuItem
            // 
            this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.copyMenuItem,
            this.cutMenuItem,
            this.pasteCenteredMenuItem,
            this.pasteStretchedMenuItem});
            this.editToolStripMenuItem.Name = "editToolStripMenuItem";
            this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20);
            this.editToolStripMenuItem.Text = "&Edit";
            // 
            // copyMenuItem
            // 
            this.copyMenuItem.Name = "copyMenuItem";
            this.copyMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
            this.copyMenuItem.Size = new System.Drawing.Size(194, 22);
            this.copyMenuItem.Text = "&Copy";
            this.copyMenuItem.ToolTipText = "Copy the selected area to the clipboard";
            this.copyMenuItem.Click += new System.EventHandler(this.copyMenuItem_Click);
            // 
            // cutMenuItem
            // 
            this.cutMenuItem.Name = "cutMenuItem";
            this.cutMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
            this.cutMenuItem.Size = new System.Drawing.Size(194, 22);
            this.cutMenuItem.Text = "C&ut";
            this.cutMenuItem.ToolTipText = "Copy the selected area to the clipboard and clear the area";
            this.cutMenuItem.Click += new System.EventHandler(this.cutMenuItem_Click);
            // 
            // pasteCenteredMenuItem
            // 
            this.pasteCenteredMenuItem.Name = "pasteCenteredMenuItem";
            this.pasteCenteredMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
            this.pasteCenteredMenuItem.Size = new System.Drawing.Size(194, 22);
            this.pasteCenteredMenuItem.Text = "&Paste Centered";
            this.pasteCenteredMenuItem.ToolTipText = "Paste the image on the clipboard to the selected area, centering it in the select" +
    "ed area";
            this.pasteCenteredMenuItem.Click += new System.EventHandler(this.pasteCenteredMenuItem_Click);
            // 
            // pasteStretchedMenuItem
            // 
            this.pasteStretchedMenuItem.Name = "pasteStretchedMenuItem";
            this.pasteStretchedMenuItem.Size = new System.Drawing.Size(194, 22);
            this.pasteStretchedMenuItem.Text = "Paste &Stretched";
            this.pasteStretchedMenuItem.ToolTipText = "Paste the image on the clipboard to the selected area, stretching it to fit";
            this.pasteStretchedMenuItem.Click += new System.EventHandler(this.pasteStretchedMenuItem_Click);
            // 
            // frm92CopyImagePart
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(334, 261);
            this.Controls.Add(this.menuStrip1);
            this.Controls.Add(this.originalPictureBox);
            this.Name = "frm92CopyImagePart";
            this.Text = "CopyImagePart";
            this.Load += new System.EventHandler(this.frm92CopyImagePart_Load);
            ((System.ComponentModel.ISupportInitialize)(this.originalPictureBox)).EndInit();
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PictureBox originalPictureBox;
        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
        private System.Windows.Forms.ToolStripMenuItem mnuFileExit;
        private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem copyMenuItem;
        private System.Windows.Forms.ToolStripMenuItem cutMenuItem;
        private System.Windows.Forms.ToolStripMenuItem pasteCenteredMenuItem;
        private System.Windows.Forms.ToolStripMenuItem pasteStretchedMenuItem;
    }
}