/*
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
  <file> UlsObject.cpp </file>
  <brief>
   This implements basic class.
  </brief>
  <author>
    Stanley Hong <link2next@gmail.com>, Oct. 2017.
  </author>
*/
#include "Stdafx.h"
#include "UlsLog.h"
#include <ctype.h>

using namespace System;

#define _uls_log_static(proc) UlsLog::proc##_static

namespace uls {
	namespace polaris {
#define ULS_CLASS_NAME UlsObject

	static ULS_CLASS_NAME::ULS_CLASS_NAME()
	{
		sys_global_lock = CreateMutex(NULL, FALSE, NULL);
		if (sys_global_lock == INVALID_HANDLE_VALUE) {
			_uls_log_static(err_panic)("Fatal Error: Can't create system lock!");
		}
	}

	void ULS_CLASS_NAME::deInitializeClass()
	{
		CloseHandle(sys_global_lock);
		sys_global_lock = INVALID_HANDLE_VALUE;
	}

	ULS_CLASS_NAME::ULS_CLASS_NAME()
	{
		i_uls_obj = -1;
	}

	void ULS_CLASS_NAME::sysLock()
	{
		DWORD dwWaitResult;

		dwWaitResult = WaitForSingleObject(sys_global_lock, INFINITE);
		if (dwWaitResult != WAIT_OBJECT_0) {
			_uls_log_static(err_panic)("Fatal Error: Failed to lock the system lock!");
		}
	}

	void ULS_CLASS_NAME::sysUnlock()
	{
		ReleaseMutex(sys_global_lock);
	}

	void ULS_CLASS_NAME::changeUlsObjectIndex(int ind)
	{
		i_uls_obj = ind;
	}

	void ULS_CLASS_NAME::addUlsObject2List(UlsObjectListExp ^list)
	{
		sysLock();

		if (list->n >= list->siz) {
			list->siz += 16;
			Array::Resize(list->lst, list->siz);
		}

		i_uls_obj = list->n++;
		changeUlsObjectIndex(i_uls_obj);
		list->lst[i_uls_obj] = this;

		sysUnlock();
	}

	void ULS_CLASS_NAME::delUlsObject2List(UlsObjectListExp ^list)
	{
		UlsObject ^oo_j;
		int j_uls_obj;

		sysLock();

		j_uls_obj = list->n - 1;
		if (i_uls_obj != j_uls_obj) {
			oo_j = list->lst[j_uls_obj];
			list->lst[i_uls_obj] = oo_j;
			oo_j->changeUlsObjectIndex(i_uls_obj);
		}

		list->lst[j_uls_obj] = nullptr;
		--list->n;

		sysUnlock();
	}

	void ULS_CLASS_NAME::finalizeUlsObjectList(UlsObjectListExp ^list)
	{
		int i;

		sysLock();

		for (i = 0; i < list->n; i++) {
			UlsObject ^oo = list->lst[i];
			list->lst[i] = nullptr;
			oo->finalizer();
		}

		sysUnlock();
	}

	void ULS_CLASS_NAME::finalizer()
	{
	}

#undef ULS_CLASS_NAME
	} //  End of polaris
} //  End of uls
