View Javadoc

1   /*
2    *   Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  package net.sf.magicproject.stack;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import net.sf.magicproject.clickable.ability.Ability;
25  import net.sf.magicproject.clickable.targetable.Targetable;
26  import net.sf.magicproject.event.Targeted;
27  import net.sf.magicproject.test.Test;
28  import net.sf.magicproject.token.IdTargets;
29  import net.sf.magicproject.tools.Log;
30  
31  /***
32   * MTargetedList.java Created on 8 oct. 2003 represents list of targets :
33   * player(s) and/or card(s).
34   * 
35   * @see net.sf.magicproject.xml.tbs.Card
36   * @see net.sf.magicproject.clickable.targetable.player.Player
37   * @since 0.2
38   * @since 0.53 manage the abortion when resoving a spell
39   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
40   */
41  public class TargetedList {
42  
43  	/***
44  	 * Creates a new instance of MTargetedList
45  	 * 
46  	 * @param source
47  	 *          the source of this list of targets
48  	 */
49  	public TargetedList(Ability source) {
50  		super();
51  		// TODO allAbortion = true;
52  		this.source = source;
53  	}
54  
55  	/***
56  	 * Add a player/card to the targeted list <br>
57  	 * If the current target options indicates that an event has to be generated
58  	 * when a target is choosen, the event Targeted is dispatched.
59  	 * 
60  	 * @param eventOption
61  	 *          is the event mode : Force, default, none. Depending this value,
62  	 *          the added target will be rechecked before resolution process
63  	 * @param targeted
64  	 *          the player to add to the list
65  	 * @param test
66  	 *          is the used filter. All objects making false this test are removed
67  	 *          from the specified list and from the constraint really targeted
68  	 *          list.
69  	 * @param raiseEvent
70  	 *          if false, is any case, no event can be triggered.
71  	 */
72  	public void addTarget(int eventOption, Targetable targeted, Test test,
73  			boolean raiseEvent) {
74  		if (list.contains(targeted)) {
75  			Log.warn("The target " + targeted + " is already in the target list");
76  		}
77  		list.add(targeted);
78  		if (eventOption != IdTargets.RAISE_EVENT_NOT) {
79  			// we mark this target as really targeted
80  			if (reallyTargeted == null) {
81  				reallyTargeted = new ArrayList<Targetable>();
82  				reallyTargetedTest = new ArrayList<Test>();
83  			}
84  			reallyTargeted.add(targeted);
85  			reallyTargetedTest.add(test);
86  			if (raiseEvent) {
87  				Targeted.dispatchEvent(source.getCard(), targeted);
88  			}
89  		}
90  	}
91  
92  	/***
93  	 * Return the target placed at index
94  	 * 
95  	 * @param index
96  	 *          the target register to extract from the list
97  	 * @return the target placed at index
98  	 */
99  	public Targetable get(int index) {
100 		return list.get(index);
101 	}
102 
103 	/***
104 	 * Return the last target
105 	 * 
106 	 * @return the last target
107 	 */
108 	public Targetable getLast() {
109 		return get(size() - 1);
110 	}
111 
112 	/***
113 	 * Return the first target
114 	 * 
115 	 * @return the first target
116 	 */
117 	public Targetable getFirst() {
118 		return get(0);
119 	}
120 
121 	/***
122 	 * Remove the last target
123 	 */
124 	public void removeLast() {
125 		remove(size() - 1);
126 	}
127 
128 	/***
129 	 * Return a target from the list
130 	 * 
131 	 * @param index
132 	 *          the index of the element to be removed.
133 	 */
134 	public void remove(int index) {
135 		if (reallyTargeted != null) {
136 			Targetable removed = list.remove(index);
137 			final int indexOf = reallyTargeted.indexOf(removed);
138 			if (indexOf != -1) {
139 				reallyTargeted.remove(indexOf);
140 				reallyTargetedTest.remove(indexOf);
141 			}
142 		} else {
143 			list.remove(index);
144 		}
145 	}
146 
147 	/***
148 	 * Return the specified target from the list
149 	 * 
150 	 * @param target
151 	 *          the target to be removed.
152 	 */
153 	public void remove(Targetable target) {
154 		list.remove(target);
155 		if (reallyTargeted != null) {
156 			final int indexOf = reallyTargeted.indexOf(target);
157 			if (indexOf != -1) {
158 				reallyTargeted.remove(indexOf);
159 				reallyTargetedTest.remove(indexOf);
160 			}
161 		}
162 	}
163 
164 	/***
165 	 * Return the specified target from the list
166 	 * 
167 	 * @param target
168 	 *          the target to be removed.
169 	 */
170 	public void removeTargeted(Targetable target) {
171 		list.remove(target);
172 		if (reallyTargeted != null) {
173 			final int indexOf = reallyTargeted.lastIndexOf(target);
174 			if (indexOf != -1) {
175 				reallyTargeted.remove(indexOf);
176 				reallyTargetedTest.remove(indexOf);
177 			}
178 		}
179 	}
180 
181 	/***
182 	 * Remove all component but the first.
183 	 */
184 	public void removeQueue() {
185 		for (int i = list.size(); i-- > 1;) {
186 			remove(i);
187 		}
188 	}
189 
190 	/***
191 	 * Remove all component but the last.
192 	 */
193 	public void removeTail() {
194 		for (int i = list.size() - 1; i-- > 0;) {
195 			remove(i);
196 		}
197 	}
198 
199 	/***
200 	 * Indicates if there are targets
201 	 * 
202 	 * @return true if there are targets
203 	 */
204 	public boolean isEmpty() {
205 		return list.isEmpty();
206 	}
207 
208 	/***
209 	 * Retourne la taille de la liste
210 	 * 
211 	 * @return number of targets
212 	 */
213 	public int size() {
214 		return list.size();
215 	}
216 
217 	/***
218 	 * Indicates that we're no longer looking for the targets
219 	 */
220 	public void clear() {
221 		list.clear();
222 		if (reallyTargeted != null) {
223 			reallyTargeted.clear();
224 			reallyTargetedTest.clear();
225 		}
226 	}
227 
228 	/***
229 	 * Recheck the whole list of targets added with raised event.
230 	 * 
231 	 * @param ability
232 	 *          is the ability owning this request. The card component of this
233 	 *          ability should correspond to the card owning this request too.
234 	 * @return the amount of remaining object making true the specified test.
235 	 */
236 	public int recheckList(Ability ability) {
237 		if (reallyTargeted == null || reallyTargeted.size() == 0) {
238 			return 1;
239 		}
240 		for (int i = reallyTargeted.size(); i-- > 0;) {
241 			final Targetable tested = reallyTargeted.get(i);
242 			if (!reallyTargetedTest.get(i).test(ability, tested)) {
243 				// invalid target
244 				list.remove(tested);
245 				reallyTargeted.remove(i);
246 				reallyTargetedTest.remove(i);
247 			}
248 		}
249 		return reallyTargeted.size();
250 	}
251 
252 	/***
253 	 * Return a clone of this list.
254 	 * 
255 	 * @return a clone of this list.
256 	 */
257 	public TargetedList cloneList() {
258 		TargetedList clone = new TargetedList(source);
259 		clone.list = new ArrayList<Targetable>(list);
260 		clone.reallyTargeted = reallyTargeted == null ? null
261 				: new ArrayList<Targetable>(reallyTargeted);
262 		clone.reallyTargetedTest = reallyTargetedTest == null ? null
263 				: new ArrayList<Test>(reallyTargetedTest);
264 		return clone;
265 
266 	}
267 
268 	@Override
269 	public String toString() {
270 		return list.toString();
271 	}
272 
273 	/***
274 	 * represents all targeted card(s) and/or player(s)
275 	 */
276 	public List<Targetable> list = new ArrayList<Targetable>();
277 
278 	/***
279 	 * indicates if currently, all targets have been aborted.
280 	 */
281 	// TODO private boolean allAbortion;
282 	/***
283 	 * Indicates if target was really targeted. Item is null is was not really
284 	 * targeted, non-null otherwise
285 	 */
286 	private List<Targetable> reallyTargeted;
287 
288 	/***
289 	 * Indicates if target was really targeted. Item is null is was not really
290 	 * targeted, non-null otherwise
291 	 */
292 	private List<Test> reallyTargetedTest;
293 
294 	/***
295 	 * Source of this target spell/ability
296 	 */
297 	public Ability source;
298 }