001package fr.aumgn.dac2.arena;
002
003import java.util.UUID;
004
005import org.bukkit.Bukkit;
006import org.bukkit.World;
007
008import fr.aumgn.dac2.DAC;
009import fr.aumgn.dac2.arena.regions.Pool;
010import fr.aumgn.dac2.arena.regions.StartRegion;
011import fr.aumgn.dac2.arena.regions.SurroundingRegion;
012import fr.aumgn.dac2.exceptions.ArenaComponentUndefined;
013
014public class Arena {
015
016    private final String name;
017    private final UUID worldId;
018    private Pool pool;
019    private StartRegion startRegion;
020    private Diving diving;
021    private SurroundingRegion surrounding;
022
023    private transient SurroundingRegion autoSurrounding;
024
025    public Arena(String name, World world) {
026        this.name = name;
027        this.worldId = world.getUID();
028        this.pool = null;
029        this.startRegion = null;
030        this.diving = null;
031        this.surrounding = null;
032        this.autoSurrounding = null;
033    }
034
035    public String getName() {
036        return name;
037    }
038
039    public World getWorld() {
040        return Bukkit.getWorld(worldId);
041    }
042
043    public boolean isIn(World world) {
044        return worldId.equals(world.getUID());
045    }
046
047    /**
048     * Checks if this arena is complete.
049     *
050     * An arena is considered complete if it has :
051     * <ul>
052     *   <li>A pool</li>
053     *   <li>A start region</li>
054     *   <li>A diving</li>
055     * </ul>
056     */
057    public boolean isComplete() {
058        return pool != null && startRegion != null && diving != null;
059    }
060
061    public Pool getPool() {
062        return pool;
063    }
064
065    /**
066     * Returns the pool if defined or throws an exception if not.
067     *
068     * @param dac the main DAC instance.
069     * @throws ArenaComponentUndefined
070     * @return the pool
071     */
072    public Pool safeGetPool(DAC dac) {
073        if (pool == null) {
074            throw new ArenaComponentUndefined(dac.getMessages()
075                    .get("arena.pool.notdefined"));
076        }
077
078        return pool;
079    }
080
081    public void setPool(Pool pool) {
082        this.pool = pool;
083        this.surrounding = null;
084    }
085
086    public StartRegion getStartRegion() {
087        return startRegion;
088    }
089
090    /**
091     * Returns the start region if defined or throws an exception if not.
092     *
093     * @param dac the main DAC instance.
094     * @throws ArenaComponentUndefined
095     * @return the start region
096     */
097
098    public StartRegion safeGetStartRegion(DAC dac) {
099        if (startRegion == null) {
100            throw new ArenaComponentUndefined(dac.getMessages()
101                    .get("arena.start.notdefined"));
102        }
103
104        return startRegion;
105    }
106
107    public void setStartRegion(StartRegion region) {
108        this.startRegion = region;
109    }
110
111    public Diving getDiving() {
112        return diving;
113    }
114
115    /**
116     * Returns the diving board if defined or throws an exception if not.
117     *
118     * @param dac the main DAC instance.
119     * @throws ArenaComponentUndefined
120     * @return the diving board
121     */
122    public Diving safeGetDiving(DAC dac) {
123        if (diving == null) {
124            throw new ArenaComponentUndefined(dac.getMessages()
125                    .get("arena.diving.notdefined"));
126        }
127
128        return diving;
129    }
130
131    public void setDiving(Diving diving) {
132        this.diving = diving;
133        this.surrounding = null;
134    }
135
136    public SurroundingRegion getSurroundingRegion() {
137        if (surrounding != null) {
138            return surrounding;
139        }
140
141        if (autoSurrounding == null) {
142            if (diving == null || pool == null) {
143                return null;
144            }
145
146            autoSurrounding = new SurroundingRegion(diving, pool);
147        }
148        return autoSurrounding;
149    }
150
151    /**
152     * Returns the surrounding region if defined or throws an exception if not.
153     *
154     * The surrounding region doesn't need to be manually defined.
155     * It is also considered defined if the pool and the diving are.
156     *
157     * @param dac the main DAC instance.
158     * @throws ArenaComponentUndefined
159     * @return the surrounding region
160     */
161    public SurroundingRegion safeGetSurroundingRegion(DAC dac) {
162        SurroundingRegion region = getSurroundingRegion();
163        if (region == null) {
164            throw new ArenaComponentUndefined(dac.getMessages()
165                    .get("arena.surrounding.notdefined"));
166        }
167
168        return region;
169    }
170
171    /**
172     * Sets the surrrounding region.
173     *
174     * This will override the region wich is automatically defined
175     * using the pool and the diving.
176     * 
177     * @param surrounding the new manually defined surrounding region.
178     */
179    public void setSurroundingRegion(SurroundingRegion surrounding) {
180        this.surrounding = surrounding;
181        this.autoSurrounding = null;
182    }
183}