using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MccSdk = BioLab.Biometrics.Mcc.Sdk;

namespace ResultsExtraction
{
  public static class ROC
  {
    private static readonly double coefficient = 0.01;

    public static void GetPositiveRates(string path, string outputName)
    {
      // Create all information about fingerprints 
      FingerprintsDictionary dictionary = new FingerprintsDictionary(path);
      List<List<FingerprintStruct>> sameList = new List<List<FingerprintStruct>>();

      foreach (var pair in dictionary.DictionaryOfSame)
      {
        sameList.Add(pair.Value);
      }

      int countOfThreshold = 99;
      int[] tpr = new int[countOfThreshold];
      int[] fpr = new int[countOfThreshold];
      double resultSame = 0, resultNotSame = 0;
      int countOfMatching = 0;
      double threshold;

      SetMatchParameters();

      for (int k = 0; k < sameList.Count; k++)
      {
        int next = k + 1 < sameList.Count ? k + 1 : 0;

        for (int i = 0; i < sameList[k].Count; i++)
        {
          for (int j = i + 1; j < sameList[k].Count; j++)
          {
            resultSame = Match(sameList[k][i].Template, sameList[k][j].Template);
            resultNotSame = Match(sameList[k][i].Template, sameList[next][j].Template);

            for (int m = 0; m < countOfThreshold; m++)
            {
              threshold = (m + 1) * coefficient;
              // if same are same => +1
              tpr[m] += resultSame >= threshold ? 1 : 0;
              // if notSame are same => +1
              fpr[m] += resultNotSame >= threshold ? 1 : 0;
            }

            countOfMatching++;
          }
        }
      }

      PrintResult(tpr, fpr, countOfMatching, countOfThreshold, outputName);
    }

    private static void SetMatchParameters()
    {
      MccSdk.MccSdk.SetMccMatchParameters(Resources.MccMatchParameters);
    }

    private static double Match(object template1, object template2)
    {
      return MccSdk.MccSdk.MatchMccTemplates(template1, template2);
    }

    public static void PrintResult(int[] tpr, int[] fpr, int countOfMatching, int countOfThreshold, string name)
    {
      // count
      // fpr; tpr
      StreamWriter sw = new StreamWriter(name);
      sw.WriteLine(countOfMatching);

      for (int m = 0; m < countOfThreshold; m++)
      {
        sw.WriteLine("{0};{1}", fpr[m], tpr[m]);
      }

      sw.Close();
      Process.Start(name);
    }

    public static bool IsGoodMinutia(int value)
    {
      // kind of minutiae for template 
      return value > 1;  // 2,3,4
    }
  }
}

