// ---------------------------------------------------------------------------------
//  clipboard.h:
//      Wrapper class for Windows clipboard operations.
//
//  2009 Written by Luis García.
//
//  History:
//    09.08.20 - Added STL like functions
//    09.08.19 - First release
// ---------------------------------------------------------------------------------

#if !defined CLIPBOARD_H
#define CLIPBOARD_H

#include <string>
#include <iterator>

namespace newcastle {

	struct _Clipboard_traits_A {
		typedef size_t							_Size_type;
		typedef char							_Value_type;
		typedef _Value_type *					_Pointer;
		typedef const _Value_type *				_Const_pointer;
		typedef std::basic_string<_Value_type>	_String;

		static void _Assign(
			_Const_pointer _Ptr, _Size_type _Count
			);

		static bool _IsAvailable(
			);

		static bool _IsEmpty(
			);

		static void _Clear(
			);

		static _Size_type _Size(
			);

		static _String _Str(
			);

	};

	struct _Clipboard_traits_W {
		typedef size_t							_Size_type;
		typedef wchar_t							_Value_type;
		typedef _Value_type *					_Pointer;
		typedef const _Value_type *				_Const_pointer;
		typedef std::basic_string<_Value_type>	_String;

		static void _Assign(
			_Const_pointer _Ptr, _Size_type _Count
			);

		static bool _IsAvailable(
			);

		static bool _IsEmpty(
			);

		static void _Clear(
			);

		static _Size_type _Size(
			);

		static _String _Str(
			);

	};

	template <
		typename _CharTy
	>
	struct _Clipboard_traits;

	template <>
	struct _Clipboard_traits<char> :
		_Clipboard_traits_A
	{
	};

	template <>
	struct _Clipboard_traits<wchar_t> :
		_Clipboard_traits_W
	{
	};

	template <
		typename _CharTy
	>
	class _Clipboard {
		typedef _Clipboard							_This;

		typedef _Clipboard_traits<_CharTy>			_Traits;
		typedef typename _Traits::_String			_String;

	public:
		typedef typename _Traits::_Size_type		size_type;
		typedef typename _Traits::_Value_type		value_type;
		typedef typename _Traits::_Pointer			pointer;
		typedef typename _Traits::_Const_pointer	const_pointer;

		_This & assign(
			const_pointer _Ptr
			) {
				return assign(_Ptr, std::char_traits<value_type>::length(_Ptr));
			}

		_This & assign(
			const_pointer _Ptr, size_type _Count
			) {
				_Traits::_Assign(_Ptr, _Count);
				return * this;
			}

		template <
			typename _TraitsTy, typename _AllocatorTy
		>
		_This & assign(
			const std::basic_string<_CharTy, _TraitsTy, _AllocatorTy> & _Str
			) {
				return assign(_Str.c_str(), _Str.size());
			}

		template<
			typename _InputIteratorTy
		>
		_This & assign(
			_InputIteratorTy _First, _InputIteratorTy _Last
			) {
				return assign(_String(_First, _Last));
			}

		_This & assign(
			const_pointer _First, const_pointer _Last
			) {
				return assign(_First, _Last - _First);
			}

		bool empty(
			) const {
				return _Traits::_IsEmpty();
			}

		void clear(
			) const {
				return _Traits::_Clear();
			}

		size_type size(
			) const {
				return _Traits::_Size();
			}

		_String str(
			) const {
				return _Traits::_Str();
			}

		template <
			typename _TraitsTy, typename _AllocatorTy
		>
		_This & operator = (
			const std::basic_string<_CharTy, _TraitsTy, _AllocatorTy> & _Right
			) {
				return assign(_Right);
			}

		_This & operator = (
			value_type _Right
			) {
				return assign(_Right);
			}

		_This & operator = (
			const_pointer _Right
			) {
				return assign(_Right);
			}

	};

	extern _Clipboard<char> clipboard;

	extern _Clipboard<wchar_t> wclipboard;

}

#endif // !CLIPBOARD_H

// ---------------------------------------------------------------------------------
//  End of file
// ---------------------------------------------------------------------------------
