
#include "Stdafx.h"

#pragma once
#include "lkfxdok.h"

using namespace System::Runtime::InteropServices;

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

#include "LKFController.h"
#include "LKFDataProvider.h"
#include "LKFSemaphoreHandler.h"
#include "LKFException.h"
#include "LKFMemoryDelegate.h"

namespace lkfxdok {
	namespace c {
		String ^LKFController::Version::get(void) {
			const char *v = lkf_GetVersion();
			return gcnew String(v);
		}

		String ^LKFController::DataPath::get (void) {
			if (_path != nullptr)
				return _path;
			return "NULL";
		}
			
		void LKFController::DataPath::set(String ^path) {
			_path = path;
		}

		unsigned int LKFController::ModelljahrMinimum::get(void) {
			return lkf_GetYearFirst();
		}

		unsigned int LKFController::ModelljahrMaximum::get(void) {
			return lkf_GetYearLatest();
		}

		void LKFController::activateMetaDataSemaphore(void) {

			if (_metaDataSemaphoreHandler == nullptr) {
				_metaDataSemaphoreHandler = gcnew LKFSemaphoreHandler();
			}
			_metaDataSemaphoreHandler->assign();
			
		}

		void LKFController::enableMemoryTrace(void) {
			if (lkf_enableMemoryTrace() < 0) {
				throw gcnew LKFException(-1, "cannot enable memory trace");
			}
		}

		void LKFController::setMemoryDelegate(LKFMemoryDelegate^ memoryDelegate) 
		{
			memoryDelegate->Assign();
		}

		void LKFController::setMemoryDebugLimit(long availableMemory, long usedMemory, String^ breakingKey, int count) {

			char* breakingPtr = (char*)Marshal::StringToHGlobalAnsi(breakingKey).ToPointer();
			lkf_set_memoryDebugLimit(availableMemory, usedMemory, breakingPtr, count);			
			Marshal::FreeHGlobal((IntPtr)breakingPtr);
		}

		void LKFController::clearDebugMemoryCallback(void) {
			lkf_setMemoryTraceDelegate(nullptr, 0);
		}

		unsigned long long LKFController::getDebugMemoryBytes(void) {
			return lkf_debugmemory_bytes();
		}

		unsigned long long LKFController::getDebugMemoryBlocks(void) {
			return lkf_debugmemory_blocks();
		}

		LKFDataProvider ^LKFController::DataProvider::get() {
			return _dataProvider;
		}

		void LKFController::DataProvider::set(LKFDataProvider ^provider) {
			if (_dataProvider != nullptr) {
				_dataProvider->Deassign();
			}
			_dataProvider = provider;
			if (_dataProvider != nullptr) {
				_dataProvider->Assign();
			}
		}
	}
}
