using DataDisplay.Common;
using DataDisplay.DataSource;
using DataDisplay.Graph;
using DataDisplay.Renderers;
using MarketData.Utils;
using SkiaSharp;
using System;

namespace Navigator.Renderers
{
  public class ConsumerPriceIndexRenderer : IRenderer
		{
      private SKPaint paintSeries=new SKPaint{Style=SKPaintStyle.StrokeAndFill,Color=new SKColor((uint)SKColors.Black),StrokeWidth=5f};
      private LineGraph consumerPriceIndexLineGraph;

		  public event EventHandler RefreshRequested;

      public void Refresh()
      {
        RefreshRequested?.Invoke(this, EventArgs.Empty);
      }

      public double XDataExtent{get;set;}
      public double XDataExtentMin{get;set;}
      public double XRange{get{return XDataExtent-XDataExtentMin;}}
      public double YDataExtent{get;set;}
      public double YDataExtentMin{get;set;}
      public double YRange{get{return YDataExtent-YDataExtentMin;}}

      public CompositeDataSource ConsumerPriceIndexElements
      {
        set
        {
          if(null==consumerPriceIndexLineGraph)consumerPriceIndexLineGraph=new LineGraph(paintSeries,value);
          else consumerPriceIndexLineGraph.SetDataSource(value); 
        }
      }
      public bool AnyData()
      {
        if(null==consumerPriceIndexLineGraph)return false;
        return true;
      }

      public void SetColorRed()
      {
        if(!AnyData())return;
        paintSeries.Color=new SKColor((uint)SKColors.Red);
      }

      public void SetColorGreen()
      {
        if(!AnyData())return;
        paintSeries.Color=new SKColor((uint)SKColors.Green);
      }

      public void SetColorBlack()
      {
        if(!AnyData())return;
        paintSeries.Color=new SKColor((uint)SKColors.Black);
      }

		// ************************************************************************************************************************************
		// *********************************************************  R E N D E R E R *********************************************************
		// ************************************************************************************************************************************
		public void PaintSurface(SKSurface surface,SKImageInfo imageInfo)
      {
        SKCanvas canvas = surface.Canvas; 
        canvas.Clear();
        if(!AnyData())return;

        int width=imageInfo.Width;
        int height=imageInfo.Height;

        XDataExtent=GetXDataExtent(); 
        YDataExtent=GetYDataExtent();
        XDataExtentMin=GetXDataExtentMin(); 
        YDataExtentMin=GetYDataExtentMin();

        PointMapping pointMapping=new PointMapping(width,height,XDataExtent,XDataExtentMin,YDataExtent,YDataExtentMin,80,50);

        GridLines gridLines=new GridLines(10,10);
        gridLines.AssignXDataType=GetXDataType;
        gridLines.AssignGetYDataType=GetYDataType;
        gridLines.AssignYDataFormatter=YDataFormatter;
        gridLines.Render(canvas,pointMapping);

        if(null!=consumerPriceIndexLineGraph)consumerPriceIndexLineGraph.Render(canvas,pointMapping);
      }

      private double GetXDataExtent()
      {
        if(null==consumerPriceIndexLineGraph)return 0.00;
        return consumerPriceIndexLineGraph.GetXExtent(); 
      }

      private double GetYDataExtent()
      {
        if(null==consumerPriceIndexLineGraph)return 0.00;
        double maxDataExtent=consumerPriceIndexLineGraph.GetYExtent(); 
        return maxDataExtent;
      }

      // custom grid label formatter for the data along the left side of the chart.  We know a-priori that this is of type double.
      private String YDataFormatter(Object data)
      {
        Type dataType=data.GetType();
        String strValue=Utility.FormatNumberConstrain((double)data);
        return strValue;
      }

      private double GetXDataExtentMin()
      {
        if(null==consumerPriceIndexLineGraph)return 0.00;
        return consumerPriceIndexLineGraph.GetXExtentMin();
      }

      private double GetYDataExtentMin()
      {
        if(null==consumerPriceIndexLineGraph)return 0.00;
        return consumerPriceIndexLineGraph.GetYExtentMin();
      }

      private Type GetXDataType()
      {
        return typeof(DateTime);
      }

      private Type GetYDataType()
      {
        return typeof(double);
      }
		}
	}
