#include <osg/Notify>
#include <osg/ImageStream>
#include <osg/MatrixTransform>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile>

class SubImage : public osg::ImageStream
{
public:

	SubImage(osg::Image* parent, osg::Vec2 position, osg::Vec2 size) :
	  _parent(parent),
		  _position(position),
		  _size(size),
		  _modifCount(0)
	  {
		  if (_parent)
		  {
			  setImage(_size.x(), _size.y(), 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, _parent->data(_position.x(), _position.y()), NO_DELETE);
			  setOrigin(osg::Image::BOTTOM_LEFT);
		  }
	  }

	  bool requiresUpdateCall() const { return true; }

	  void update(osg::NodeVisitor*)
	  {
		  if (_parent && _parent->getModifiedCount() != _modifCount)
		  {
			  setImage(_size.x(), _size.y(), 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, _parent->data(_position.x(), _position.y()), NO_DELETE);
			  _modifCount = _parent->getModifiedCount();
		  }
	  }

private:

	osg::ref_ptr<osg::Image> _parent;
	osg::Vec2 _position, _size;
	unsigned int _modifCount;
};

/*
**
*/

int	main(int ac, char **av)
{
	osg::setNotifyLevel(osg::NOTICE);

	osg::ArgumentParser	argumentParser(&ac, av);
	std::string			fileName = "../../media/outv.mp4";
	bool				fullscreen = false;

	argumentParser.read("-file", fileName);
	fullscreen = argumentParser.read("-fullscreen");

	osgViewer::CompositeViewer	viewer;
	osg::Image					*image = osgDB::readImageFile(fileName + ".ffmpeg");

	if (image)
	{
		static_cast<osg::ImageStream *>(image)->play();
	}

	for (int i = 0; i < 4; ++i)
	{
			osgViewer::View			*view = new osgViewer::View();
			osg::MatrixTransform	*mt = new osg::MatrixTransform();
			SubImage				*subImage = new SubImage(image, osg::Vec2(0, 1633 * i), osg::Vec2(768, 1633));

			// Add the texture
			{
				osg::Geode	*geode = new osg::Geode();

				geode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(0, -200, -150), osg::Vec3(0, 400, 0), osg::Vec3(0, 0, 300)));
				{
					osg::Texture2D	*texture = new osg::Texture2D();

					texture->setResizeNonPowerOfTwoHint(false);
					texture->setImage(subImage);
					geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
				}

				geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
				mt->addChild(geode);
			}

			mt->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(-90.0), 0, 0, 1));

			if (fullscreen == false)
			{
				view->setUpViewInWindow(i * 470 + 10, 10, 450, 800);
			}
			else
			{
				view->setUpViewOnSingleScreen(i);
			}
			if (i == 0)
			{
				view->addEventHandler(new osgViewer::StatsHandler());
				view->addEventHandler(new osgViewer::ThreadingHandler());
			}
			view->setSceneData(mt);
			view->getCamera()->setProjectionMatrixAsOrtho2D(-200, 200, -150, 150);
			viewer.addView(view);
	}

	return viewer.run();
}
