import "doc_Storage.jnc"
import "std_HashTable.jnc"

// non-unique key-value store

namespace ui {

//! \addtogroup api-ui
//! @{

//..............................................................................

struct DictionaryEntry {
	DictionaryEntry cmut* m_next;
	char const* m_key;
	char const* m_value;
	bool m_isChecked;
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

DictionaryEntry* loadDictionary(
	doc.Storage* storage,
	char const* name,
	size_t* count = null
) {
	DictionaryEntry* dictionary = null;
	DictionaryEntry* prevEntry = null;

	for (size_t i = 0;; i++) {
		char const* key = storage.readString($"%1-key-%2"(name, i));
		if (!key)
			break;

		DictionaryEntry* entry = new DictionaryEntry;
		entry.m_key = key;
		entry.m_value = storage.readString($"%1-value-%2"(name, i));
		entry.m_isChecked = storage.readBool($"%1-checked-%2"(name, i), true);

		if (prevEntry)
			prevEntry.m_next = entry;
		else
			dictionary = entry;

		prevEntry = entry;
	}

	return dictionary;
}

void saveDictionary(
	DictionaryEntry const* dictionary,
	doc.Storage* storage,
	char const* name
) {
	size_t i = 0;
	DictionaryEntry const* entry = dictionary;
	for (; entry; entry = entry.m_next, i++) {
		storage.writeString($"%1-key-%2"(name, i), entry.m_key);
		storage.writeString($"%1-value-%2"(name, i), entry.m_value);
		storage.writeBool($"%1-checked-%2"(name, i), entry.m_isChecked);
	}

	storage.writeString($"%1-key-%2"(name, i), null); // null-terminate
}

DictionaryEntry* insertDictionaryHead(
	DictionaryEntry* dictionary,
	char const* key,
	char const* value,
	bool isChecked = true
) {
	DictionaryEntry entry;
	entry.m_key = key;
	entry.m_value = value;
	entry.m_isChecked = isChecked;
	entry.m_next = dictionary;
	return entry;
}

std.StringHashTable* createDictionaryHashTable(DictionaryEntry const* dictionary) {
	std.StringHashTable hashTable;
	DictionaryEntry const* entry = dictionary;
	for (; entry; entry = entry.m_next)
		if (entry.m_isChecked)
			hashTable[entry.m_key] = entry.m_value;

	return hashTable;
}

DictionaryEntry* findDictionaryEntry(
	DictionaryEntry* dictionary,
	char const* key
) {
	DictionaryEntry* entry = dictionary;
	for (; entry; entry = entry.m_next)
		if (strcmp(entry.m_key, key) == 0)
			return entry;

	return null;
}

//..............................................................................

//! @}

} // namespace ui
