001    /*
002     * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
003     * Copyright (C) 2000-2011 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    
020    package net.sf.gridarta.gui.panel.selectedsquare;
021    
022    import java.awt.Point;
023    import net.sf.gridarta.model.archetype.Archetype;
024    import net.sf.gridarta.model.gameobject.GameObject;
025    import net.sf.gridarta.model.maparchobject.MapArchObject;
026    import net.sf.gridarta.model.mapmodel.MapModel;
027    import net.sf.gridarta.model.mapmodel.MapSquare;
028    import org.jetbrains.annotations.NotNull;
029    
030    /**
031     * Implementing actions that operate on {@link SelectedSquareModel
032     * SelectedSquareModels}.
033     * @author Andreas Kirschbaum
034     */
035    public class SelectedSquareActions<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> {
036    
037        /**
038         * The {@link SelectedSquareModel} for this controller.
039         */
040        @NotNull
041        private final SelectedSquareModel<G, A, R> selectedSquareModel;
042    
043        /**
044         * Creates a new instance.
045         * @param selectedSquareModel the selected square model to operate on
046         */
047        public SelectedSquareActions(@NotNull final SelectedSquareModel<G, A, R> selectedSquareModel) {
048            this.selectedSquareModel = selectedSquareModel;
049        }
050    
051        /**
052         * Executes the "move square prev" action.
053         * @param performAction whether the action should be performed
054         * @return whether the action was or can be performed
055         */
056        public boolean doMoveSquarePrev(final boolean performAction) {
057            final GameObject<G, A, R> gameObject = selectedSquareModel.getSelectedGameObject();
058            if (gameObject == null || !gameObject.isHead()) {
059                return false;
060            }
061    
062            G prevGameObject = gameObject.getPrev();
063            if (prevGameObject == null) {
064                prevGameObject = gameObject.getContainerGameObject();
065                if (prevGameObject == null) {
066                    return false;
067                }
068            } else if (performAction) {
069                while (true) {
070                    final G tmp = prevGameObject.getFirst();
071                    if (tmp == null) {
072                        break;
073                    }
074                    prevGameObject = tmp;
075                }
076            }
077    
078            if (performAction) {
079                selectedSquareModel.setSelectedGameObject(prevGameObject);
080            }
081    
082            return true;
083        }
084    
085        /**
086         * Executes the "move square next" action.
087         * @param performAction whether the action should be performed
088         * @return whether the action was or can be performed
089         */
090        public boolean doMoveSquareNext(final boolean performAction) {
091            final G gameObject = selectedSquareModel.getSelectedGameObject();
092            if (gameObject == null || !gameObject.isHead()) {
093                return false;
094            }
095    
096            G nextGameObject = gameObject.getLast();
097            if (nextGameObject == null) {
098                nextGameObject = gameObject;
099                while (true) {
100                    final G tmp = nextGameObject.getNext();
101                    if (tmp != null) {
102                        nextGameObject = tmp;
103                        break;
104                    }
105                    nextGameObject = nextGameObject.getContainerGameObject();
106                    if (nextGameObject == null) {
107                        return false;
108                    }
109                }
110            }
111    
112            if (performAction) {
113                selectedSquareModel.setSelectedGameObject(nextGameObject);
114            }
115    
116            return true;
117        }
118    
119        /**
120         * Executes the "move square top" action.
121         * @param performAction whether the action should be performed
122         * @return whether the action was or can be performed
123         */
124        public boolean doMoveSquareTop(final boolean performAction) {
125            final GameObject<G, A, R> gameObject = selectedSquareModel.getSelectedGameObject();
126            if (gameObject == null || !gameObject.isHead()) {
127                return false;
128            }
129    
130            if (gameObject.isTop()) {
131                return false;
132            }
133    
134            if (performAction) {
135                final MapSquare<G, A, R> mapSquare = gameObject.getMapSquare();
136                assert mapSquare != null;
137                final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
138                mapModel.beginTransaction("Move Top");
139                try {
140                    gameObject.moveTop();
141                } finally {
142                    mapModel.endTransaction();
143                }
144            }
145    
146            return true;
147        }
148    
149        /**
150         * Executes the "move square up" action.
151         * @param performAction whether the action should be performed
152         * @return whether the action was or can be performed
153         */
154        public boolean doMoveSquareUp(final boolean performAction) {
155            final GameObject<G, A, R> gameObject = selectedSquareModel.getSelectedGameObject();
156            if (gameObject == null || !gameObject.isHead()) {
157                return false;
158            }
159    
160            if (gameObject.isTop()) {
161                return false;
162            }
163    
164            if (performAction) {
165                final MapSquare<G, A, R> mapSquare = gameObject.getMapSquare();
166                assert mapSquare != null;
167                final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
168                mapModel.beginTransaction("Move Up");
169                try {
170                    gameObject.moveUp();
171                } finally {
172                    mapModel.endTransaction();
173                }
174            }
175    
176            return true;
177        }
178    
179        /**
180         * Executes the "move square down" action.
181         * @param performAction whether the action should be performed
182         * @return whether the action was or can be performed
183         */
184        public boolean doMoveSquareDown(final boolean performAction) {
185            final GameObject<G, A, R> gameObject = selectedSquareModel.getSelectedGameObject();
186            if (gameObject == null || !gameObject.isHead()) {
187                return false;
188            }
189    
190            if (gameObject.isBottom()) {
191                return false;
192            }
193    
194            if (performAction) {
195                final MapSquare<G, A, R> mapSquare = gameObject.getMapSquare();
196                assert mapSquare != null;
197                final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
198                mapModel.beginTransaction("Move Down");
199                try {
200                    gameObject.moveDown();
201                } finally {
202                    mapModel.endTransaction();
203                }
204            }
205    
206            return true;
207        }
208    
209        /**
210         * Executes the "move square bottom" action.
211         * @param performAction whether the action should be performed
212         * @return whether the action was or can be performed
213         */
214        public boolean doMoveSquareBottom(final boolean performAction) {
215            final GameObject<G, A, R> gameObject = selectedSquareModel.getSelectedGameObject();
216            if (gameObject == null || !gameObject.isHead()) {
217                return false;
218            }
219    
220            if (gameObject.isBottom()) {
221                return false;
222            }
223    
224            if (performAction) {
225                final MapSquare<G, A, R> mapSquare = gameObject.getMapSquare();
226                assert mapSquare != null;
227                final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
228                mapModel.beginTransaction("Move Bottom");
229                try {
230                    gameObject.moveBottom();
231                } finally {
232                    mapModel.endTransaction();
233                }
234            }
235    
236            return true;
237        }
238    
239        /**
240         * Executes the "move square env" action.
241         * @param performAction whether the action should be performed
242         * @return whether the action was or can be performed
243         */
244        public boolean doMoveSquareEnv(final boolean performAction) {
245            final G gameObject = selectedSquareModel.getSelectedGameObject();
246            if (gameObject == null || !gameObject.isHead()) {
247                return false;
248            }
249    
250            final G envGameObject = gameObject.getContainerGameObject();
251            if (envGameObject == null) {
252                return false;
253            }
254    
255            final MapSquare<G, A, R> mapSquare = selectedSquareModel.getSelectedMapSquare();
256            if (mapSquare == null) {
257                return false;
258            }
259    
260            final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
261            final Point pos = mapSquare.getMapLocation();
262            if (!envGameObject.isInContainer() && gameObject.getArchetype().isMulti() && !mapModel.isMultiArchFittingToMap(gameObject.getArchetype(), pos, true)) {
263                return false;
264            }
265    
266            if (performAction) {
267                mapModel.beginTransaction("Move To Environment");
268                try {
269                    mapModel.moveEnv(gameObject, pos, envGameObject);
270                } finally {
271                    mapModel.endTransaction();
272                }
273            }
274    
275            return true;
276        }
277    
278        /**
279         * Executes the "move square inv" action.
280         * @param performAction whether the action should be performed
281         * @return whether the action was or can be performed
282         */
283        public boolean doMoveSquareInv(final boolean performAction) {
284            final G gameObject = selectedSquareModel.getSelectedGameObject();
285            if (gameObject == null || !gameObject.isHead()) {
286                return false;
287            }
288    
289            final GameObject<G, A, R> prevGameObject = gameObject.getPrev();
290            if (prevGameObject == null) {
291                return false;
292            }
293    
294            if (performAction) {
295                final MapSquare<G, A, R> mapSquare = gameObject.getMapSquare();
296                assert mapSquare != null;
297                final MapModel<G, A, R> mapModel = mapSquare.getMapModel();
298                mapModel.beginTransaction("Move To Inventory");
299                try {
300                    mapModel.moveInv(gameObject, prevGameObject.getHead());
301                } finally {
302                    mapModel.endTransaction();
303                }
304            }
305    
306            return true;
307        }
308    
309    }