// Created with MonoDevelop
//
//    Copyright (C) 2010 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Drawing;
using System.Drawing.Drawing2D;

using Hiperscan.Spectroscopy;


namespace Hiperscan.NPlotEngine.Overlay.Annotation
{

    public class Line : Annotation
    {

        public Line(IPlotEngine plot, float line_width, Color color, LineStyle line_style) 
            : base(plot, AnnotationType.Line)
        {
            this.Visible = false;
            this.Interactive = true;
            this.ColorArgb = color.ToArgb();
            this.LineWidth = line_width;
            this.LineStyle = line_style;
        }
        
        public Line(IPlotEngine plot, Annotation a) : base(plot, a)
        {
        }

        public override void Draw (Graphics g)
        {
            if (this.Visible == false || this.PlotTypeId != this.plot.PlotTypeId)
                return;
            
            float x1 = (float)this.plot.GetPhysicalXCoord(this.X, false);
            float y1 = (float)this.plot.GetPhysicalYCoord(this.Y, false);
            float x2 = (float)this.plot.GetPhysicalXCoord(this.X + this.Width, false);
            float y2 = (float)this.plot.GetPhysicalYCoord(this.Y + this.Height, false);

            Pen pen = new Pen(this.Color, this.LineWidth)
            {
                DashStyle = (DashStyle)Enum.Parse(typeof(DashStyle), this.LineStyle.ToString())
            };

            Region clip = g.Clip;
            g.Clip = this.ClippingRegion;
            g.DrawLine(pen, x1, y1, x2, y2);
            g.Clip = clip;
        }
        
        public override void ButtonPressed (int x, int y, Gdk.ModifierType modifier)
        {
            this.X = this.plot.GetWorldXCoord(x, false);
            this.Y = this.plot.GetWorldYCoord(y, false);
            this.Width   = 0.0;
            this.Height  = 0.0;
            this.Visible = true;
        }
        
        public override void Motion (int x, int y, Gdk.ModifierType modifier)
        {
            this.Width  = this.plot.GetWorldXCoord(x, false) - this.X;
            this.Height = this.plot.GetWorldYCoord(y, false) - this.Y;
            
            if ((modifier & Gdk.ModifierType.ShiftMask) != Gdk.ModifierType.None)
            {
                
                int x0 = this.plot.GetPhysicalXCoord(this.X, false);
                int y0 = this.plot.GetPhysicalYCoord(this.Y, false);
                int w = Math.Abs(x - x0);
                int h = Math.Abs(y - y0);
                
                if (w > h && w > 2*h)
                    this.Height = 0.0;
                else if (w > h)
                    this.Height = this.Y - this.plot.GetWorldYCoord(y0 + Math.Sign(this.Height) * w, false);
                else if (h > w && h > 2*w)
                    this.Width = 0.0;
                else
                    this.Width = this.plot.GetWorldXCoord(x0 + Math.Sign(this.Width) * h, false) - this.X;
            }
        }
        
        public override void ButtonReleased (int x, int y, Gdk.ModifierType modifier)
        {
            this.Motion(x, y, modifier);
            this.Interactive = false;
        }
    }
}