using System;
using System.Drawing;
using System.Windows.Forms;

namespace MyScreenCap.Ctrl {

    /// <summary>
    /// Rectangle画像切り出し
    /// </summary>
    class FormRectCap : Form {

        /// <summary>
        /// Rectangleで囲まれた範囲の画像
        /// </summary>
        public Bitmap BmpRect { get; set; }

        /// <summary>
        /// FullScreen画像
        /// </summary>
        private Bitmap bmp = null;

        /// <summary>
        /// Rectangle Start Position
        /// </summary>
        private Point startPos;

        /// <summary>
        /// Rectangle Current Position
        /// </summary>
        private Point currentPos;

        /// <summary>
        /// Rectangle Drawing Flg
        /// </summary>
        private bool drawing;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public FormRectCap() {
            bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size);
            }
            this.BackgroundImage = bmp;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.ShowInTaskbar = false;
            this.DoubleBuffered = true;

            this.MouseDown += new MouseEventHandler(FormRectCap_MouseDown);
            this.MouseMove += new MouseEventHandler(FormRectCap_MouseMove);
            this.MouseUp += new MouseEventHandler(FormRectCap_MouseUp);

            this.Shown += new EventHandler(FormRectCap_Shown);
            this.FormClosed += new FormClosedEventHandler(FormRectCap_FormClosed);

        }

        /// <summary>
        /// FormRectCap Shown
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void FormRectCap_Shown(object sender, EventArgs e) {

            this.BringToFront();
            this.Activate();
            Cursor.Hide();
        }

        /// <summary>
        /// FormRectCap FormClosed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void FormRectCap_FormClosed(object sender, FormClosedEventArgs e) {

            Cursor.Show();
        }

        /// <summary>
        /// FormRectCap MouseDown
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormRectCap_MouseDown(object sender, MouseEventArgs e) {
            currentPos = startPos = e.Location;
            drawing = true;
        }

        /// <summary>
        /// FormRectCap MouseMove
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormRectCap_MouseMove(object sender, MouseEventArgs e) {
            currentPos = e.Location;
            this.Invalidate();
        }

        /// <summary>
        /// FormRectCap MouseUp
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormRectCap_MouseUp(object sender, MouseEventArgs e) {
            if (drawing) {
                drawing = false;
                Rectangle rect = GetRectangle();
                if (rect.Width != 0 && rect.Height != 0) {
                    BmpRect = new Bitmap(rect.Width, rect.Height);
                    using (Graphics g = Graphics.FromImage(BmpRect)) {
                        g.DrawImage(bmp, 0, 0, rect, GraphicsUnit.Pixel);
                    }
                } else {
                    BmpRect = null;
                }
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.Close();
            }
        }

        /// <summary>
        /// OnPaint
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e) {
            base.OnPaint(e);
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
            if (drawing) {
                e.Graphics.DrawRectangle(Pens.Red, GetRectangle());
            } else {
                Rectangle rect = Screen.PrimaryScreen.Bounds;
                e.Graphics.FillRectangle(Brushes.Red,
                    currentPos.X,
                    0,
                    1,
                    rect.Bottom);
                e.Graphics.FillRectangle(Brushes.Red,
                    0,
                    currentPos.Y,
                    rect.Right,
                    1);
            }
        }

        /// <summary>
        /// Get Rectangle
        /// </summary>
        /// <returns></returns>
        private Rectangle GetRectangle() {
            return new Rectangle(
                Math.Min(startPos.X, currentPos.X),
                Math.Min(startPos.Y, currentPos.Y),
                Math.Abs(startPos.X - currentPos.X),
                Math.Abs(startPos.Y - currentPos.Y));
        }
    }
}
