/* * Copyright (C) 2006 Clam <clamisgood@gmail.com> * Copyright (C) 2008 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2008, 2009 Quadduc <quadduc@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.sub; import java.awt.Dimension; import java.awt.Point; import java.util.EnumMap; import org.lateralgm.file.GmFile; import org.lateralgm.main.UpdateSource; import org.lateralgm.main.UpdateSource.UpdateEvent; import org.lateralgm.main.UpdateSource.UpdateListener; import org.lateralgm.main.UpdateSource.UpdateTrigger; import org.lateralgm.resources.Background; import org.lateralgm.resources.ResourceReference; import org.lateralgm.resources.Room; import org.lateralgm.util.PropertyMap; import org.lateralgm.util.PropertyMap.PropertyUpdateEvent; import org.lateralgm.util.PropertyMap.PropertyUpdateListener; import org.lateralgm.util.PropertyMap.PropertyValidationException; import org.lateralgm.util.PropertyMap.PropertyValidator; public class Tile implements Room.Piece,UpdateListener,PropertyValidator<Tile.PTile> { private ResourceReference<?> background = null; //kept for listening purposes public final PropertyMap<PTile> properties; private final ResourceReference<Room> room; private final TilePropertyListener tpl = new TilePropertyListener(); private final UpdateTrigger updateTrigger = new UpdateTrigger(); public final UpdateSource updateSource = new UpdateSource(this,updateTrigger); public enum PTile { BG_X,BG_Y,ROOM_X,ROOM_Y,WIDTH,HEIGHT,DEPTH,BACKGROUND,ID,LOCKED } private static final EnumMap<PTile,Object> DEFS = PropertyMap.makeDefaultMap(PTile.class,0,0,0,0, 0,0,0,null,0,false); /** * Do not call this constructor unless you intend * to handle your own tile ID. See Tile(Room r, GmFile f). */ public Tile(Room r) { room = r.reference; properties = new PropertyMap<PTile>(PTile.class,this,DEFS); properties.getUpdateSource(PTile.BACKGROUND).addListener(tpl); } public Tile(Room r, int id) { this(r); properties.put(PTile.ID,id); } /** * Constructs a tile for this GmFile, and determines ID via the last tile id. * Notice that a tile initializes with no settings. */ public Tile(Room r, GmFile f) { this(r,++f.lastTileId); } protected void fireUpdate(UpdateEvent e) { if (e == null) e = updateTrigger.getEvent(); updateTrigger.fire(e); Room r = room == null ? null : room.get(); if (r != null) r.tileUpdated(e); } public Point getBackgroundPosition() { int x = properties.get(PTile.BG_X); int y = properties.get(PTile.BG_Y); return new Point(x,y); } public void setBackgroundPosition(Point p) { properties.put(PTile.BG_X,p.x); properties.put(PTile.BG_Y,p.y); fireUpdate(null); } public Point getRoomPosition() { int x = properties.get(PTile.ROOM_X); int y = properties.get(PTile.ROOM_Y); return new Point(x,y); } public void setRoomPosition(Point p) { properties.put(PTile.ROOM_X,p.x); properties.put(PTile.ROOM_Y,p.y); } public Dimension getSize() { int w = properties.get(PTile.WIDTH); int h = properties.get(PTile.HEIGHT); return new Dimension(w,h); } public void setSize(Dimension s) { properties.put(PTile.WIDTH,s.width); properties.put(PTile.HEIGHT,s.height); fireUpdate(null); } public int getDepth() { return properties.get(PTile.DEPTH); } public void setDepth(int d) { properties.put(PTile.DEPTH,d); } public void updated(UpdateEvent e) { fireUpdate(e); } public boolean isLocked() { return properties.get(PTile.LOCKED); } public void setLocked(boolean l) { properties.put(PTile.LOCKED,l); } public Object validate(PTile k, Object v) { if (k == PTile.BACKGROUND) { ResourceReference<?> r = (ResourceReference<?>) v; if (r != null) { Object o = r.get(); if (o == null) r = null; else if (!(o instanceof Background)) throw new PropertyValidationException(); } if (background != null) background.updateSource.removeListener(this); background = r; if (background != null) background.updateSource.addListener(this); } return v; } private class TilePropertyListener extends PropertyUpdateListener<PTile> { @Override public void updated(PropertyUpdateEvent<PTile> e) { if (e.key == PTile.BACKGROUND) fireUpdate(null); } } public boolean equals(Object o) { if (o == this) return true; if (o == null || !(o instanceof Tile)) return false; //room? return properties.equals(((Tile) o).properties); } }