/*
	ZRegistry.hpp
	Author: James Russell <jcrussell@762studios.com>
	Created: 2/18/2013

	Purpose: 

	ZRegistry defines a use case for ZKVTree as a concurrent data store.  A ZRegistry
	maps keys to values using path strings, just as ZKVTree does, but the path string 
	must be unique as subscripts are not supported and siblings with the same name
	are not supported.

	ZRegistry is thread-safe on all operations.

	ZRegistry (currently) supports only string value types, but the return value struct
	from 'Get' can be converted to integer and double types with the Convert() function.

	License:

	TODO

*/

#pragma once

#ifndef _ZREGISTRY_HPP
#define _ZREGISTRY_HPP

#include <ZUtil/ZConcurrency.hpp>
#include <ZUtil/ZKVTree.hpp>

class ZRegistry
{
public:
	/*
	Default Constructor.
	*/
	ZRegistry();

	/*
	Constructs this registry from a KVTree.
	*/
	ZRegistry(const ZKVTree& _tree);

	/*
	Destructor.
	*/
	~ZRegistry();

	/*
	ZRegistry value type, which will evaluate to true if the value was found
	and false otherwise.
	*/
	class Value
	{
	friend class ZRegistry;
	public:
		/*
		Operator overload used to get the value.
		*/
		operator ZString () const
			{ return Val; }
		
		/*
		Function used to verify validity of the returned value.
		*/
		bool Valid() const
			{ return bValid; }

		/*
		Function used to get the string value.
		*/
		const ZString& GetString() const
			{ return Val; }

		int GetInt() const 
			{ return ZStringAlgo::NumericInt(Val); }

		double GetDouble() const 
			{ return ZStringAlgo::NumericDouble(Val); }

	private:
		/*
		Constructor, which initializes the reference and the flag indicating
		whether or not this is a valid value.
		*/
		Value(const ZString& _val, bool _valid)
			: Val(_val), bValid(_valid) { }
		
		ZString	Val;		//Value copy (cannot maintain reference into data structure)
		bool	bValid;		//Validity flag
	};

	/*
	public ZRegistry::operator []

	[] operator overload, equivalent to Get(_key).

	@param _key - the key to look up
	@return (const ZString&) - the value looked up
	*/
	const Value operator [] (const ZString& _key) const
		{ return Get(_key); }

	/*
	public ZRegistry::Erase

	Erases a key/value pair (and all child key/value pairs) from the registry.

	@param _key - the key to erase
	@return (void)
	*/
	void Erase(const ZString& _key);

	/*
	public ZRegistry::Get

	Returns the value instance bound to the given key.

	@param _key - the key to evaluate
	@return (Value) - value instance for this key
	*/
	const Value Get(const ZString& _key) const;

	/*
	public ZRegistry::Put

	Places a key / value pair into the registry.  Will create any necessary nodes
	to place the key and value pair.

	@param _key - the key to map
	@param _value - the value to map to the key
	@return (bool) - true if able to map the key/value, false otherwise
	*/
	bool Put(const ZString& _key, const ZString& _value);

private:
	DISABLE_COPY_AND_ASSIGN(ZRegistry);

	ZReadWriteLock	Lock;		//The concurrency read write lock
	ZKVTree			Tree;		//The tree we store out data in
};

#endif
 
