package org.gbcpainter.game.view;
import org.gbcpainter.env.GraphicsEnv;
import org.gbcpainter.loaders.textures.TextureNotFoundException;
import org.gbcpainter.loaders.textures.TextureLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* An implementation of {@link org.gbcpainter.game.view.AbstractResourceDrawable} that selects its texture rotation basing on a selectable slot system
*
* @author Lorenzo Pellegrini
*/
public abstract class SlotResourceDrawable<T> extends AbstractResourceDrawable {
@NotNull
private final Map<T, Iterable<String>> resources;
@NotNull
private T actualSlot;
@NotNull
private Iterator<String> nextTexture;
@NotNull
private String actualTexture;
/**
* Creates a slot drawable with the given mapping slot:textures to be rotated
*
* @param resources The textures mapping
* @param slot The initial textures slot
*
* @throws Exception If an error occurs while loading the textures
*/
public SlotResourceDrawable( @NotNull final Map<T,
Iterable<String>> resources, @NotNull T slot ) throws Exception {
super( );
this.resources = new HashMap<>( resources );
this.actualSlot = slot;
final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();
for (Iterable<String> slotList : resources.values()) {
for (String resource : slotList) {
try {
loader.loadTexture( resource, true );
} catch ( Exception e ) {
throw new TextureNotFoundException( e );
}
}
}
this.nextTexture = resources.get( this.actualSlot ).iterator();
this.actualTexture =this. nextTexture.next();
}
@Nullable
@Override
protected synchronized String getResourceName() {
return this.actualTexture;
}
/**
* Switches the slot. The new texture is set as the first of that slot.
*
* @param newSlot The new slot to use
*/
protected synchronized void switchSlot( @NotNull T newSlot ) {
this.actualSlot = newSlot;
this.nextTexture = this.resources.get( this.actualSlot ).iterator();
this.actualTexture = this.nextTexture.next();
}
/**
* Gets the actual used slot to choose textures from
*
* @return The actual texture slot
*/
@NotNull
protected synchronized T getSlot() {
return this.actualSlot;
}
/**
* Gets the next texture af the actual slot
*
* @return The texture that will be used from now
*/
@NotNull
protected synchronized String nextTexture() {
if ( ! this.nextTexture.hasNext() ) {
this.nextTexture = this.resources.get( this.actualSlot ).iterator();
}
this.actualTexture = this.nextTexture.next();
return this.actualTexture;
}
}