package com.custardgames.hotel.entities.ecs.systems;

import java.util.EventListener;

import net.dermetfan.gdx.graphics.g2d.AnimatedBox2DSprite;
import net.dermetfan.gdx.graphics.g2d.AnimatedSprite;
import net.dermetfan.gdx.graphics.g2d.Box2DSprite;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.physics.box2d.Body;
import com.custardgames.hotel.entities.ecs.components.Box2dBodyComponent;
import com.custardgames.hotel.entities.ecs.components.Box2dSpriteComponent;
import com.custardgames.hotel.entities.ecs.components.CharacterDataComponent;
import com.custardgames.hotel.entities.ecs.components.CharacterInputComponent;
import com.custardgames.hotel.events.BeginContactEvent;
import com.custardgames.hotel.events.PlayerDiedEvent;
import com.custardgames.hotel.managers.EventManager;

public class CharacterMovementSystem extends EntityProcessingSystem implements EventListener
{
	@Mapper
	ComponentMapper<Box2dBodyComponent> bodyComponents;
	@Mapper
	ComponentMapper<CharacterInputComponent> characterInputComponents;
	@Mapper
	ComponentMapper<CharacterDataComponent> characterDataComponents;
	@Mapper
	ComponentMapper<Box2dSpriteComponent> spriteComponents;

	private Box2DSprite leftAnimation;
	private Box2DSprite rightAnimation;
	private Box2DSprite upAnimation;
	private Box2DSprite downAnimation;

	@SuppressWarnings("unchecked")
	public CharacterMovementSystem(AssetManager assetManager)
	{
		super(Aspect.getAspectForAll(Box2dBodyComponent.class, CharacterInputComponent.class, CharacterDataComponent.class, Box2dSpriteComponent.class));
		EventManager.get_instance().register(BeginContactEvent.class, this);

		{
			TextureRegion frame1 = new TextureRegion((Texture) assetManager.get("images/player.png"), 0, 0, 32, 64);
			TextureRegion frame2 = new TextureRegion((Texture) assetManager.get("images/player.png"), 32, 0, 32, 64);
			TextureRegion frame3 = new TextureRegion((Texture) assetManager.get("images/player.png"), 64, 0, 32, 64);
			TextureRegion frame4 = new TextureRegion((Texture) assetManager.get("images/player.png"), 96, 0, 32, 64);
			TextureRegion frame5 = new TextureRegion((Texture) assetManager.get("images/player.png"), 128, 0, 32, 64);
			TextureRegion frame6 = new TextureRegion((Texture) assetManager.get("images/player.png"), 160, 0, 32, 64);
			Animation animation = new Animation(1 / 20f, frame1, frame2, frame3, frame4, frame5, frame6);
			animation.setPlayMode(Animation.PlayMode.LOOP);
			AnimatedSprite animatedSprite = new AnimatedSprite(animation);
			AnimatedBox2DSprite animatedBox2DSprite = new AnimatedBox2DSprite(animatedSprite);
			downAnimation = animatedBox2DSprite;
		}
		{
			TextureRegion frame1 = new TextureRegion((Texture) assetManager.get("images/player.png"), 0, 64, 32, 64);
			TextureRegion frame2 = new TextureRegion((Texture) assetManager.get("images/player.png"), 32, 64, 32, 64);
			TextureRegion frame3 = new TextureRegion((Texture) assetManager.get("images/player.png"), 64, 64, 32, 64);
			TextureRegion frame4 = new TextureRegion((Texture) assetManager.get("images/player.png"), 96, 64, 32, 64);
			TextureRegion frame5 = new TextureRegion((Texture) assetManager.get("images/player.png"), 128, 64, 32, 64);
			TextureRegion frame6 = new TextureRegion((Texture) assetManager.get("images/player.png"), 160, 64, 32, 64);
			Animation animation = new Animation(1 / 20f, frame1, frame2, frame3, frame4, frame5, frame6);
			animation.setPlayMode(Animation.PlayMode.LOOP);
			AnimatedSprite animatedSprite = new AnimatedSprite(animation);
			AnimatedBox2DSprite animatedBox2DSprite = new AnimatedBox2DSprite(animatedSprite);
			leftAnimation = animatedBox2DSprite;
		}
		{
			TextureRegion frame1 = new TextureRegion((Texture) assetManager.get("images/player.png"), 0, 128, 32, 64);
			TextureRegion frame2 = new TextureRegion((Texture) assetManager.get("images/player.png"), 32, 128, 32, 64);
			TextureRegion frame3 = new TextureRegion((Texture) assetManager.get("images/player.png"), 64, 128, 32, 64);
			TextureRegion frame4 = new TextureRegion((Texture) assetManager.get("images/player.png"), 96, 128, 32, 64);
			TextureRegion frame5 = new TextureRegion((Texture) assetManager.get("images/player.png"), 128, 128, 32, 64);
			TextureRegion frame6 = new TextureRegion((Texture) assetManager.get("images/player.png"), 160, 128, 32, 64);
			Animation animation = new Animation(1 / 20f, frame1, frame2, frame3, frame4, frame5, frame6);
			animation.setPlayMode(Animation.PlayMode.LOOP);
			AnimatedSprite animatedSprite = new AnimatedSprite(animation);
			AnimatedBox2DSprite animatedBox2DSprite = new AnimatedBox2DSprite(animatedSprite);
			upAnimation = animatedBox2DSprite;
		}
		{
			TextureRegion frame1 = new TextureRegion((Texture) assetManager.get("images/player.png"), 0, 192, 32, 64);
			TextureRegion frame2 = new TextureRegion((Texture) assetManager.get("images/player.png"), 32, 192, 32, 64);
			TextureRegion frame3 = new TextureRegion((Texture) assetManager.get("images/player.png"), 64, 192, 32, 64);
			TextureRegion frame4 = new TextureRegion((Texture) assetManager.get("images/player.png"), 96, 192, 32, 64);
			TextureRegion frame5 = new TextureRegion((Texture) assetManager.get("images/player.png"), 128, 192, 32, 64);
			TextureRegion frame6 = new TextureRegion((Texture) assetManager.get("images/player.png"), 160, 192, 32, 64);
			Animation animation = new Animation(1 / 20f, frame1, frame2, frame3, frame4, frame5, frame6);
			animation.setPlayMode(Animation.PlayMode.LOOP);
			AnimatedSprite animatedSprite = new AnimatedSprite(animation);
			AnimatedBox2DSprite animatedBox2DSprite = new AnimatedBox2DSprite(animatedSprite);
			rightAnimation = animatedBox2DSprite;
		}
	}

	@Override
	protected void process(Entity e)
	{
		Body body = bodyComponents.get(e).getBody();
		CharacterInputComponent characterInput = characterInputComponents.get(e);
		Box2dSpriteComponent spriteComponent = spriteComponents.get(e);

		float maxSpeed = 10;

		if (!characterInput.isReset())
		{
			spriteComponent.setSprite(downAnimation);
			characterInput.setReset(true);
		}
		
		if (characterInput.isUp())
		{
			body.setLinearVelocity(body.getLinearVelocity().x, maxSpeed);
			spriteComponent.setSprite(upAnimation);
		}
		else if (characterInput.isDown())
		{
			body.setLinearVelocity(body.getLinearVelocity().x, -maxSpeed);
			spriteComponent.setSprite(downAnimation);
		}

		if (characterInput.isLeft())
		{
			body.setLinearVelocity(-maxSpeed, body.getLinearVelocity().y);
			spriteComponent.setSprite(leftAnimation);
		}
		else if (characterInput.isRight())
		{
			body.setLinearVelocity(maxSpeed, body.getLinearVelocity().y);
			spriteComponent.setSprite(rightAnimation);
		}

	}

	public void handleBeginContactEvent(BeginContactEvent e)
	{
		ImmutableBag<Entity> entities = getActives();
		for (int x = 0; x < entities.size(); x++)
		{
			Body body = bodyComponents.get(entities.get(x)).getBody();
			if (e.getFa().getBody() == body || e.getFb().getBody() == body)
			{
				if (e.getFa().getBody() == body)
				{
					if (e.getFb().getBody().getUserData().equals("spikes"))
					{
						EventManager.get_instance().broadcast(new PlayerDiedEvent());
					}
				}
				else
				{
					if (e.getFa().getBody().getUserData().equals("spikes"))
					{
						EventManager.get_instance().broadcast(new PlayerDiedEvent());
					}
				}
			}
		}
	}

}
