#include "stdafx.h"

extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lkf5defs.h"
}

#include "LKFAufenthalt.h"
#include "LKFAufenthaltAbteilung.h"
#include "LKFAufenthaltDiagnose.h"
#include "LKFAufenthaltMEL.h"
#include "LKFAufenthaltSubgruppe.h"
#include "LKFAufenthaltAkWarn.h"
#include "LKFAufenthaltIntLine.h"
#include "LKFAufenthaltError.h"
#include "LKFAufenthaltMeldeDiag.h"
#include "LKFException.h"

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

namespace lkfxdok {
	namespace c {
		LKFAufenthalt::LKFAufenthalt (LKFContextWithData ^context, void *aufenthaltPtr)
		{
			_aufenthaltPtr = aufenthaltPtr;
			_contextWithData = context;
			_plausContext = context;
		}

		LKFAufenthalt::LKFAufenthalt(LKFContext ^context) {
			_aufenthaltPtr = lkf_alloc_aufenthalt_context((LKF_CONTEXT *)context->_contextPtr);
			_contextWithData = nullptr;
			_plausContext = context;
		}

		LKFAufenthalt::~LKFAufenthalt() {
			this->!LKFAufenthalt();
		}

		LKFAufenthalt::!LKFAufenthalt() {
			if (_contextWithData == nullptr && _aufenthaltPtr != nullptr) {
				lkf_free_aufenthalt((LKF_AUFENTHALT *)_aufenthaltPtr);
				_aufenthaltPtr = nullptr;
			}
		}

		void LKFAufenthalt::AttachToContext(LKFContextWithData ^context) {
			_contextWithData = context;
			lkf_insert_aufenthalt((LKF_CONTEXT *)context->_contextPtr, (LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		int LKFAufenthalt::OutputLineCount::get(void) {
			return lkf_auf_getlineanz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		void LKFAufenthalt::ClearData(void) {
			lkf_reset_aufenthalt((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		void LKFAufenthalt::AddLine(String ^line)
		{
			char *cline = (char*)(Marshal::StringToHGlobalAnsi(line)).ToPointer();
			int ret = lkf_add_line_auf((LKF_AUFENTHALT *)_aufenthaltPtr, cline);
			Marshal::FreeHGlobal((IntPtr)cline);
			/*
			if (ret < 0) {

				if (_contextWithData != nullptr) {
					String^ str = _contextWithData->GetLastError();
					throw gcnew LKFException(ret, str);
				}

				throw gcnew LKFException(ret, "lkf_add_line_auf failed");
			}
			*/
		};

		unsigned int LKFAufenthalt::AbtCount::get(void) {
			return lkf_auf_get_abtanz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::HDiagCount::get(void) {
			return lkf_auf_get_hdiaganz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::ZDiagCount::get(void) {
			return DiagCount - HDiagCount;
		}

		unsigned int LKFAufenthalt::DiagCount::get(void) {
			return lkf_auf_get_diaganz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::MELCount::get(void) {
			return lkf_auf_get_melanz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::IntensivCount::get(void) {
			return lkf_auf_getintlineanz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::SubgruppeCount::get(void) {
			return lkf_auf_get_subgruppenanz((LKF_AUFENTHALT *) _aufenthaltPtr);
		}

		unsigned int LKFAufenthalt::AkWarnCount::get(void) {
			return lkf_auf_get_akwarnanz((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		bool LKFAufenthalt::IsOptimizable::get() {
			return lkf_auf_is_optimizable((LKF_AUFENTHALT *)_aufenthaltPtr) != 0;
		}

		String ^LKFAufenthalt::Ident::get() {
			char buf[128];
			const char *ident = lkf_auf_get_ident((LKF_AUFENTHALT *)_aufenthaltPtr, buf);
			return gcnew String (ident);
		}

		int LKFAufenthalt::Differences::get() {
			return lkf_auf_getdiff((LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		bool LKFAufenthalt::Select::get() {
			return lkf_auf_is_marked((LKF_AUFENTHALT *)_aufenthaltPtr) != 0;
		}

		void LKFAufenthalt::Select::set(bool v) {
			lkf_auf_mark((LKF_AUFENTHALT *)_aufenthaltPtr, v ? 1 : 0);
		}

		String ^LKFAufenthalt::Line::get() {
			char buf[2048];
			lkf_auf_line_root((LKF_AUFENTHALT *)_aufenthaltPtr, buf);
			return gcnew String(buf);
		}

		String ^LKFAufenthalt::LineKOST::get() {
			char buf[2048];
			if (lkf_auf_line_kost((LKF_AUFENTHALT *)_aufenthaltPtr, 0, buf))
				return gcnew String(buf);
			return nullptr;
		}

		String ^LKFAufenthalt::LineRESULT::get() {
			char buf[2048];
			if (lkf_auf_line_scoring((LKF_AUFENTHALT *)_aufenthaltPtr, buf))
				return gcnew String(buf);
			return nullptr;
		}

		String ^LKFAufenthalt::LineKOMMENTAR::get() {
			char buf[2048];
			if (lkf_auf_line_kommentar((LKF_AUFENTHALT *)_aufenthaltPtr, 0, buf))
				return gcnew String(buf, 0, (int) strlen(buf), System::Text::Encoding::UTF8);
			return nullptr;
		}

		LKFAufenthaltAbteilung ^LKFAufenthalt::GetAbteilung(unsigned int index)
		{
			if (index < AbtCount)
				return gcnew LKFAufenthaltAbteilung(this, index);
			return nullptr;
		}

		LKFAufenthaltDiagnose ^LKFAufenthalt::GetDiagnose(unsigned int index)
		{
			if (index < DiagCount)
				return gcnew LKFAufenthaltDiagnose(this, index);
			return nullptr;
		}

		LKFAufenthaltMEL ^LKFAufenthalt::GetMEL(unsigned int index)
		{
			if (index < MELCount)
				return gcnew LKFAufenthaltMEL(this, index);
			return nullptr;
		}

		LKFAufenthaltSubgruppe ^LKFAufenthalt::GetSubgruppe(unsigned int index)
		{
			if (index < SubgruppeCount)
				return gcnew LKFAufenthaltSubgruppe(this, index);
			return nullptr;
		}

		LKFAufenthaltAkWarn ^LKFAufenthalt::GetAkWarn(unsigned int index) {
			if (index < AkWarnCount)
				return gcnew LKFAufenthaltAkWarn(this, index);
			return nullptr;
		}

		LKFAufenthaltIntLine ^LKFAufenthalt::GetIntLine(unsigned int index) {
			if (index < IntensivCount)
				return gcnew LKFAufenthaltIntLine(this, index);
			return nullptr;
		}

		String ^LKFAufenthalt::GetOutputLine(int i) {
			char buf[2048];
			lkf_auf_getline((LKF_AUFENTHALT *)_aufenthaltPtr, i, buf);
			return gcnew String(buf, 0, (int) strlen(buf), System::Text::Encoding::UTF8);
		};

		int LKFAufenthalt::PlausCheck() {
			//if (_ownedByContext)
//				return -99;

			return lkf_plaus((LKF_CONTEXT *)_plausContext->_contextPtr, (LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		int LKFAufenthalt::PlausCheck(LKFContext ^context) {
			return lkf_plaus((LKF_CONTEXT *)context->_contextPtr, (LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		int LKFAufenthalt::Scoring() {
	//		if (_ownedByContext)
	//			return -99;

			return lkf_scoring((LKF_CONTEXT *)_plausContext->_contextPtr, (LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		int LKFAufenthalt::Scoring(LKFContext ^context) {
			return lkf_scoring((LKF_CONTEXT *)context->_contextPtr, (LKF_AUFENTHALT *)_aufenthaltPtr);
		}

		LKFAufenthaltError ^LKFAufenthalt::FirstError::get(void) {
			const void *ptr = lkf_auf_getSatzartError((LKF_AUFENTHALT *)_aufenthaltPtr);
			if (ptr == 0)
				return nullptr;
			return gcnew LKFAufenthaltError(this, ptr);
		}
/*
		LKFAufenthaltWarning ^LKFAufenthalt::FirstWarning::get(void) {
			void *ptr = lkf_auf_firstwarning((LKF_AUFENTHALT *)_aufenthaltPtr);
			if (ptr == 0)
				return nullptr;
			return gcnew LKFAufenthaltWarning(this, ptr);
		}

		LKFAufenthaltInfo ^LKFAufenthalt::FirstInfo::get(void) {
			void *ptr = lkf_auf_firstinfo((LKF_AUFENTHALT *)_aufenthaltPtr);
			if (ptr == 0)
				return nullptr;
			return gcnew LKFAufenthaltInfo(this, ptr);
		}
*/
		LKFAufenthaltMeldeDiag ^LKFAufenthalt::FirstMeldeDiag::get(void) {
			void *ptr = lkf_auf_firstmeldediag((LKF_AUFENTHALT *)_aufenthaltPtr);
			if (ptr == 0)
				return nullptr;
			return gcnew LKFAufenthaltMeldeDiag(this, ptr);
		}

		String ^LKFAufenthalt::GetFieldValue(LKFAufenthaltScorField field) {
			char buf[256];
			::lkf_auf_get_fieldvalue((LKF_AUFENTHALT *)_aufenthaltPtr, (unsigned int)(int)field, buf, 256);
			if (buf[0])
				return gcnew String(buf);
			return nullptr;
		}

		String ^LKFAufenthalt::AUFNR::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::AUFNR);
		}
		String ^LKFAufenthalt::KANR::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::KANR);
		}
		String ^LKFAufenthalt::PlausFlag::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::PlausFlag);
		}
		String ^LKFAufenthalt::GRUPPE::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::Gruppe);
		}
		String ^LKFAufenthalt::KNOTEN::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::Knoten);
		}
		String ^LKFAufenthalt::GesamtPunkte::get(void) {
			return GetFieldValue(LKFAufenthaltScorField::SCGES);
		}

		LKFAbtScoring ^LKFAufenthalt::GetAbtScoring(unsigned int abtIndex) {
			double kp, lp;
			lkf_auf_get_abtscor((LKF_AUFENTHALT *)_aufenthaltPtr, abtIndex, 0, &kp, &lp);
			return gcnew LKFAbtScoring(lp, kp);
		}

		long LKFAufenthalt::GetAbtBD(unsigned int abtIndex) {
			long bd;
			lkf_auf_get_abtbd((LKF_AUFENTHALT *)_aufenthaltPtr, abtIndex, &bd);
			return bd;
		}

		bool LKFAufenthalt::TK::get(void) {
			return lkf_auf_get_scorvalue((LKF_AUFENTHALT *)_aufenthaltPtr, 97) == 2;
		}

		long LKFAufenthalt::GetLongFieldValue(unsigned int fieldNum) {
			char buf[256];
			lkf_auf_get_fieldvalue((LKF_AUFENTHALT *)_aufenthaltPtr, fieldNum, buf, 256);
			return atol(buf);
		}

		double LKFAufenthalt::GetDoubleFieldValue(unsigned int fieldNum) {
			char buf[256];
			lkf_auf_get_fieldvalue((LKF_AUFENTHALT *)_aufenthaltPtr, fieldNum, buf, 256);
			return atof(buf);
		}

		String ^LKFAufenthalt::GetStringFieldValue(unsigned int fieldNum) {
			char buf[256];
			lkf_auf_get_fieldvalue((LKF_AUFENTHALT *)_aufenthaltPtr, fieldNum, buf, 256);
			return gcnew String(buf);
		}

		long LKFAufenthalt::GESBD::get(void) {
			return GetLongFieldValue(14);
		}

		long LKFAufenthalt::Alter::get(void) {
			return GetLongFieldValue(5);
		}

		long LKFAufenthalt::BDU::get(void) {
			return GetLongFieldValue(23);
		}

		long LKFAufenthalt::BDO::get(void) {
			return GetLongFieldValue(24);
		}

		double LKFAufenthalt::BDMW::get(void) {
			return GetDoubleFieldValue(25);
		}


		LKFAbtScoring::LKFAbtScoring(double lp, double kp) {
			_kp = kp;
			_lp = lp;
		}

		double LKFAbtScoring::LP::get(void) {
			return _lp;
		}

		double LKFAbtScoring::KP::get(void) {
			return _kp;
		}
	}
}


