001/*
002 * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
003 * Copyright (C) 2000-2010 The Gridarta Developers.
004 *
005 * This program is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation; either version 2 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License along
016 * with this program; if not, write to the Free Software Foundation, Inc.,
017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
018 */
019
020package net.sf.gridarta.model.match;
021
022import java.awt.event.ActionEvent;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.List;
026import javax.swing.AbstractAction;
027import javax.swing.Action;
028import org.jetbrains.annotations.NotNull;
029
030/**
031 * Manages {@link GameObjectMatcher GameObjectMatchers}.
032 * @author <a href="mailto:cher@riedquat.de">Christian Hujer</a>
033 */
034public class ViewGameObjectMatcherManager {
035
036    /**
037     * The {@link MutableOrGameObjectMatcher} that is manipulated by the
038     * actions.
039     */
040    @NotNull
041    private final MutableOrGameObjectMatcher mutableOrGameObjectMatcher;
042
043    /**
044     * The actions.
045     */
046    @NotNull
047    private final List<GameObjectMatcherToggleAction> actions = new ArrayList<GameObjectMatcherToggleAction>();
048
049    /**
050     * The reset action.
051     */
052    @NotNull
053    private final Action resetAction = new ResetAction(Collections.unmodifiableList(actions));
054
055    /**
056     * Creates a <code>ViewArchObjectMatcher</code>.
057     * @param mutableOrGameObjectMatcher the <code>MutableOrGameObjectMatcher</code>
058     * to manipulate
059     */
060    public ViewGameObjectMatcherManager(@NotNull final MutableOrGameObjectMatcher mutableOrGameObjectMatcher) {
061        this.mutableOrGameObjectMatcher = mutableOrGameObjectMatcher;
062    }
063
064    /**
065     * Adds an {@link GameObjectMatcher}.
066     * @param gameObjectMatcher the <code>GameObjectMatcher</code> to add
067     * @return the <code>Action</code> created for toggling
068     *         <code>gameObjectMatcher</code>
069     */
070    @NotNull
071    public Action addArchObjectMatcher(@NotNull final GameObjectMatcher gameObjectMatcher) {
072        final GameObjectMatcherToggleAction action = new GameObjectMatcherToggleAction(gameObjectMatcher, mutableOrGameObjectMatcher);
073        actions.add(action);
074        return action;
075    }
076
077    /**
078     * Gets all actions.
079     * @return all actions created so far (except reset)
080     */
081    @NotNull
082    public List<? extends Action> getAllActions() {
083        return Collections.unmodifiableList(actions);
084    }
085
086    /**
087     * Gets the reset action.
088     * @return the reset action
089     */
090    @NotNull
091    public Action getResetAction() {
092        return resetAction;
093    }
094
095    /**
096     * The reset action.
097     */
098    private static class ResetAction extends AbstractAction {
099
100        /**
101         * The serial version UID.
102         */
103        private static final long serialVersionUID = 1L;
104
105        /**
106         * The actions to reset.
107         */
108        @NotNull
109        private final Iterable<? extends GameObjectMatcherToggleAction> actions;
110
111        /**
112         * Creates a <code>ResetAction</code>.
113         * @param actions the <code>Action</code>s to reset
114         */
115        ResetAction(@NotNull final Iterable<? extends GameObjectMatcherToggleAction> actions) {
116            this.actions = actions;
117        }
118
119        @Override
120        public void actionPerformed(@NotNull final ActionEvent e) {
121            for (final GameObjectMatcherToggleAction action : actions) {
122                action.setSelected(false);
123            }
124        }
125
126        @NotNull
127        @Override
128        protected Object clone() {
129            try {
130                return super.clone();
131            } catch (final CloneNotSupportedException ex) {
132                throw new AssertionError(ex);
133            }
134        }
135
136    }
137
138    /**
139     * An {@link Action} to toggle an {@link GameObjectMatcher} within an {@link
140     * MutableOrGameObjectMatcher}.
141     */
142    private static class GameObjectMatcherToggleAction extends AbstractAction {
143
144        /**
145         * The serial version UID.
146         */
147        private static final long serialVersionUID = 1L;
148
149        /**
150         * Selected state.
151         */
152        private boolean selected;
153
154        /**
155         * A {@link MutableOrGameObjectMatcher} to add / remove {@link
156         * GameObjectMatcher} to.
157         */
158        @NotNull
159        private final MutableOrGameObjectMatcher mutableOrArchObjectMatcher;
160
161        /**
162         * The {@link GameObjectMatcher} to add / remove.
163         */
164        @NotNull
165        private final GameObjectMatcher gameObjectMatcher;
166
167        /**
168         * Creates an <code>GameObjectMatcherToggleAction</code>.
169         * @param gameObjectMatcher the matcher to add / remove to / from
170         * <code>mutableOrGameObjectMatcher</code>
171         * @param mutableOrArchObjectMatcher the <code>MutableOrGameObjectMatcher</code>
172         * to add / remove <code>gameObjectMatcher</code> to / from
173         */
174        GameObjectMatcherToggleAction(@NotNull final GameObjectMatcher gameObjectMatcher, @NotNull final MutableOrGameObjectMatcher mutableOrArchObjectMatcher) {
175            this.gameObjectMatcher = gameObjectMatcher;
176            this.mutableOrArchObjectMatcher = mutableOrArchObjectMatcher;
177        }
178
179        @Override
180        public void actionPerformed(@NotNull final ActionEvent e) {
181            if (!isEnabled()) {
182                return;
183            }
184            setSelected(!selected);
185        }
186
187        /**
188         * Sets the selected state.
189         * @param selected the new selected state
190         */
191        public void setSelected(final boolean selected) {
192            this.selected = selected;
193            if (selected) {
194                mutableOrArchObjectMatcher.addArchObjectMatcher(gameObjectMatcher);
195            } else {
196                mutableOrArchObjectMatcher.removeArchObjectMatcher(gameObjectMatcher);
197            }
198        }
199
200        /**
201         * Gets the selected state.
202         * @return the selected state
203         * @retval <code>true</code> if this action is selected
204         * @retval <code>false</code> if this action is not selected
205         */
206        public boolean isSelected() {
207            return selected;
208        }
209
210        @NotNull
211        @Override
212        protected Object clone() {
213            try {
214                return super.clone();
215            } catch (final CloneNotSupportedException ex) {
216                throw new AssertionError(ex);
217            }
218        }
219
220    }
221
222}