using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZedGraph;
using ResultsExtraction;
using CUDAFingerprinting.Common;

namespace DrawGraphics
{
  public partial class MainForm : Form
  {
    private char[] splitter = new char[] { ';' };
    private char[] splitterMap = new char[] { ' ' };
    private const int countOfThreshold = 99;
    private int count = 0;
    private int[] x = new int[countOfThreshold];
    private int[] fx = new int[countOfThreshold];
    private string roc = @"..\..\..\Results\ROC\";

    private int imgX = 46;
    private int imgY = 32;

    public MainForm()
    {
      InitializeComponent();
      DrawAllGraphs();
    }

    #region Sum file
    public void GetSumFile(string folder)
    {
      string path = roc + folder;
      string[] files = Directory.GetFiles(path);

      foreach (string file in files)
      {
        AddPoints(file);
      }

      if (count == 0)
      {
        throw new ArgumentException();
      }

      StreamWriter sw = new StreamWriter(path + "sum.txt");
      sw.WriteLine(count);

      // or some map
      for (int i = 0; i < countOfThreshold; i++)
      {
        sw.WriteLine("{0};{1}", (double)x[i] / count, (double)fx[i] / count);
      }

      sw.Close();
    }

    private void AddPoints(string name)
    {
      StreamReader sr = new StreamReader(name);
      int threshold = 0;
      count += Int32.Parse(sr.ReadLine());

      while (!sr.EndOfStream)
      {
        if (threshold >= countOfThreshold)
        {
          throw new ArgumentException();
        }

        string[] split = (sr.ReadLine()).Split(splitter);
        x[threshold] += Int32.Parse(split[0]);
        fx[threshold] += Int32.Parse(split[1]);
        threshold++;
      }

      sr.Close();
    }
    #endregion

    #region Graphs
    private void DrawAllGraphs()
    {
      GraphPane pane = zedGraph.GraphPane;

      pane.Title.Text = "";
      // not same => same +   FMR
      pane.XAxis.Title.Text = "FMR (False Match Rate)";
      // same => same +  TMR => 1 - FNMR
      pane.YAxis.Title.Text = "FNMR (False Non-Match Rate)"; // = True Match Rate";
      pane.CurveList.Clear();

      AddLineToPane("all", "все минуции", Color.Black, ref pane);
      AddLineToPane("4", "минуции качества 1", Color.Blue, ref pane);
      AddLineToPane("34", "минуции качества 1,2", Color.Green, ref pane);
      AddLineToPane("3", "минуции качества 2", Color.Aqua, ref pane);
      AddLineToPane("234", "минуции качества 1,2,3", Color.Red, ref pane);
      AddLineToPane("2", "минуции качества 3", Color.Coral, ref pane);
      AddLineToPane("1234", "минуции качества 1,2,3,4", Color.Yellow, ref pane);
      AddLineToPane("1", "минуции качества 4", Color.Gray, ref pane);
      AddLineToPane("23", "минуции качества 2,3", Color.Brown, ref pane);

      PointPairList idealList = new PointPairList(new double[] { 0.0, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 1.0 }, new double[] { 0.0, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 1.0 });
      LineItem myCurve = pane.AddCurve("EER", idealList, Color.Goldenrod, SymbolType.None);

      pane.XAxis.Scale.Min = 0.0;
      pane.XAxis.Scale.Max = 1.0;
      pane.YAxis.Scale.Min = 0.0;
      pane.YAxis.Scale.Max = 1.0;
      zedGraph.AxisChange();
      zedGraph.Invalidate();
    }

    private void AddLineToPane(string folderName, string nameToPane, Color color, ref GraphPane pane)
    {
      PointPairList list = GetPoints(folderName);
      LineItem myCurve = pane.AddCurve("DET: " + nameToPane, list, color, SymbolType.None);
    }

    private PointPairList GetPoints(string name)  // name as "all"
    {
      PointPairList list = new PointPairList();
      StreamReader sr = new StreamReader(roc + name + @"\sum.txt");
      int countOfMatching = Int32.Parse(sr.ReadLine());
      double x, fx;

      while (!sr.EndOfStream)
      {
        string[] split = (sr.ReadLine()).Split(splitter);
        x = Double.Parse(split[0]);
        fx = Double.Parse(split[1]);
        list.Add(x, 1 - fx);
      }

      sr.Close();
      return list;
    }

    private void DrawGraph()
    {
      GraphPane pane = zedGraph.GraphPane;

      pane.Title.Text = "";
      pane.XAxis.Title.Text = "FMR (False Match Rate)";
      pane.YAxis.Title.Text = "FNMR (False Non-Match Rate)"; 
      pane.CurveList.Clear();

      var p = GetPointsDET("34");
      LineItem myCurve = pane.AddCurve("DET-кривая", p, Color.Red, SymbolType.None);
     
      pane.XAxis.Scale.Min = 0.0;
      pane.XAxis.Scale.Max = 1.0;
      pane.YAxis.Scale.Min = 0.0;
      pane.YAxis.Scale.Max = 1.0;
      zedGraph.AxisChange();
      zedGraph.Invalidate();
    }

    private Tuple<PointPairList, PointPairList> GetPointsFMR(string name)  
    {
      PointPairList list1 = new PointPairList();
      PointPairList list2 = new PointPairList();
      StreamReader sr = new StreamReader(roc + name + @"\sum.txt");
      int countOfMatching = Int32.Parse(sr.ReadLine());
      double x, fx;
      double t = 0.01;

      while (!sr.EndOfStream)
      {
        string[] split = (sr.ReadLine()).Split(splitter);
        x = Double.Parse(split[0]);
        fx = Double.Parse(split[1]);
        list1.Add(t, x);
        list2.Add(t, 1 - fx);
        t += 0.01;
      }

      sr.Close();
      return new Tuple<PointPairList, PointPairList>(list1, list2);
    }

    private PointPairList GetPointsDET(string name)  
    {
      PointPairList list = new PointPairList();
      StreamReader sr = new StreamReader(roc + name + @"\sum.txt");
      int countOfMatching = Int32.Parse(sr.ReadLine());
      double x, fx;

      while (!sr.EndOfStream)
      {
        string[] split = (sr.ReadLine()).Split(splitter);
        x = Double.Parse(split[0]);
        fx = Double.Parse(split[1]);
        list.Add(x, fx);
      }

      sr.Close();
      return list;
    }

    #endregion

    #region Maps
    private void SaveImgMap(string name)
    {
      double[,] image = new double[imgX, imgY]; 
      StreamReader sr = new StreamReader(name);
      int i = 0;

      while (!sr.EndOfStream)
      {
        string[] split = (sr.ReadLine()).Split(splitterMap);

        for (int j = 0; j < imgY; j++)
        {
          image[i, j] = Int32.Parse(split[j]);
        }

        i++;
      }

      sr.Close();
      ImageHelper.SaveArray(image, name + ".bmp");
    }
    #endregion
  }
}
