using System;

namespace BoFilTest
{
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Media;
    using BoFilTest.Domain;
    using BoFilTest.Utils;
    using OxyPlot;
    using OxyPlot.Axes;
    using OxyPlot.Series;

    public class RunningModel
    {
        private readonly LineSeries weight;
        private readonly LineSeries pressure;
        private readonly LineSeries flow;
        private readonly LineSeries extra;

        private static Brush ToBrush(OxyColor Color)
        {
            var c = new Color();
            c.A = Color.A;
            c.R = Color.R;
            c.G = Color.G;
            c.B = Color.B;

            return new SolidColorBrush(c);
        }

        public RunningModel(bool EnableExtra)
        {
            plotModel = new PlotModel
            {
                IsLegendVisible = false,
            };
            ExtraEnabled = EnableExtra ? Visibility.Visible : Visibility.Hidden;

            var weightColor = OxyColor.FromRgb(20, 120, 180);
            var pressureColor = OxyColor.FromRgb(200, 141, 0);
            var flowColor = OxyColor.FromRgb(0, 204, 0);
            var extraColor = OxyColor.FromRgb(160, 140, 160);

            WeightBrush = ToBrush(weightColor);
            PressureBrush = ToBrush(pressureColor);
            FlowBrush = ToBrush(flowColor);
            ExtraBrush = ToBrush(extraColor);

            weight = new LineSeries { Title = Translated.FromKey("WEIGHT"), YAxisKey = "WEIGHT", Color = weightColor };
            pressure = new LineSeries { Title = Translated.FromKey("PRESSURE"), YAxisKey = "PRESSURE", Color = pressureColor };
            flow = new LineSeries { Title = Translated.FromKey("GAS_FLOW"), YAxisKey = "GAS_FLOW", Color = flowColor };
            extra = new LineSeries { Title = Translated.FromKey("EXTRA"), YAxisKey = "EXTRA", Color = extraColor };

            var weightAxis = new LinearAxis { Key = "WEIGHT", PositionTier = 2, TextColor = weightColor };
            var pressureAxis = new LinearAxis { Key = "PRESSURE", PositionTier = 1, TextColor = pressureColor };
            var flowAxis = new LinearAxis { Key = "GAS_FLOW", TextColor = flowColor };

            plotModel.Axes.Add(weightAxis);
            plotModel.Axes.Add(pressureAxis);
            plotModel.Axes.Add(flowAxis);

            plotModel.Series.Add(weight);
            plotModel.Series.Add(pressure);
            plotModel.Series.Add(flow);

            if (EnableExtra)
            {
                var extraAxis = new LinearAxis { Key = "EXTRA", PositionTier = 3, TextColor = extraColor };
                plotModel.Axes.Add(extraAxis);
                plotModel.Series.Add(extra);
            }
        }

        public void UpdateMeasuredValues(TimeSpan time, MeasuredValues values)
        {
            var x = time.TotalSeconds;
            values.Weight.MatchSome(weight => this.Weight.Add(new DataPoint(x, weight.Value)));
            values.Flow.MatchSome(flow => this.Flow.Add(new DataPoint(x, flow.Value)));
            values.Pressure.MatchSome(pressure => this.Pressure.Add(new DataPoint(x, pressure.Value)));
            values.ExtraValue.MatchSome(extra => this.Extra.Add(new DataPoint(x, extra.Value)));
            this.plotModel.InvalidatePlot(true);
        }

        public void Clear()
        {
            Weight.Clear();
            Flow.Clear();
            Pressure.Clear();
            Extra.Clear();
            this.plotModel.InvalidatePlot(true);
        }

        public IList<DataPoint> Weight => this.weight.Points;
        public IList<DataPoint> Flow => this.flow.Points;
        public IList<DataPoint> Pressure => this.pressure.Points;
        public IList<DataPoint> Extra => this.extra.Points;

        public Brush WeightBrush { get; }
        public Brush FlowBrush { get; }
        public Brush PressureBrush { get; }
        public Brush ExtraBrush { get; }

        public PlotModel PlotModel => this.plotModel;

        public Visibility ExtraEnabled { get; }

        private readonly PlotModel plotModel;
    }
}
