/** The Ogre renderQueueStarted implementation
  *
  * The more used parameter is the queueGroupId. 90 is for the 
  * object to be highlighted, 91 is its outline.
  *
  * \param queueGroupId The queue group identifier (90 and 91 are treated)
  * \param invocation Unused Ogre provided parameter
  * \param skipThisInvocation Unused Ogre provided parameter
  *
  */
void RainbruRPG::Core::HighlightQueueListener::
renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, 
		   bool& skipThisInvocation)

{
  //RenderQueue containing the object to be highlighted
  if (queueGroupId == 90){
    Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton()
      .getRenderSystem();
		
    rendersys->clearFrameBuffer(Ogre::FBT_STENCIL);
    rendersys->setStencilCheckEnabled(true);
    rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS,1,0xFFFFFFFF,
				      Ogre::SOP_KEEP,Ogre::SOP_KEEP,
				      Ogre::SOP_REPLACE,false);      
  }
  
  //RenderQueue containing the outline
  if (queueGroupId == 91){
    Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton()
      .getRenderSystem();
    
    rendersys->setStencilCheckEnabled(true);
    rendersys->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL,1,0xFFFFFFFF,
				      Ogre::SOP_KEEP,Ogre::SOP_KEEP,
				      Ogre::SOP_KEEP,false);      
    }
}
/** The Ogre renderQueueStarted implementation
  *
  * The more used parameter is the queueGroupId. 90 is for the 
  * object to be highlighted, 91 is its outline.
  *
  * \param queueGroupId The queue group identifier (90 and 91 are treated)
  * \param invocation Unused Ogre provided parameter
  * \param repeatThisInvocation Unused Ogre provided parameter
  *
  */
void RainbruRPG::Core::HighlightQueueListener::
renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, 
		 bool& repeatThisInvocation)
{
  if (( queueGroupId == 90 ) || ( queueGroupId == 91 )){
    Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton()
      .getRenderSystem();

    rendersys->setStencilCheckEnabled(false);
    rendersys->setStencilBufferParams();
  }
}
	void CustomRenderSequenceListener::renderQueueStarted(Ogre::uint8 queueGroupId, 
		const Ogre::String& invocation, bool& skipThisInvocation) 
	{ 
		typedef std::map<int, StencilConfig>::iterator StencilConfigIterator;
		Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 

		StencilConfigIterator it = iteration->stencilConfigs.find(queueGroupId);

		if(it != iteration->stencilConfigs.end())
		{
			if(it->second.stencil)
			{
				rendersys->setStencilCheckEnabled(true); 
				rendersys->setStencilBufferParams(
					static_cast<Ogre::CompareFunction>(it->second.compare), 
					static_cast<Ogre::uint32>(it->second.mask),
					static_cast<Ogre::uint32>(it->second.ref),
					static_cast<Ogre::StencilOperation>(it->second.failOp),
					static_cast<Ogre::StencilOperation>(it->second.depthFailOp),
					static_cast<Ogre::StencilOperation>(it->second.passOp),
					false); 
			}
			else
			{
				//rendersys->setStencilCheckEnabled(false); 
			}
		}
		
		/*if(queueGroupId == 75)
		{
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 

			if(pass.first == 0)
			{
				rendersys->setStencilCheckEnabled(true); 
				rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS,
					1, MASK_FULL, 
					Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false);       
			}
			else if(pass.first == 1)
			{
				rendersys->setStencilCheckEnabled(true); 
				rendersys->setStencilBufferParams(Ogre::CMPF_EQUAL,
					pass.second + 1, MASK_FULL, 
					Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_INCREMENT,false);       
			}
			//else
			//{
			//	rendersys->setStencilCheckEnabled(false); 
			//}
		}
		else if(queueGroupId == 76)
		{
			Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 

			if(pass.first == 0)
			{
				rendersys->setStencilCheckEnabled(true); 
				rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS,
					51, MASK_FULL, 
					Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false);       
			}
			else if(pass.first == 2)
			{
				rendersys->setStencilCheckEnabled(true); 
				rendersys->setStencilBufferParams(Ogre::CMPF_EQUAL,
					51 + pass.second, MASK_FULL, 
					Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_INCREMENT,false);       
			}
			//else
			//{
			//	rendersys->setStencilCheckEnabled(false); 
			//}
		}*/
	} 
	void OgreSubsystem::renderFrame()
	{
		Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); 
		Ogre::WindowEventUtilities::messagePump();

		if (!mCustomRenderSequenceEnabled)
		{
			mRoot->renderOneFrame();
		}
		else
		{
			// clear framebuffer
			rendersys->clearFrameBuffer(Ogre::FBT_STENCIL | Ogre::FBT_COLOUR | Ogre::FBT_DEPTH,
				mViewport->getBackgroundColour()); 

			// pass index
			int pass = 0;

			std::list<CustomRenderIteration>::iterator it = mRenderSequence->getIterator();

			while (it != mRenderSequence->getEnd())
			{
				// signal after each iteration
				getSignal("CustomRenderSequenceIteration")->send(pass);

				// update iteration info with listener
				mSequenceListener->iteration = &(*it);
				StencilConfig& cfg = mSequenceListener->iteration->stencilConfigs[-1];

				if(cfg.stencil)
				{
					// set initial stencil info
					rendersys->setStencilCheckEnabled(true); 
					rendersys->setStencilBufferParams(
						static_cast<Ogre::CompareFunction>(cfg.compare), 
						static_cast<Ogre::uint32>(cfg.mask), 
						static_cast<Ogre::uint32>(cfg.ref), 
						static_cast<Ogre::StencilOperation>(cfg.failOp), 
						static_cast<Ogre::StencilOperation>(cfg.depthFailOp), 
						static_cast<Ogre::StencilOperation>(cfg.passOp), 
						false);       
				}

				if(it->clearDepth)
					rendersys->clearFrameBuffer(Ogre::FBT_DEPTH);
				
				// force a transformation update and render
				getActiveCamera()->getCamera()->_notifyMoved();
				getActiveCamera()->getCamera()->_renderScene(mViewport, true);
				
				++pass;
				++it;
			}

			// final signal
			getSignal("CustomRenderSequenceIteration")->send(pass);

			// finally swap the buffers
			mWindow->swapBuffers();

		}
	}