package studio.junk.jam.coloritum.entities.systems;

import javax.swing.JOptionPane;

import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.ashley.systems.IteratingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Manifold;

import studio.junk.jam.coloritum.ColoritumGame;
import studio.junk.jam.coloritum.GameState;
import studio.junk.jam.coloritum.entities.Families;
import studio.junk.jam.coloritum.entities.Pigment;
import studio.junk.jam.coloritum.entities.components.Collision;
import studio.junk.jam.coloritum.entities.components.MirrorComponent;
import studio.junk.jam.coloritum.entities.components.PigmentComponent;
import studio.junk.jam.coloritum.screen.LoadGame;

public class LightBulbController extends IteratingSystem {
	public static final Family family = Families.lightBulb;

	public static final ContactListener contactListener = new ContactListener() {

		protected Entity[] collide(Entity entityA, Entity entityB) {

			if (family.matches(entityA)) {
				return new Entity[] { entityA, entityB };
			} else if (family.matches(entityB)) {
				return new Entity[] { entityB, entityA };
			} else {
				return null;
			}
		}

		@Override
		public void beginContact(Contact contact) {

			Entity entityA = (Entity) contact.getFixtureA().getBody().getUserData();
			Entity entityB = (Entity) contact.getFixtureB().getBody().getUserData();

			Entity[] entities = collide(entityA, entityB);

			if (entities != null) {

				if (family.matches(entities[1])) {

					Collision collision0 = Collision.mapper.get(entities[0]);
					Vector2 velocity0 = collision0.body.getLinearVelocity();

					Collision collision1 = Collision.mapper.get(entities[1]);
					Vector2 velocity1 = collision1.body.getLinearVelocity();

					Pigment pigment1 = PigmentComponent.mapper.get(entities[0]).pigment;
					Pigment pigment2 = PigmentComponent.mapper.get(entities[1]).pigment;

					Pigment newPigment = pigment1.merge(pigment2);

					PigmentComponent.setPigment(entities[0], newPigment);
					PigmentComponent.setPigment(entities[1], newPigment);

					if ((velocity0.x * velocity1.x) < -0.1) {
						collision0.body.setLinearVelocity(new Vector2(0, velocity0.x));
						collision1.body.setLinearVelocity(new Vector2(0, velocity1.x));

					} else if ((velocity0.y * velocity1.y) < -0.1) {
						collision0.body.setLinearVelocity(new Vector2(velocity0.y, 0));
						collision1.body.setLinearVelocity(new Vector2(velocity1.y, 0));

					}

				} else if (Families.mirror.matches(entities[1])) {

					final Collision collision0 = Collision.mapper.get(entities[0]);
					final Collision collision1 = Collision.mapper.get(entities[1]);

					Vector2 velocity0 = collision0.body.getLinearVelocity();

					MirrorComponent mirrorComponent = MirrorComponent.mapper.get(entities[1]);

					final int signX;
					final int signY;

					if (mirrorComponent.orientation == MirrorComponent.Orientation.NorthEast) {

						if (velocity0.y == 0) {
							if (velocity0.x > 0) {
								signY = -1;
								signX = 0;
							} else {
								signY = 1;
								signX = 0;
							}
						} else if (velocity0.y < 0) {
							signX = 1;
							signY = 0;
						} else {
							signX = -1;
							signY = 0;
						}
					}

					else {

						if (velocity0.y == 0) {
							if (velocity0.x > 0) {
								signY = 1;
								signX = 0;
							} else {
								signY = -1;
								signX = 0;
							}
						} else if (velocity0.y < 0) {
							signX = -1;
							signY = 0;
						} else {
							signX = 1;
							signY = 0;
						}
					}

					final Vector2 pos = collision1.body.getWorldCenter().cpy().add(signX / 10, signY / 10);

					Gdx.app.postRunnable(new Runnable() {

						@Override
						public void run() {
							collision0.body.setLinearVelocity(
									new Vector2(signX * GameState.LIGHT_BULB_VEL, signY * GameState.LIGHT_BULB_VEL));

							collision0.body.setTransform(pos, 0);
						}
					});

				} else if (Families.obstacle.matches(entities[1])) {
					GameState.state.rmEntity(entities[0]);
					// TODO Add effect

				} else if (Families.lightSource.matches(entities[1])) {
					GameState.state.rmEntity(entities[0]);

				} else if (Families.drain.matches(entities[1])) {

					PigmentComponent pigment1 = PigmentComponent.mapper.get(entities[0]);
					PigmentComponent pigment2 = PigmentComponent.mapper.get(entities[1]);

					if (pigment1.pigment == pigment2.pigment) {
						JOptionPane.showMessageDialog(null, "Game finished!");
						ColoritumGame.game.setScreen(new LoadGame());
					}
				}
			}
		}

		@Override
		public void endContact(Contact contact) {
		}

		@Override
		public void preSolve(Contact contact, Manifold oldManifold) {
		}

		@Override
		public void postSolve(Contact contact, ContactImpulse impulse) {
		}
	};

	public LightBulbController(int priority) {
		super(family, priority);
	}

	public LightBulbController() {
		super(family);
	}

	@Override
	protected void processEntity(Entity entity, float deltaTime) {
		Vector2 pos = Collision.mapper.get(entity).body.getWorldCenter();

		if (pos.x < 0 || pos.y < 0 || pos.x > GameState.WORLD_WIDTH_M || pos.y > GameState.WORLD_HEIGHT_M)
			GameState.state.rmEntity(entity);
	}
}
