#pragma once

#include "btree.h"

class StringBTree
	: public BTreeBase
{
public:
	typedef int TraverseStringCallback(const String* const string, void* const arg);

	struct Key
	{
		inline Key()
			: data(nullptr)
			, length(0)
		{
		}

		inline Key(const void* const data, const uint32_t length)
			: data(data)
			, length(length)
		{
		}

		const void* data;
		size_t length;
	};

	inline StringBTree(const void* const table_data)
		: BTreeBase(table_data, key_comparsion_op(&key_less_than_op), key_comparsion_op(&key_equal_op))
	{
	}

	inline ~StringBTree()
	{
	}

	inline bool search_by_index(const uint32_t index, String* string) const
	{
		const void* const data = BTreeBase::search(index);
		if (!data)
			return false;
		return string->parse(data) != nullptr;
	}

	inline const void* search(const char* const string, uint32_t* const index = nullptr) const
	{
		return search(string, strlen(string), index);
	}

	inline const void* search(const char* const string, const size_t string_length, uint32_t* const index = nullptr) const
	{
		return BTreeBase::search(&Key(string, string_length), index);
	}

	inline uint32_t index_by_string(const char* const string) const
	{
		return index_by_string(string, strlen(string));
	}

	inline uint32_t index_by_string(const char* const string, const size_t string_length) const
	{
		uint32_t index;
		search(string, string_length, &index);
		return index;
	}

	inline void traverse(TraverseStringCallback* const callback, void* const arg) const
	{
		TraverseCallbackArgs<TraverseStringCallback> args(callback, arg);
		BTreeBase::traverse(traverse_callback, &args);
	}

protected:
	virtual const void* skip_node_data(const void* const node) const;

private:
	static int key_equal_op(const Key* const key, const void* const data);
	static int key_less_than_op(const Key* const key, const void* const data);

	static int traverse_callback(const void* const data, void* const arg);
};
