package org.gbcpainter.game.view;
import org.gbcpainter.env.GraphicsEnv;
import org.gbcpainter.loaders.textures.TextureLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.geom.Point2D;
import java.util.NoSuchElementException;
/**
* Provides the methods to draw a texture from a given image and element coordinates
* <p/>
* The texture name is fetched from {@link #getResourceName()} and position is fetched from
* {@link #getPosition()}. This class follows the template method pattern.
*
* @author Lorenzo Pellegrini
*/
public abstract class AbstractResourceDrawable extends AbstractDrawableElement {
/**
* Creates a drawable element that fetches the drawing data from its abstract methods
*/
public AbstractResourceDrawable( ) {
super();
}
/**
* Draws the element with the texture defined by {@link #getDrawTexture()}
*
* @param g2 The graphics object to draw to
*
* @throws Exception if an exception occurs while managing textures
*/
@Override
public synchronized void draw( @NotNull Graphics2D g2 ) throws Exception {
boolean done = false;
boolean tryAcceleration = true;
final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();
do {
final String resourceName = this.getResourceName();
if ( resourceName == null ) {
done = true;
} else {
super.draw( g2 );
try {
if ( ! loader.mustReload( resourceName, tryAcceleration ) ) {
done = true;
}
} catch ( NoSuchElementException e ) {
tryAcceleration = false;
}
}
} while ( ! done );
}
@Override
protected Rectangle getDrawingRect() throws Exception {
final String resourceName;
final Point2D position;
synchronized (this) {
resourceName = this.getResourceName();
position = this.getPosition();
}
if ( resourceName == null ) {
return null;
}
@Nullable
final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();
final Dimension dimension = loader.getDimension( resourceName );
return GraphicsEnv.getInstance().gamePointAndTextureToScreen( position, dimension );
}
@Nullable
@Override
protected Image getDrawTexture() throws Exception {
final String resourceName;
resourceName = this.getResourceName();
if ( resourceName == null ) {
return null;
}
final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();
Image texture = loader.getTexture( resourceName, true );
if ( texture == null ) {
texture = loader.loadTexture( resourceName, true );
}
return texture;
}
/*
* Gets the position of the element
*
* This method is not called to obtain the position to draw the texture to.
*
* @return The position of the element
*/
@NotNull
public abstract Point2D getPosition();
/**
* Retrieves the name of element's texture name
*
* @return The name of the texture or null if the element is hidden
*/
@Nullable
protected abstract String getResourceName();
/**
* Gets the Rectangle of the texture in the screen coordinates system from a given game point coordinates
*
* @param asIfItWasHere The game point
*
* @return The rectangle where the texture would be drawn if the element was at a given position
*/
@Nullable
protected Rectangle getDrawingRect( @NotNull Point2D asIfItWasHere ) {
@Nullable
final String resourceName = this.getResourceName();
if ( resourceName == null ) {
return null;
}
final TextureLoader loader = GraphicsEnv.getInstance().getTextureLoader();
final Dimension dimension = loader.getDimension( resourceName );
return GraphicsEnv.getInstance().gamePointAndTextureToScreen( asIfItWasHere, dimension );
}
}