#include "IngameState.hpp"
#include "Player.hpp"
#include <thread>

IngameState::IngameState(): State(), _player(), _paused(false), _blurSize(0.f), _frameAlpha(0.f)
{

}


Rect Player::getBounds()
{
	Rect rect;
	sf::Vector2f A = _vertices[0].position;
	sf::Vector2f B = _vertices[1].position;
	sf::Vector2f C = _vertices[2].position;
	
	rect.top = std::min({A.y, B.y, C.y});
	rect.bottom = std::max({A.y, B.y, C.y});
	rect.left = std::min({A.x, B.x, C.x});
	rect.right = std::max({A.x, B.x, C.x});
	
	return rect;
}

void IngameState::init()
{
	_background.setTexture(_context->assets->loadTexture("data/background/Background.png"));
	_context->assets->loadTexture("data/background/Background.png").setRepeated(true);

	_player.setContext(_context);
	_player.setTexture(_context->assets->loadTexture("data/triangle/Texture.png"));
	_player.setPosition(400.f, 400.f);
	
	_foreground.create("data/background/Foreground.png", "data/background/75pxjitter03.png");
	_context->foreground = &_foreground;
	
	_pauseFrame.setFillColor(sf::Color(0, 0, 0, 155));
	_pauseFrame.setPosition(0, 0);
	
	/*_unshadowShader.loadFromFile("assets/unshadowShader.frag", sf::Shader::Fragment);
    _lightOverShapeShader.loadFromFile("assets/lightOverShapeShader.frag", sf::Shader::Fragment);
    _normalsShader.loadFromFile("assets/normalsShader.frag", sf::Shader::Fragment);
	_penumbraTexture.loadFromFile("data/light/penumbraTexture.png");
	_penumbraTexture.setSmooth(true);*/
	
	/*_light = std::make_shared<ltbl::LightPointEmission>();
	_light->_emissionSprite.setOrigin(330.f, 871.f);
	_light->_emissionSprite.setPosition(0.f, 0.f);
	_light->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/texture.png"));
	_light->_emissionSprite.setColor(sf::Color::White);
	_light->_localCastCenter = sf::Vector2f(0.0f, 0.0f); // This is where the shadows emanate from relative to the sprite*/
	
	_blurV.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-v.frag");
	_blurH.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-h.frag");
	
	_marioSound.setBuffer(_context->assets->loadSound("data/audio/Mario.ogg"));
	_wasted.setTexture(_context->assets->loadTexture("data/background/Wasted.png"));
	
	// Global window is not initialized yet in this method. If you need _context->window->getSize(), go to refresh() instead.
	
	_status = State::Ongoing;
}

void IngameState::refresh()
{
	sf::Vector2u res = _context->window->getSize();
	_background.setTextureRect(sf::IntRect(0, 0, _context->window->getSize().x, _context->window->getSize().y));
	_camera.setSize(static_cast<sf::Vector2f>(_context->window->getSize()));
	_camera.setTwilightViewport(_context->window->getSize().x / 2.f - 240.f/* * (bool) _czyWOgóleTwilightViewportMaByć*/, _context->window->getSize().y / 2.f - 240.f);
	_camera.setCenter(_player.getPosition());
	_foreground.setResolution(res);
	
	_pauseFrame.setSize((sf::Vector2f)res);
	
	_wasted.setScale(_context->window->getSize().x / 1920.f,  _context->window->getSize().y / 1080.f);
	_wasted.setPosition(0, _context->window->getSize().y);
	
	_backgroundH.create(_context->window->getSize().x, _context->window->getSize().y);
	_backgroundV.create(_context->window->getSize().x, _context->window->getSize().y);
	
	//_lightSystem.create(sf::FloatRect{{0.f, 0.f}, {0.f, 0.f}}, {1920, 1080}, _penumbraTexture, _unshadowShader, _lightOverShapeShader, _normalsShader);
	//_lightSystem.normalsEnabled(true);
	//_lightSystem.addLight(_light);
}

void IngameState::coreThink(const sf::Event& event)
{
	if(event.type == sf::Event::Closed or (event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::Escape))
		_status = State::Menu;
	if(event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::P and !_player.isDead())
		_paused = !_paused;
	_player.think(event);
}
void IngameState::coreInput()
{
	if(_paused)
		return;

	_player.think();
}
void IngameState::coreUpdate(sf::Time delta)
{
	if(_player.isDead())
	{
		if(_blurSize < 4.f)
			_blurSize += delta.asSeconds();
			
		/** 
		 * This will dynamically fade the grey pause foreground from 0 to 100 alpha.
		 */
		if(_frameAlpha < 100.f)
			_frameAlpha += (delta.asSeconds() * 25.f);
		sf::Color color = _pauseFrame.getFillColor();
		color.a = (int)_frameAlpha;
		_pauseFrame.setFillColor(color);
		
		_blurH.setParameter("blurSize", _blurSize / _context->window->getSize().x);
		_blurV.setParameter("blurSize", _blurSize / _context->window->getSize().y);
		
		if(_wasted.getPosition().y > 0.f)
			_wasted.move(0.f, -250.f * delta.asSeconds());
		else if(_wasted.getPosition().y < 0.f)
			_wasted.setPosition(0.f, 0.f);
	}

	if(_paused)
		return;
		
	if(sf::Joystick::isConnected(0))
		_context->window->lockMouse();

	const sf::Vector2f pos = _player.getPosition();
	_player.update(delta);
	_camera.move(_player.getPosition() - pos);
	//_light->_emissionSprite.setPosition(_player.getPosition());
	//_light->_emissionSprite.setRotation(_player.getRotation());
	_foreground.setPosition(_camera.getCenter() - _camera.getSize() / 2.f);
	
	if(_player.checkCollision(_foreground)) /// True if the target died.
	{
		_paused = true;
		_marioSound.play();
	}
}
void IngameState::coreRender(const bool shaders)
{
	if(_player.isDead())
	{
	//	_blurH.setParameter("RTScene", backgroundH.getTexture());
	//	_blurV.setParameter("RTBlurH", backgroundV.getTexture());
		
		_background.setTexture(_context->assets->loadTexture("data/background/Background.png"));
		_backgroundH.draw(_background);
		_backgroundH.setView(*_camera.getView());
		_backgroundH.draw(_foreground);
		_backgroundH.draw(_player);
		sf::Sprite sprite(_backgroundH.getTexture());
		sprite.setScale(1.f, -1.f);
		sprite.setOrigin(0, _context->window->getSize().y);
		sprite.setPosition(0.f, 0.f);
		_backgroundV.draw(sprite, &_blurH);
		sf::Sprite sprite2(_backgroundV.getTexture());
		sprite2.setScale(1.f, -1.f);
		sprite2.setOrigin(0, _context->window->getSize().y);
		sprite2.setPosition(0.f, 0.f);
		_context->window->draw(sprite2, &_blurH);
		_context->window->draw(_pauseFrame);
		_context->window->draw(_wasted);
	}
	else
	{
	
	//_lightSystem.normalsTargetClear();
	_background.setTexture(_context->assets->loadTexture("data/background/Background.png"));
	_context->window->draw(_background);//, &_normalBackground);
	//_background.setTexture(_context->assets->loadTexture("data/background/normal.JPG"));
	//_lightSystem.normalsTargetDraw(_background);
	//_lightSystem.normalsTargetDraw(_foreground);
	_context->window->setView(_camera.getView());
	_context->window->draw(_foreground);
	//_context->window->draw(_foreground);
	_context->window->draw(_player);
	//_lightSystem.normalsTargetDisplay();
	//_lightSystem.render(*_camera.getView(), _unshadowShader, _lightOverShapeShader, _normalsShader);
	//sf::Sprite sprite(_lightSystem.getLightingTexture());
	//sf::RenderStates lightRenderStates;
    //lightRenderStates.blendMode = sf::BlendMultiply;
	//_context->window->draw(sprite, lightRenderStates);
	_context->window->setView();
	if(_paused)
		_context->window->draw(_pauseFrame);
	}
}