text: /*!
  	@file
  	@author		Albert Semenov
  	@date		08/2010
  */
  
  #include "Precompiled.h"
  #include "HotKeyManager.h"
  #include "CommandManager.h"
  
  MYGUI_SINGLETON_DEFINITION(tools::HotKeyManager);
  
  namespace tools
  {
  
  	HotKeyManager::HotKeyManager() :
  		mSingletonHolder(this)
  	{
  		#define BIND_KEY(name) mKeyNames[#name] = MyGUI::KeyCode::name
  
  		BIND_KEY(None);
  		BIND_KEY(Escape);
  		BIND_KEY(One);
  		BIND_KEY(Two);
  		BIND_KEY(Three);
  		BIND_KEY(Four);
  		BIND_KEY(Five);
  		BIND_KEY(Six);
  		BIND_KEY(Seven);
  		BIND_KEY(Eight);
  		BIND_KEY(Nine);
  		BIND_KEY(Zero);
  		BIND_KEY(Minus);
  		BIND_KEY(Equals);
  		BIND_KEY(Backspace);
  		BIND_KEY(Tab);
  		BIND_KEY(Q);
  		BIND_KEY(W);
  		BIND_KEY(E);
  		BIND_KEY(R);
  		BIND_KEY(T);
  		BIND_KEY(Y);
  		BIND_KEY(U);
  		BIND_KEY(I);
  		BIND_KEY(O);
  		BIND_KEY(P);
  		BIND_KEY(LeftBracket);
  		BIND_KEY(RightBracket);
  		BIND_KEY(Return);
  		BIND_KEY(LeftControl);
  		BIND_KEY(A);
  		BIND_KEY(S);
  		BIND_KEY(D);
  		BIND_KEY(F);
  		BIND_KEY(G);
  		BIND_KEY(H);
  		BIND_KEY(J);
  		BIND_KEY(K);
  		BIND_KEY(L);
  		BIND_KEY(Semicolon);
  		BIND_KEY(Apostrophe);
  		BIND_KEY(Grave);
  		BIND_KEY(LeftShift);
  		BIND_KEY(Backslash);
  		BIND_KEY(Z);
  		BIND_KEY(X);
  		BIND_KEY(C);
  		BIND_KEY(V);
  		BIND_KEY(B);
  		BIND_KEY(N);
  		BIND_KEY(M);
  		BIND_KEY(Comma);
  		BIND_KEY(Period);
  		BIND_KEY(Slash);
  		BIND_KEY(RightShift);
  		BIND_KEY(Multiply);
  		BIND_KEY(LeftAlt);
  		BIND_KEY(Space);
  		BIND_KEY(Capital);
  		BIND_KEY(F1);
  		BIND_KEY(F2);
  		BIND_KEY(F3);
  		BIND_KEY(F4);
  		BIND_KEY(F5);
  		BIND_KEY(F6);
  		BIND_KEY(F7);
  		BIND_KEY(F8);
  		BIND_KEY(F9);
  		BIND_KEY(F10);
  		BIND_KEY(NumLock);
  		BIND_KEY(ScrollLock);
  		BIND_KEY(Numpad7);
  		BIND_KEY(Numpad8);
  		BIND_KEY(Numpad9);
  		BIND_KEY(Subtract);
  		BIND_KEY(Numpad4);
  		BIND_KEY(Numpad5);
  		BIND_KEY(Numpad6);
  		BIND_KEY(Add);
  		BIND_KEY(Numpad1);
  		BIND_KEY(Numpad2);
  		BIND_KEY(Numpad3);
  		BIND_KEY(Numpad0);
  		BIND_KEY(Decimal);
  		BIND_KEY(OEM_102);
  		BIND_KEY(F11);
  		BIND_KEY(F12);
  		BIND_KEY(F13);
  		BIND_KEY(F14);
  		BIND_KEY(F15);
  		BIND_KEY(Kana);
  		BIND_KEY(ABNT_C1);
  		BIND_KEY(Convert);
  		BIND_KEY(NoConvert);
  		BIND_KEY(Yen);
  		BIND_KEY(ABNT_C2);
  		BIND_KEY(NumpadEquals);
  		BIND_KEY(PrevTrack);
  		BIND_KEY(At);
  		BIND_KEY(Colon);
  		BIND_KEY(Underline);
  		BIND_KEY(Kanji);
  		BIND_KEY(Stop);
  		BIND_KEY(AX);
  		BIND_KEY(Unlabeled);
  		BIND_KEY(NextTrack);
  		BIND_KEY(NumpadEnter);
  		BIND_KEY(RightControl);
  		BIND_KEY(Mute);
  		BIND_KEY(Calculator);
  		BIND_KEY(PlayPause);
  		BIND_KEY(MediaStop);
  		BIND_KEY(VolumeDown);
  		BIND_KEY(VolumeUp);
  		BIND_KEY(WebHome);
  		BIND_KEY(NumpadComma);
  		BIND_KEY(Divide);
  		BIND_KEY(SysRq);
  		BIND_KEY(RightAlt);
  		BIND_KEY(Pause);
  		BIND_KEY(Home);
  		BIND_KEY(ArrowUp);
  		BIND_KEY(PageUp);
  		BIND_KEY(ArrowLeft);
  		BIND_KEY(ArrowRight);
  		BIND_KEY(End);
  		BIND_KEY(ArrowDown);
  		BIND_KEY(PageDown);
  		BIND_KEY(Insert);
  		BIND_KEY(Delete);
  		BIND_KEY(LeftWindows);
  		BIND_KEY(RightWindow);
  		BIND_KEY(RightWindows);
  		BIND_KEY(AppMenu);
  		BIND_KEY(Power);
  		BIND_KEY(Sleep);
  		BIND_KEY(Wake);
  		BIND_KEY(WebSearch);
  		BIND_KEY(WebFavorites);
  		BIND_KEY(WebRefresh);
  		BIND_KEY(WebStop);
  		BIND_KEY(WebForward);
  		BIND_KEY(WebBack);
  		BIND_KEY(MyComputer);
  		BIND_KEY(Mail);
  		BIND_KEY(MediaSelect);
  
  		#undef BIND_KEY
  	}
  
  	HotKeyManager::~HotKeyManager()
  	{
  		mKeyNames.clear();
  	}
  
  	void HotKeyManager::initialise()
  	{
  		MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("HotKeys") = MyGUI::newDelegate(this, &HotKeyManager::loadXml);
  	}
  
  	void HotKeyManager::shutdown()
  	{
  		MyGUI::ResourceManager::getInstance().unregisterLoadXmlDelegate("HotKeys");
  	}
  
  	void HotKeyManager::loadXml(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version)
  	{
  		MyGUI::xml::ElementEnumerator node = _node->getElementEnumerator();
  		while (node.next("Command"))
  		{
  			HotKeyCommand command;
  
  			MyGUI::xml::ElementEnumerator nodeCommand = node->getElementEnumerator();
  			while (nodeCommand.next())
  			{
  				if (nodeCommand->getName() == "Name")
  				{
  					command.setCommand(nodeCommand->getContent());
  				}
  				/*else if (nodeCommand->getName() == "Pressed")
  				{
  					command.setPressed(MyGUI::utility::parseValue<bool>(nodeCommand->getContent()));
  				}*/
  				else if (nodeCommand->getName() == "KeyCode")
  				{
  					MapKeys::const_iterator item = mKeyNames.find(nodeCommand->getContent());
  					if (item != mKeyNames.end())
  					{
  						command.setKey((*item).second);
  					}
  					else
  					{
  						// log
  					}
  				}
  				else if (nodeCommand->getName() == "Modifier")
  				{
  					command.setShift(nodeCommand->getContent().find("Shift") != std::string::npos);
  					command.setControl(nodeCommand->getContent().find("Control") != std::string::npos);
  				}
  			}
  
  			addCommand(command);
  		}
  	}
  
  	void HotKeyManager::addCommand(HotKeyCommand& _command)
  	{
  		MapCommand::iterator section = mCommands.find(_command.getKey());
  		if (section == mCommands.end())
  			section = mCommands.insert(std::make_pair(_command.getKey(), VectorCommand())).first;
  
  		(*section).second.push_back(_command);
  	}
  
  	bool HotKeyManager::onKeyEvent(bool _pressed, bool _shift, bool _control, MyGUI::KeyCode _key)
  	{
  		bool result = false;
  
  		MapCommand::const_iterator section = mCommands.find(_key);
  		if (section == mCommands.end())
  			return result;
  
  		const VectorCommand& commands = (*section).second;
  		for (VectorCommand::const_iterator item = commands.begin(); item != commands.end(); ++item)
  		{
  			const HotKeyCommand& command = (*item);
  			if (command.getPressed() == _pressed
  				&& command.getShift() == _shift
  				&& command.getControl() == _control)
  			{
  				if (CommandManager::getInstance().executeCommand(command.getCommand()))
  					result = true;
  			}
  		}
  
  		return result;
  	}
  
  }
  