using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ScottPlot;
using ScottPlot.Plottables;
using ScottPlot.TickGenerators;
using ScottPlot.WinForms;

namespace chart_scottplot
{
    public partial class Form1 : Form
    { // Create an instance of a FormsPlot like this
        readonly FormsPlot formsPlot1;
        public Form1()
        {
            InitializeComponent();

            // Add the FormsPlot to the panel
            formsPlot1 = new FormsPlot() { Dock = DockStyle.Fill };
            panel1.Controls.Add(formsPlot1);


        }

        ScottPlot.Plottables.Crosshair CrossHair;

        private DateTime[] xs,xs2;
        private double[] ys,ys2;
        private int pointCount;

        private void Form1_Load(object sender, EventArgs e)
        {
            // 초기 데이터 생성
            pointCount = 51;
            xs = new DateTime[pointCount];
            ys = new double[pointCount];

            xs2 = new DateTime[pointCount];
            ys2 = new double[pointCount];

            DateTime startTime = DateTime.Now;
            for (int i = 0; i < pointCount; i++)
            {
                xs[i] = startTime.AddSeconds(i);
                ys[i] = Math.Sin(i * 0.1);

                xs2[i] = startTime.AddSeconds(i);
                ys2[i] = Math.Sin(i * 0.1)+0.1;
            }

            // 초기 데이터 플로팅
            var sig3 = formsPlot1.Plot.Add.Scatter(xs, ys);
           // formsPlot1.Plot.Axes.DateTimeTicksBottom();

            var sig4 = formsPlot1.Plot.Add.Scatter(xs2, ys2);
           formsPlot1.Plot.Axes.DateTimeTicksBottom();

            //var sig1 = formsPlot1.Plot.Add.Signal(Generate.Sin(51));
            //sig1.LegendText = "Sin";

            //var sig2 = formsPlot1.Plot.Add.Signal(Generate.Cos(51));
            //sig2.LegendText = "Sin";


            //myScatter.Color = Colors.Green.WithOpacity(.2);
            //myScatter.LineWidth = 5;
            //myScatter.MarkerSize = 15;
            //formsPlot1.Plot.Axes.SetLimits(-100, 150, -5, 5); //limit 설정
            formsPlot1.Plot.Axes.AutoScale(); //auto limit , fit data

            formsPlot1.Plot.XLabel("TIME");
            formsPlot1.Plot.YLabel("VOLTAGE");
            //formsPlot1.Plot.Title("V");
            var anno = formsPlot1.Plot.Add.Annotation("This is an Annotation");
            anno.LabelFontSize = 32;
            anno.LabelFontName = Fonts.Serif;
            anno.LabelBackgroundColor = Colors.RebeccaPurple.WithAlpha(.3);
            anno.LabelFontColor = Colors.RebeccaPurple;
            anno.LabelBorderColor = Colors.Green;
            anno.LabelBorderWidth = 3;
            anno.LabelShadowColor = Colors.Transparent;
            anno.OffsetY = 40;
            anno.OffsetX = 20;


            CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0);
            CrossHair.TextColor = Colors.White;
            CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color;


            //커서기능용 특정위치에 세로선을 표시
            var axLine1 = formsPlot1.Plot.Add.VerticalLine(startTime.AddSeconds(pointCount / 2).ToOADate());
            axLine1.Text = "Cursor 1";
            axLine1.LabelAlignment = Alignment.UpperRight;
            axLine1.IsDraggable = true;

            var axLine2 = formsPlot1.Plot.Add.VerticalLine(startTime.AddSeconds(pointCount / 3).ToOADate());
            axLine2.Text = "Cursor 2";
            axLine2.LabelAlignment = Alignment.UpperRight;
            axLine2.IsDraggable = true;

            var hs = formsPlot1.Plot.Add.HorizontalSpan(startTime.AddSeconds(pointCount / 4).ToOADate(), startTime.AddSeconds(pointCount / 3).ToOADate());
            hs.LegendText = "Hello";
            hs.LineStyle.Width = 2;
            hs.LineStyle.Color = Colors.Magenta;
            hs.LineStyle.Pattern = LinePattern.Dashed;
            hs.FillStyle.Color = Colors.Magenta.WithAlpha(.2);

            formsPlot1.Plot.Add.Callout("Hello",
    textLocation: new Coordinates(xs[5].ToOADate(), 0.3),
    tipLocation: new Coordinates(xs[6].ToOADate(), 1.2));


            //double[] values = { 100, 80};
            //formsPlot1.Plot.Add.RadialGaugePlot(values);


            // add logic into the RenderStarting event to customize tick labels
            formsPlot1.Plot.RenderManager.RenderStarting += (s1, e1) =>
            {
                Tick[] ticks = formsPlot1.Plot.Axes.Bottom.TickGenerator.Ticks;
                for (int i = 0; i < ticks.Length; i++)
                {
                    DateTime dt = DateTime.FromOADate(ticks[i].Position);
                    string label = $"{dt:HH}:{dt:mm}:{dt:ss}";
                    ticks[i] = new Tick(ticks[i].Position, label);
                }
            };




            // some items must be styled directly
            //formsPlot1.Plot.Grid.MajorLineColor = Color.FromHex("#0e3d54");
            //formsPlot1.Plot.FigureBackground.Color = Color.FromHex("#07263b");
            //formsPlot1.Plot.DataBackground.Color = Color.FromHex("#0b3049");



            // create a custom formatter to return a string with
            // date only when zoomed out and time only when zoomed in

            // apply our custom tick formatter





            // the Style object contains helper methods to style many items at once
            formsPlot1.Plot.Axes.Color(Color.FromHex("#a0acb5"));

            formsPlot1.MouseDown += FormsPlot1_MouseDown;
            formsPlot1.MouseUp += FormsPlot1_MouseUp;
            formsPlot1.MouseMove += FormsPlot1_MouseMove;


            formsPlot1.Refresh();
        }

        private void FormsPlot1_MouseDown(object sender, MouseEventArgs e)
        {
            var lineUnderMouse = GetLineUnderMouse(e.X, e.Y);
            if (lineUnderMouse != null)
            {
                PlottableBeingDragged = lineUnderMouse;
                formsPlot1.Interaction.Disable(); // disable panning while dragging
            }
        }

        private void FormsPlot1_MouseUp(object sender, MouseEventArgs e)
        {
            PlottableBeingDragged = null;
            formsPlot1.Interaction.Enable(); // enable panning again
            formsPlot1.Refresh();
        }
        AxisLine PlottableBeingDragged = null;
        private void FormsPlot1_MouseMove(object sender, MouseEventArgs e)
        {

            //update cross line
            Pixel mousePixel = new Pixel(e.X, e.Y);
            Coordinates mouseCoordinates = formsPlot1.Plot.GetCoordinates(mousePixel);
            this.Text = $"X={mouseCoordinates.X:N3}, Y={mouseCoordinates.Y:N3}";
            CrossHair.Position = mouseCoordinates;
            CrossHair.VerticalLine.Text = $"{mouseCoordinates.X:N3}";
            CrossHair.HorizontalLine.Text = $"{mouseCoordinates.Y:N3}";
            formsPlot1.Refresh();



            // this rectangle is the area around the mouse in coordinate units
            CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(e.X, e.Y, radius: 10);

            if (PlottableBeingDragged is null)
            {
                // set cursor based on what's beneath the plottable
                var lineUnderMouse = GetLineUnderMouse(e.X, e.Y);
                if (lineUnderMouse is null) Cursor = Cursors.Default;
                else if (lineUnderMouse.IsDraggable && lineUnderMouse is VerticalLine) Cursor = Cursors.SizeWE;
                else if (lineUnderMouse.IsDraggable && lineUnderMouse is HorizontalLine) Cursor = Cursors.SizeNS;
            }
            else
            {
                // update the position of the plottable being dragged
                if (PlottableBeingDragged is HorizontalLine hl)
                {
                    hl.Y = rect.VerticalCenter;
                    hl.Text = $"{hl.Y:0.00}";
                }
                else if (PlottableBeingDragged is VerticalLine vl)
                {
                    vl.X = rect.HorizontalCenter;
                    vl.Text = $"{vl.X:0.00}";
                }
                formsPlot1.Refresh();
            }
        }
        private AxisLine GetLineUnderMouse(float x, float y)
        {
            CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(x, y, radius: 10);

            foreach (AxisLine axLine in formsPlot1.Plot.GetPlottables<AxisLine>().Reverse())
            {
                if (axLine.IsUnderMouse(rect))
                    return axLine;
            }

            return null;
        }
        private void button1_Click(object sender, EventArgs e)
        {


        }

        private void button2_Click(object sender, EventArgs e)
        {
            AddDataPoint();
        }

        public void AddDataPoint()
        {
            // 새로운 데이터 추가
            pointCount += 1;
            Array.Resize(ref xs, pointCount);
            Array.Resize(ref ys, pointCount);
            xs[pointCount - 1] = xs[pointCount - 2].AddSeconds(1);
            ys[pointCount - 1] = Math.Sin(pointCount * 0.1);

            // 데이터 업데이트
            formsPlot1.Plot.Clear();
            formsPlot1.Plot.Add.Scatter(xs, ys);

            // Y축 자동 스케일 조정
            //FormsPlot1.Plot.Axes.AutoScaleY();
            formsPlot1.Plot.Axes.AutoScale();

            // 플롯 갱신
            formsPlot1.Refresh();
        }
    }
}
