//#include "..\..\Language.h"

#ifndef SIMPLEUNITTESTS_H__ 
#define SIMPLEUNITTESTS_H__
#if  __cplusplus_cli

#include "NearlyEqual_vc.h"
#include <string>

namespace rk1 {

using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;


ref class Assert {
  static int PassCount,FailCount;
  static TextBox^ tb=nullptr; 
  static FileStream^ fs=nullptr; 
  static StreamWriter^ w=nullptr;

  static void showResult(bool passed, String^ msg) 
  { // shows one test result 
  if (!passed)
    {
      WriteLine("Test failed: "+msg);
      ++FailCount;
    }
  else
    {
      if (logTestcases)
        WriteLine("Test passed: "+msg);
      ++PassCount;
    }
  }

  template<typename T>
  static void showResult(T expected, T actual, String^ message) 
  {
  showResult(expected==actual," erwartet: <"+expected.ToString()+">, tatsächlich: <"+actual.ToString()+"> "+message);
  }

  template<typename T>
  static void showResult(T* expected, T* actual, String^ message) 
  {
  showResult(expected==actual," erwartet: <"+expected->ToString()+">, tatsächlich: <"+actual->ToString()+"> "+message);
  }

  static void showResult(std::string expected, std::string actual, String^ message) 
  { // ??? schöner
  String^ exp(gcnew System::String(expected.c_str()));
  String^ act(gcnew System::String(actual.c_str()));
  showResult(expected==actual," erwartet: <"+exp+">, tatsächlich: <"+
             act+"> "+message);
  }


  static void showResult(std::wstring expected, std::wstring actual, String^ message) 
  { // ??? schöner
  String^ exp(gcnew System::String(expected.c_str()));
  String^ act(gcnew System::String(actual.c_str()));
  
  showResult(expected==actual," erwartet: <"+exp+">, tatsächlich: <"+
             act+"> "+message);
  }

  static void showResult(String^ expected, String^ actual, String^ message) 
  { // ??? schöner
  showResult(expected==actual," erwartet: <"+expected+
             ">, tatsächlich: <"+actual+"> "+message);
  }

 public:
  
  Assert()
  { // hier oder oben initialisieren? Unterschied ???
    fs=nullptr; 
    w=nullptr;
    PassCount=0;
    FailCount=0;
    tb=nullptr; 
  }

  static void WriteLine(String^ s)
  {
  if (tb!=nullptr)
     tb->AppendText(s+"\r\n");
  if (fs!=nullptr && fs->CanWrite)
    {
      w->WriteLine(s);
      w->Flush();
    }
  }
  
  static property bool logTestcases;

  static void Init(TextBox^ out) 
  {
  tb=out;
  PassCount=0;
  FailCount=0;
  }

  static void Init(TextBox^ out, String^ message) 
  {
  Init(out);
  WriteLine(message);
  }

  static void OpenOutputFile(String^ FileName) 
  {
  if (fs!=nullptr)
    {
      w->Close();
      fs->Close();
    }
  fs = gcnew FileStream(FileName,FileMode::Create);
  w = gcnew StreamWriter(fs);
  }

  static void Reset() 
  {
  PassCount=0;
  FailCount=0;
  }
/*  
  static void Fail(String^ s)
  {
  WriteLine(s);
  }
*/  
  ~Assert()
  {
  if (fs!=nullptr)
    {
      w->Close();
      fs->Close();
    }
  }
  

  template<typename T>
  static void AreEqual (T expected, T actual, String^ message)
  {
  showResult(expected, actual, message);
  }
 
  template<typename T>
  static void AreEqual (T expected, T actual)
  {
  AreEqual(expected, actual, "");
  }
   
  static void AreEqual(double expected, double actual, int digits, String^ message)
  { // digits: the number of significant digits, for which the values have to be equal
  showResult(NearlyEqual2(expected,actual,digits)," erwartet: <"+expected.ToString()+">, tatsächlich: <"+actual.ToString()+"> "+message);
  }

  static void AreEqual(double expected, double actual, int digits)
  { // digits: the number of significant digits, for which the values have to be equal
  showResult(NearlyEqual2(expected,actual,digits)," erwartet: <"+expected.ToString()+">, tatsächlich: <"+actual.ToString()+"> ");
  }

  static void AreEqual(double expected, double actual, String^ message)
  { // usually 10 significant digits are enough for type double
  int DefaultDigits=10;
  AreEqual(expected, actual, DefaultDigits, message);
  }

  static void AreNotEqual(double expected, double actual, int digits, String^ message)
  { 
  showResult(!NearlyEqual2(expected, actual,digits)," erwartet: <"+expected.ToString()+">, tatsächlich: <"+actual.ToString()+"> "+message);
  }

  static void AreNotEqual(double expected, double actual, int digits)
  { 
  showResult(!NearlyEqual2(expected, actual,digits)," erwartet: <"+expected.ToString()+">, tatsächlich: <"+actual.ToString()+"> ");
  }

  static void AreNotEqual(double expected, double actual, String^ message)
  { 
  int DefaultDigits=10;
  AreNotEqual(expected,actual,DefaultDigits, message);
  }

  static void Summary()
  {
  if (tb!=nullptr)
    {
      if (FailCount==0)
        WriteLine("All tests passed (total: "+
                   PassCount.ToString()+")");
      else
        WriteLine(FailCount.ToString()+
           " Tests failed from "+ (PassCount+FailCount).ToString());
    }
}

};

} // end of namespace rk1 

#endif // __cplusplus_cli

#endif // SIMPLEUNITTESTS_H__
