/*
* Copyright (C) 2006 Clam <clamisgood@gmail.com>
* Copyright (C) 2008, 2009 Quadduc <quadduc@gmail.com>
* Copyright (C) 2011 IsmAvatar <IsmAvatar@gmail.com>
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.resources;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferDouble;
import java.awt.image.DataBufferFloat;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferShort;
import java.lang.ref.SoftReference;
import java.util.EnumMap;
import org.lateralgm.main.Util;
import org.lateralgm.util.PropertyMap;
import org.lateralgm.util.PropertyMap.PropertyUpdateEvent;
import org.lateralgm.util.PropertyMap.PropertyUpdateListener;
public class Background extends InstantiableResource<Background,Background.PBackground> implements
Resource.Viewable
{
private BufferedImage backgroundImage = null;
private SoftReference<BufferedImage> imageCache = null;
private final BackgroundPropertyListener bpl = new BackgroundPropertyListener();
public enum PBackground
{
TRANSPARENT,SMOOTH_EDGES,PRELOAD,USE_AS_TILESET,TILE_WIDTH,TILE_HEIGHT,H_OFFSET,V_OFFSET,H_SEP,
V_SEP,TILE_HORIZONTALLY,TILE_VERTICALLY,FOR3D
}
private static final EnumMap<PBackground,Object> DEFS = PropertyMap.makeDefaultMap(
PBackground.class,false,false,false,false,16,16,0,0,0,0,false,false,false);
public Background()
{
this(null);
}
public Background(ResourceReference<Background> r)
{
super(r);
properties.getUpdateSource(PBackground.TRANSPARENT).addListener(bpl);
}
public Background makeInstance(ResourceReference<Background> r)
{
return new Background(r);
}
public BufferedImage getDisplayImage()
{
if (backgroundImage == null) return null;
BufferedImage bi;
if (imageCache != null)
{
bi = imageCache.get();
if (bi != null)
{
return bi;
}
}
bi = backgroundImage;
if (get(PBackground.TRANSPARENT)) bi = Util.getTransparentImage(bi);
imageCache = new SoftReference<BufferedImage>(bi);
return bi;
}
protected void postCopy(Background dest)
{
super.postCopy(dest);
dest.backgroundImage = Util.cloneImage(backgroundImage);
}
@Override
protected void fireUpdate()
{
if (imageCache != null) imageCache.clear();
super.fireUpdate();
}
public BufferedImage getBackgroundImage()
{
return backgroundImage;
}
public void setBackgroundImage(BufferedImage backgroundImage)
{
this.backgroundImage = backgroundImage;
fireUpdate();
}
/** Returns the byte length of a DataBuffer **/
//TODO: This function reports astronomical values for some reason.
public long getDataBytes(DataBuffer data)
{
int dataType = data.getDataType();
switch (dataType)
{
case DataBuffer.TYPE_BYTE:
byte[] bytes = ((DataBufferByte) data).getData();
return bytes.length;
case DataBuffer.TYPE_USHORT:
short[] shorts = ((DataBufferShort) data).getData();
return shorts.length * 2;
case DataBuffer.TYPE_INT:
int[] ints = ((DataBufferInt) data).getData();
return ints.length * 4;
case DataBuffer.TYPE_FLOAT:
float[] floats = ((DataBufferFloat) data).getData();
return floats.length * 4;
case DataBuffer.TYPE_DOUBLE:
double[] doubles = ((DataBufferDouble) data).getData();
return doubles.length * 8;
default:
throw new IllegalArgumentException("Unknown data buffer type: " + dataType);
}
}
/** Returns the size of the background image in bytes */
public long getSize()
{
if (backgroundImage != null)
{
return this.getWidth() * this.getHeight() * 4;//getDataBytes(backgroundImage.getRaster().getDataBuffer());
}
return 0;
}
public int getWidth()
{
return backgroundImage == null ? 0 : backgroundImage.getWidth();
}
public int getHeight()
{
return backgroundImage == null ? 0 : backgroundImage.getHeight();
}
@Override
protected PropertyMap<PBackground> makePropertyMap()
{
return new PropertyMap<PBackground>(PBackground.class,this,DEFS);
}
private class BackgroundPropertyListener extends PropertyUpdateListener<PBackground>
{
@Override
public void updated(PropertyUpdateEvent<PBackground> e)
{
switch (e.key)
{
case TRANSPARENT:
fireUpdate();
break;
default:
//TODO: maybe put a failsafe here?
break;
}
}
}
}