//-----------------------------------------------------------------------------
//
//	CommandClasses.h
//
//	Singleton holding methods to create each command class object
//
//	Copyright (c) 2010 Mal Lansell <openzwave@lansell.org>
//
//	SOFTWARE NOTICE AND LICENSE
//
//	This file is part of OpenZWave.
//
//	OpenZWave is free software: you can redistribute it and/or modify
//	it under the terms of the GNU Lesser General Public License as published
//	by the Free Software Foundation, either version 3 of the License,
//	or (at your option) any later version.
//
//	OpenZWave is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public License
//	along with OpenZWave.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------

#ifndef _CommandClasses_H
#define _CommandClasses_H

#include <string>
#include <map>
#include <list>
#include "Defs.h"

namespace OpenZWave
{
	namespace Internal
	{
		namespace CC
		{
			class CommandClass;

			/** \brief Manages a map of command classes supported by a specific Z-Wave node.
			 * \ingroup CommandClass
			 */
			class CommandClasses
			{
				public:
					typedef CommandClass* (*pfnCreateCommandClass_t)(uint32 const _homeId, uint8 const _nodeId);

					static void RegisterCommandClasses();
					static CommandClass* CreateCommandClass(uint8 const _commandClassId, uint32 const _homeId, uint8 const _nodeId);

					static bool IsSupported(uint8 const _commandClassId);
					static string GetName(uint8 const _commandClassId);
					static list<uint8> GetAdvertisedCommandClasses();
				private:
					CommandClasses();
					CommandClasses(CommandClasses const&);					// prevent copy
					CommandClasses& operator =(CommandClasses const&);		// prevent assignment

					static CommandClasses& Get()
					{
						static CommandClasses instance;
						return instance;
					}

					void Register(uint8 const _commandClassId, string const& _commandClassName, pfnCreateCommandClass_t _create, bool advertised = false);
					void ParseCommandClassOption(string const& _optionStr, bool const _include);
					uint8 GetCommandClassId(string const& _name);

					pfnCreateCommandClass_t m_commandClassCreators[256];
					map<string, uint8> m_namesToIDs;
					/* a list of CommandClasses that are advertised on the controllers NIF packet and can be controlled
					 * via other Nodes
					 */
					list<uint8> m_advertisedCommandClasses;

					// m_supportedCommandClasses uses single bits to mark whether OpenZWave supports a command class
					// Checking this is not the same as looking for non-NULL entried in m_commandClassCreators, since
					// this may be modified by the program options --Include and --Ingnore to filter out support
					// for unwanted command classes.
					uint32 m_supportedCommandClasses[8];
			};
		} // namespace CC
	} // namespace Internal
} // namespace OpenZWave

#endif
