#pragma once

using namespace System;
using namespace System::IO;
using namespace System::Runtime::InteropServices;

namespace lkfxdok {
	namespace c {

		ref class LKFAufenthalt;
		ref class LKFIntContext;
		ref class LKFStatContext;
		ref class LKFNeoPaedContext;
		ref class LKFMetaData;

		public enum class LKFContextFileType : int { Error, Warning, Info, Stat, Result };

		public enum class LKFContextFlags : int { BM = 1, _Convert2017 = 4, StandortOff = 8, _FillBMG = 16, UTF8 = 32, Quickscore = 64, _Optimizer = 128,
		                                          PrivateSpezList = 256, PrivateKostList = 512, PrivateMELKAList = 1024,
												  NPPlaus = 2048, NichtFonds = 4096, NurMBDS = 8192, IntensivPunkte = 16384, ExportLSatzarten = 32768, AufenthaltIntensivEW = 65536, OSG = 262144,
												  DisableSomeChecks = 524288, _AbrechnungsjahrDynamisch = 1048576, _Sim1 = 2097152, _Sim2Disable2017 = 4194304,
												  OSGWarn = 8388608, _AcceptAllErrors = 16777216, _AcceptAllWarnings = 33554432, _Sim3 = 67108864, };

		public enum class LKFContextPeriode : char { Jahr = 'J', Monat = 'M', Quartal = 'Q', Halbjahr = 'H', Tag = 'T'};

		public ref class LKFContext
		{
		internal:
			void *_contextPtr;
			int _flags;
			int _modelljahr;
			int _abrechnungsjahr;

		public:
			LKFContext();

			~LKFContext();
			!LKFContext();

			property int Flags { int get(void);  void set(int);  }

			property int Modelljahr {
				int get(void);
				virtual void set(int modelljahr);
			}

			property int Abrechnungsjahr {
				int get(void);
				virtual void set(int abrechnungsjahr);
			}

			void Debug_Free();

			virtual void SetAbrechnungsPeriode(int jahr, int period_val, int lfdnr, LKFContextPeriode type, int flags);
		
			void EnableTrace(int facility, int level);
			void EnableDebugTrace();
			void SetTraceAufenthalt(String ^patid);


			void SetMetaData(LKFMetaData^ metaData);

			String^ GetMeldeDiagTypeText (char i);
			String^ GetMeldeDiagText(char i);

			String^ GetErrorText();
			String^ GetOutOfMemoryText();

			property unsigned int TraceLineCount {
				unsigned int get(void);
			}

			String ^GetTraceLine(unsigned int index);
		protected:
			void ThrowOutOfMemoryException(String^ functionName);

		};

		public ref class LKFContextWithData : public LKFContext
		{
			int _lastImportLineCount;
			int _lastImportCharCount;
			int _lastImportErrorCount;
		protected:
			int _abrechnungsjahr;

		public:
			LKFContextWithData();

			property unsigned int AufenthaltCount {
				unsigned int get(void);
			}

			void PlausCheck();
			void Scoring();

			int PlausCheck ([Out] String ^%error);
			int Scoring ([Out] String ^%error);
			String^ GetLastError();

			LKFIntContext ^IntScoring();
			LKFStatContext ^Stat();
			LKFNeoPaedContext ^NeoPaed();
			LKFAufenthalt ^GetAufenthalt(unsigned int index);
			void AddLine(String ^line);
			void LoadFile(String ^fileName);
			void AddBuffer(array<unsigned char> ^buffer);

			void WriteResultFile(StreamWriter^ f);
			void WriteFile(LKFContextFileType fileType, String ^outputFileName);
			void WriteFile(LKFContextFileType fileType, StreamWriter^ streamWriter);
			void WriteCSVFile(array<int>^ fields, StreamWriter^ streamWriter);
			void WriteCSVFile(array<int>^ fields, String^ outputFileName);

			property unsigned int AdditionalLines {
				unsigned int get(void);
			}

			String ^GetAdditionalLine(unsigned int index);

			void SetErrorFormat(unsigned int facility, array<int> ^fields);
			unsigned int SetErrorFilter(unsigned int filter);
			String  ^GetErrorHeadLine(unsigned int errorIndex);
			String  ^GetError(unsigned int errorIndex);
			String  ^GetErrorField(unsigned int index, unsigned int errorField);

			property unsigned int ErrorCount {
				unsigned int get(void);
			}
			property unsigned int WarningCount {
				unsigned int get(void);
			}

			property unsigned int AufenthaltErrorCount {
				unsigned int get(void);
			}
			property unsigned int AufenthaltWarningCount {
				unsigned int get(void);
			}

			property int LastImportLineCount {
				int get(void);
			}

			property int LastImportCharCount {
				int get(void);
			}

			property int LastImportErrorCount {
				int get(void);
			}


			property unsigned int InfoCount {
				unsigned int get(void);
			}

			property unsigned int AcceptedErrorCount {
				unsigned int get(void);
			}
			property unsigned int AcceptedWarningCount {
				unsigned int get(void);
			}
			property unsigned int AcceptedInfoCount {
				unsigned int get(void);
			}

			int GetAmbCounter(unsigned int ambIndex);
			int GetContextValue(int contextvalue);
			double GetContextScoringValue(unsigned int contextvalue);


		};

		public ref class LKFContextForStat : public LKFContextWithData 
		{
		public:
			LKFContextForStat();

			property int Modelljahr {
				void set(int modelljahr) override;
			}

			property int Abrechnungsjahr {
				void set(int abrechnungsjahr) override;
			}

			void SetAbrechnungsPeriode(int jahr, int period_val, int lfdnr, LKFContextPeriode type, int flags) override;


		};
	}
}