package net.alcuria.umbracraft.engine.manager;

import net.alcuria.umbracraft.Config;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.editor.Drawables;
import net.alcuria.umbracraft.engine.entities.BaseEntity;
import net.alcuria.umbracraft.engine.events.Event;
import net.alcuria.umbracraft.engine.events.EventListener;
import net.alcuria.umbracraft.engine.events.TintScreenEvent;
import net.alcuria.umbracraft.engine.screens.UmbraScreen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Action;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.utils.Disposable;

/** Handles screen overlays, which are rendered over all {@link UmbraScreen}
 * screens. Listens for {@link TintScreenEvent} events to adjust screen tint.
 * @author Andrew Keturi */
public class OverlayManager implements EventListener, BaseEntity, Disposable {

	private final Image overlay = new Image(Drawables.skin("ui/black"));
	private final Stage stage = new Stage(Game.view().getViewport());

	{
		overlay.setWidth(Config.viewWidth);
		overlay.setHeight(Config.viewHeight);
		overlay.getColor().a = 0;
		stage.addActor(overlay);
		Game.publisher().subscribe(this);
	}

	@Override
	public void dispose() {
		Game.publisher().unsubscribe(this);
	}

	private Action getAction(TintScreenEvent event) {
		return event.color != null ? Actions.color(event.color, event.duration) : Actions.alpha(event.target, event.duration);
	}

	@Override
	public void onEvent(Event event) {
		if (event instanceof TintScreenEvent) {
			final TintScreenEvent tint = (TintScreenEvent) event;
			overlay.addAction(Actions.sequence(getAction(tint), Actions.run(new Runnable() {
				@Override
				public void run() {
					if (tint.listener != null) {
						tint.listener.invoke();
					}
				}
			})));
		}
	}

	@Override
	public void render() {
		stage.draw();
	}

	@Override
	public void update() {
		stage.act(Gdx.graphics.getDeltaTime());
	}
}

package net.alcuria.umbracraft.engine.manager;

import net.alcuria.umbracraft.Config;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.editor.Drawables;
import net.alcuria.umbracraft.engine.entities.BaseEntity;
import net.alcuria.umbracraft.engine.events.Event;
import net.alcuria.umbracraft.engine.events.EventListener;
import net.alcuria.umbracraft.engine.events.TintScreenEvent;
import net.alcuria.umbracraft.engine.screens.UmbraScreen;
import net.alcuria.umbracraft.listeners.Listener;
import net.alcuria.umbracraft.util.O.L;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.actions.ColorAction;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.utils.Disposable;

/** Handles screen overlays, which are rendered over all {@link UmbraScreen}
 * screens. Listens for {@link TintScreenEvent} events to adjust screen tint.
 * @author Andrew Keturi */
public class OverlayManager implements EventListener, BaseEntity, Disposable {

	private final ColorAction colorAction = new ColorAction();
	private final Image overlay = new Image(Drawables.skin("ui/black"));
	private final Stage stage = new Stage(Game.view().getViewport());
	private boolean startedColorAction = false;
	private Listener tintListener;
	{
		overlay.setWidth(Config.viewWidth);
		overlay.setHeight(Config.viewHeight);
		overlay.getColor().a = 0;
		stage.addActor(overlay);
		Game.publisher().subscribe(this);
	}

	@Override
	public void dispose() {
		Game.publisher().unsubscribe(this);
	}

	@Override
	public void onEvent(Event event) {
		if (event instanceof TintScreenEvent) {
			final TintScreenEvent tint = (TintScreenEvent) event;
			if (tint.color == null) {
				overlay.addAction(Actions.sequence(Actions.alpha(tint.target, tint.duration), Actions.run(new Runnable() {
					@Override
					public void run() {
						if (tint.listener != null) {
							tint.listener.invoke();
						}
					}
				})));
			} else {
				colorAction.setColor(Game.batch().getColor());
				colorAction.setEndColor(tint.color);
				colorAction.setDuration(tint.duration);
				colorAction.restart();
				startedColorAction = true;
				tintListener = tint.listener;
			}
		}
	}

	@Override
	public void render() {
		stage.draw();
	}

	@Override
	public void update() {
		stage.act(Gdx.graphics.getDeltaTime());
		if (startedColorAction) {
			Game.batch().setColor(colorAction.getColor());
			if (colorAction.act(Gdx.graphics.getDeltaTime())) {
				L.$(tintListener);
				startedColorAction = false;
			}
		}
	}
}

Adjust batch's color on tint events