package rabbitescape.render;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static rabbitescape.engine.util.Util.*;
import rabbitescape.engine.err.RabbitEscapeException;
import rabbitescape.engine.util.Util;
public class AnimationLoader
{
public static final String NONE = "<none>";
public static class AnimationNotFound extends RabbitEscapeException
{
private static final long serialVersionUID = 1L;
public final String name;
public AnimationNotFound( String name )
{
this.name = name;
}
}
public static class BadAnimationLine extends RabbitEscapeException
{
private static final long serialVersionUID = 1L;
public final String line;
public BadAnimationLine( String line )
{
this.line = line;
}
public BadAnimationLine( String line, Throwable cause )
{
super( cause );
this.line = line;
}
}
public static class ErrorLoadingAnimationNames extends RabbitEscapeException
{
private static final long serialVersionUID = 1L;
public ErrorLoadingAnimationNames( Throwable cause )
{
super( cause );
}
}
public static String[] animationFilesInResource( String lsResourceName )
{
try
{
return stringArray(
chain(
Arrays.asList( NONE ),
map(
stripLast( 4 ),
filter(
endsWith( ".rea" ),
resourceLines( lsResourceName )
)
)
)
);
}
catch ( ReadingResourceFailed e )
{
throw new ErrorLoadingAnimationNames( e );
}
}
public static String[] listAll()
{
return animationFilesInResource(
"/rabbitescape/render/animations/ls.txt" );
}
public static Animation load( String name )
{
try
{
String key = "/rabbitescape/render/animations/" + name + ".rea";
URL url = AnimationLoader.class.getResource( key );
if ( url == null )
{
throw new AnimationNotFound( name );
}
InputStream stream = url.openStream();
return readAnimation( stream );
}
catch ( IOException e )
{
throw new AnimationNotFound( name );
}
}
private static int xOffset = 0, yOffset = 0;
public static Animation readAnimation( InputStream stream )
throws IOException
{
BufferedReader reader = new BufferedReader(
new InputStreamReader( stream ) );
List<Frame> ret = new ArrayList<>();
String ln;
xOffset = 0; yOffset = 0;
while ( ( ln = reader.readLine() ) != null )
{
String trimmedLn = ln.trim();
if ( !Util.isEmpty( trimmedLn ) )
{
Frame lineFrame = frameFromLine( trimmedLn );
if ( null != lineFrame ) {
ret.add( lineFrame );
}
}
}
return new Animation( ret );
}
private static Frame frameFromLine( String animLine )
{
String[] parts = animLine.split( " +" );
try
{
switch ( parts.length )
{
case 1:
{
return new Frame( parts[0], xOffset, yOffset, null );
}
case 2:
{
return new Frame(
parts[0], Integer.valueOf( parts[1] ) + xOffset, yOffset, null );
}
case 3:
{
if ( parts[0].equals( "offset" ) )
{
xOffset = Integer.valueOf( parts[1] ) + xOffset;
yOffset = Integer.valueOf( parts[2] ) + yOffset;
return null;
}
return new Frame(
parts[0],
Integer.valueOf( parts[1] ) + xOffset,
Integer.valueOf( parts[2] ) + yOffset,
null
);
}
case 4:
{
return new Frame(
parts[0],
Integer.valueOf( parts[1] ) + xOffset,
Integer.valueOf( parts[2] ) + yOffset,
parts[3]
);
}
default:
{
throw new BadAnimationLine( animLine );
}
}
}
catch ( NumberFormatException e )
{
throw new BadAnimationLine( animLine, e );
}
}
}