// // @(#)PhaseSelector.java 4/2002 // // Copyright 2002 Zachary DelProposto. All rights reserved. // Use is subject to license terms. // // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Or from http://www.gnu.org/ // package dip.gui; import dip.world.World; import dip.world.Phase; import dip.world.TurnState; import java.util.Set; import java.util.Arrays; /** * * Manages all (except for select) items in the History menu. * <p> * This object is created by ClientFrame, and can be used by * other classes via the getPhaseSelector() method in ClientFrame. * */ public class PhaseSelector { private World currentWorld = null; private TurnState currentTS = null; private int currentPos = 0; private int maxPos = 0; private Phase[] phases = null; private ClientFrame parent = null; private ClientMenu menu = null; private PhasePCL pcl = null; /** Create a PhaseSelector object. */ public PhaseSelector(ClientFrame parent) { this.parent = parent; this.menu = parent.getClientMenu(); this.pcl = new PhasePCL(); parent.addPropertyChangeListener(pcl); }// PhaseSelector() /** Cleanup the PhaseSelector object */ public void close() { parent.removePropertyChangeListener(pcl); }// close() /** Go to the Previous phase, if possible. */ public void previous() { if(currentPos > 0) { parent.fireTurnstateChanged( currentWorld.getTurnState(phases[currentPos-1]) ); } }// previous() /** Go to the next phase, if possible. */ public void next() { if(currentPos < maxPos) { parent.fireTurnstateChanged( currentWorld.getTurnState(phases[currentPos+1]) ); } }// previous() /** Go to the first (initial) phase. */ public void first() { this.currentTS = currentWorld.getInitialTurnState(); parent.fireTurnstateChanged(currentTS); }// previous() /** Go to the last phase. */ public void last() { this.currentTS = currentWorld.getLastTurnState(); parent.fireTurnstateChanged(currentTS); }// previous() /** Get the total number of phases. */ public int getPhaseCount() { return maxPos + 1; }// getPhaseCount() /** Get the current phase position. */ public int getCurrentPhasePosition() { return currentPos; }// getCurrentPhasePosition() private void setWorld(World newWorld) { if(newWorld == null) { // disable menu options menu.setEnabled(ClientMenu.HISTORY_PREVIOUS, false); menu.setEnabled(ClientMenu.HISTORY_NEXT, false); menu.setEnabled(ClientMenu.HISTORY_INITIAL, false); menu.setEnabled(ClientMenu.HISTORY_LAST, false); menu.setEnabled(ClientMenu.HISTORY_SELECT, false); // reset our data currentWorld = null; currentTS = null; phases = null; currentPos = 0; maxPos = 0; } else { // enable menu options // // always enable select menu.setEnabled(ClientMenu.HISTORY_SELECT, true); // always enable first and last menu.setEnabled(ClientMenu.HISTORY_INITIAL, true); menu.setEnabled(ClientMenu.HISTORY_LAST, true); // set our data currentWorld = newWorld; } }// setWorld() private void setTurnState(TurnState ts) { if(ts == null) { throw new IllegalArgumentException("null turnstate"); } if(currentWorld == null) { throw new IllegalStateException("null world"); } currentTS = ts; setCurrentPosition(); }// setTurnState() private void setCurrentPosition() { // get set, convert to array Set set = currentWorld.getPhaseSet(); phases = (Phase[]) set.toArray(new Phase[set.size()]); // set max size maxPos = phases.length - 1; // find current position in array Phase currentPhase = currentTS.getPhase(); currentPos = Arrays.binarySearch(phases, currentPhase); if(currentPos < 0) { throw new IllegalStateException("bad position!"); } // update updateNextPrevious(); updateResults(); }// setCurrentPosition() /** Update Next/Previous menu items */ private void updateNextPrevious() { menu.setEnabled(ClientMenu.HISTORY_PREVIOUS, (currentPos > 0)); menu.setEnabled(ClientMenu.HISTORY_NEXT, (currentPos < maxPos)); }// updateNextPrevious() /** Update the Reports | Result (current, previous) menu items */ private void updateResults() { if(currentTS == null) { // if currentTS is null, previous turn state must also be null menu.setEnabled(ClientMenu.REPORTS_RESULTS, false); menu.setEnabled(ClientMenu.REPORTS_PREVIOUS_RESULTS, false); } else { // set current results, if available menu.setEnabled(ClientMenu.REPORTS_RESULTS, currentTS.isResolved()); // last results available? (if a turnstate is available, and we are not at initial position) if(currentPos <= 0) { menu.setEnabled(ClientMenu.REPORTS_PREVIOUS_RESULTS, false); } else { TurnState previousTS = currentWorld.getTurnState(phases[currentPos-1]); if(previousTS != null) { menu.setEnabled(ClientMenu.REPORTS_PREVIOUS_RESULTS, previousTS.isResolved()); } else { menu.setEnabled(ClientMenu.REPORTS_PREVIOUS_RESULTS, false); } } } }// updateResults() /** * Property Change Listener * */ private class PhasePCL extends AbstractCFPListener { public void actionWorldCreated(World w) { setWorld(w); }// actionWorldCreated() public void actionWorldDestroyed(World w) { setWorld(null); }// actionWorldDestroyed() public void actionTurnstateChanged(TurnState ts) { setTurnState(ts); }// actionTurnstateChanged() public void actionTurnstateAdded(TurnState ts) { setCurrentPosition(); }// actionTurnstateAdded() public void actionTurnstateRemoved() { setCurrentPosition(); }// actionTurnstateRemoved() public void actionModeChanged(String newMode) { if( newMode == ClientFrame.MODE_NONE || newMode == ClientFrame.MODE_EDIT ) { // disable history menu, completely menu.setEnabled(ClientMenu.HISTORY_PREVIOUS, false); menu.setEnabled(ClientMenu.HISTORY_NEXT, false); menu.setEnabled(ClientMenu.HISTORY_INITIAL, false); menu.setEnabled(ClientMenu.HISTORY_LAST, false); menu.setEnabled(ClientMenu.HISTORY_SELECT, false); } else { // refresh the history menu menu.setEnabled(ClientMenu.HISTORY_INITIAL, true); menu.setEnabled(ClientMenu.HISTORY_LAST, true); menu.setEnabled(ClientMenu.HISTORY_SELECT, true); updateNextPrevious(); } updateResults(); }// actionModeChanged() }// inner class PCListener }// class PhaseSelector