/*
 Copyright (C) 2013 Erik Ogenvik

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef EMBERTERRAIN_H_
#define EMBERTERRAIN_H_

#include "components/ogre/TerrainPageDataProvider.h"

#include <OgreTerrain.h>

#include <sigc++/signal.h>
#include <functional>

namespace Ember
{
namespace OgreView
{
namespace Terrain
{

/**
 * @brief Mainly used to override the default behaviour of Ogre::Terrain.
 *
 * This to better fit the way we handle materials (since we don't use the default materials
 * as generated by the Ogre::Terrain classes).
 */
class EmberTerrain: public Ogre::Terrain
{
public:

	/**
	 * @brief Ctor.
	 * @param unloader An unloader function, called upon destruction.
	 * @param sm
	 */
	EmberTerrain(std::function<void()>& unloader, Ogre::SceneManager* sm, sigc::signal<void, Ogre::TRect<Ogre::Real>>& terrainAreaUpdatedSignal, sigc::signal<void, const Ogre::TRect<Ogre::Real>>& terrainShownSignal);
	virtual ~EmberTerrain();

	/**
	 * Specifies the index of this page in the paging component.
	 * @param index The paging specific index.
	 */
	void setIndex(const IPageDataProvider::OgreIndex& index);

	/**
	 * @brief Gets the index of the page in the paging component.
	 * @return The index of the page.
	 */
	const IPageDataProvider::OgreIndex& getIndex() const;

	void handleResponse(const Ogre::WorkQueue::Response* res, const Ogre::WorkQueue* srcQ);

	/**
	 * @brief Regenerates the material used by the page.
	 */
	void regenerateMaterial();


protected:

	/**
	 * @brief An unloader function, called upon destruction.
	 */
	std::function<void()> mUnloader;

	/**
	 * @brief The index of the page in the paging component.
	 */
	IPageDataProvider::OgreIndex mIndex;

	/**
	 * @brief Signal emitted when an area of the terrain has been updated.
	 * The argument is the area (in world coordinates) that was updated.
	 */
	sigc::signal<void, Ogre::TRect<Ogre::Real>> mTerrainAreaUpdatedSignal;

	/**
	 * @brief Signal emitted when a page has been shown for the first time.
	 * The argument is the area (in world coordinates) that was shown.
	 */
	sigc::signal<void, const Ogre::TRect<Ogre::Real>> mTerrainShownSignal;


};

}
}
}
#endif /* EMBERTERRAIN_H_ */
