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.test;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.io.Serializable;
25  
26  import net.sf.magicproject.clickable.ability.Ability;
27  import net.sf.magicproject.clickable.ability.RemoveModifier;
28  import net.sf.magicproject.clickable.ability.TriggeredAbility;
29  import net.sf.magicproject.clickable.targetable.Targetable;
30  import net.sf.magicproject.clickable.targetable.card.MCard;
31  import net.sf.magicproject.clickable.targetable.card.SystemCard;
32  import net.sf.magicproject.clickable.targetable.player.Player;
33  import net.sf.magicproject.event.context.ContextEventListener;
34  import net.sf.magicproject.event.context.MContextCardCardIntInt;
35  import net.sf.magicproject.event.context.MContextMtargetable;
36  import net.sf.magicproject.stack.StackManager;
37  
38  /***
39   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
40   */
41  public enum TestOn implements Serializable {
42  
43  	/***
44  	 * The card to use for the test with 'attachedto' is the card the card owning
45  	 * the test is attached to.
46  	 */
47  	ATTACHED_TO("attachedto"),
48  
49  	/***
50  	 * The controller of 'attachedto' to.
51  	 */
52  	ATTACHED_TO_CONTROLLER("attachedto.controller"),
53  
54  	/***
55  	 * The owner of 'attachedto' to.
56  	 */
57  	ATTACHED_TO_OWNER("attachedto.owner"),
58  
59  	/***
60  	 * The card to use for the test with 'tested.attachedto' is the card the
61  	 * 'tested' card is attached to.
62  	 */
63  	ATTACHED_TO_OF_TESTED("tested.attachedto"),
64  
65  	/***
66  	 * Player saved in the current context.
67  	 */
68  	CONTEXT_PLAYER("context.player"),
69  
70  	/***
71  	 * Player with id saved in the current context.
72  	 */
73  	CONTEXT_INT("context.int"),
74  
75  	/***
76  	 * Player with id saved in the current context(2).
77  	 */
78  	CONTEXT_INT2("context.int2"),
79  
80  	/***
81  	 * The card to use for the test with 'context.targetable' is the first
82  	 * targetable saved in the context.
83  	 */
84  	CONTEXT_TARGETABLE("context.targetable"),
85  
86  	/***
87  	 * The card to use for the test with 'context.card' is the first card saved in
88  	 * the context.
89  	 */
90  	CONTEXT_CARD1("context.card"),
91  
92  	/***
93  	 * The card to use for the test with 'context.card2' is the second card saved
94  	 * in the context.
95  	 */
96  	CONTEXT_CARD2("context.card2"),
97  
98  	/***
99  	 * The controller of the second card saved in the context.
100 	 */
101 	CONTEXT_CARD2_CONTROLLER("context.card2.controller"),
102 
103 	/***
104 	 * The owner of the second card saved in the context.
105 	 */
106 	CONTEXT_CARD2_OWNER("context.card2.owner"),
107 
108 	/***
109 	 * The controller of the first card saved in the context.
110 	 */
111 	CONTEXT_CARD1_CONTROLLER("context.card.controller"),
112 
113 	/***
114 	 * The owner of the first card saved in the context.
115 	 */
116 	CONTEXT_CARD1_OWNER("context.card.owner"),
117 
118 	/***
119 	 * The Targetable cast to MCard object of this context without considering
120 	 * it's timstamp.
121 	 */
122 	CONTEXT_CARD_SHARE("context.card-share"),
123 
124 	/***
125 	 * The controller.
126 	 */
127 	CONTROLLER("controller"),
128 
129 	/***
130 	 * The creator of the current card.
131 	 */
132 	CREATOR("creator"),
133 
134 	/***
135 	 * The active card in the stack owning the current spell or ability. This
136 	 * should be used within a pre-condition of event.
137 	 */
138 	CURRENT_CARD("currentcard"),
139 
140 	/***
141 	 * Current player
142 	 */
143 	CURRENT_PLAYER("currentplayer"),
144 
145 	/***
146 	 * Current player's opponent
147 	 */
148 	CURRENT_PLAYER_OPPONENT("currentplayer.opponent"),
149 
150 	/***
151 	 * The card to use for the test with 'context.event-source' is the source of
152 	 * current event.
153 	 */
154 	EVENT_SOURCE("context.event-source"),
155 
156 	/***
157 	 * The card to use for the test with 'target-list.first' is the first card of
158 	 * the target list.
159 	 */
160 	FIRST_TARGET("target-list.first"),
161 
162 	/***
163 	 * The card to use for the test with 'target-list.first.attachedto' is the
164 	 * first card of the target list.
165 	 */
166 	FIRST_TARGET_ATTACHED_TO("target-list.first.attachedto"),
167 
168 	/***
169 	 * The card to use for the test with 'target-list.first.attachedto.owner' is
170 	 * the first card of the target list.
171 	 */
172 	FIRST_TARGET_ATTACHED_TO_OWNER("target-list.first.attachedto.owner"),
173 
174 	/***
175 	 * The card to use for the test with 'target-list.first.attachedto.controller'
176 	 * is the first card of the target list.
177 	 */
178 	FIRST_TARGET_ATTACHED_TO_CONTROLLER("target-list.first.attachedto.controller"),
179 
180 	/***
181 	 * The card to use for the test with 'target-list.first.controller' is the
182 	 * first card of the target list.
183 	 */
184 	FIRST_TARGET_CONTROLLER("target-list.first.controller"),
185 
186 	/***
187 	 * The card to use for the test with 'target-list.first.owner' is the first
188 	 * card of the target list.
189 	 */
190 	FIRST_TARGET_OWNER("target-list.first.owner"),
191 
192 	/***
193 	 * The card to use for the test with 'target-list.last' is the last card of
194 	 * the target list.
195 	 */
196 	LAST_TARGET("target-list.last"),
197 
198 	/***
199 	 * The card to use for the test with 'target-list.last.attachedto' is the last
200 	 * card of the target list.
201 	 */
202 	LAST_TARGET_ATTACHED_TO("target-list.last.attachedto"),
203 
204 	/***
205 	 * The card to use for the test with 'target-list.last.attachedto.owner' is
206 	 * the last card of the target list.
207 	 */
208 	LAST_TARGET_ATTACHED_TO_OWNER("target-list.last.attachedto.owner"),
209 
210 	/***
211 	 * The card to use for the test with 'target-list.last.attachedto.controller'
212 	 * is the last card of the target list.
213 	 */
214 	LAST_TARGET_ATTACHED_TO_CONTROLLER("target-list.last.attachedto.controller"),
215 
216 	/***
217 	 * The card to use for the test with 'target-list.last.controller' is the last
218 	 * card of the target list.
219 	 */
220 	LAST_TARGET_CONTROLLER("target-list.last.controller"),
221 
222 	/***
223 	 * The card to use for the test with 'target-list.last.owner' is the last card
224 	 * of the target list.
225 	 */
226 	LAST_TARGET_OWNER("target-list.last.owner"),
227 
228 	/***
229 	 * The modifier creator card (may be different from THIS).
230 	 */
231 	MODIFIER_CREATOR("modifier.creator"),
232 
233 	/***
234 	 * The modifier creator card (may be different from CONTROLLER).
235 	 */
236 	MODIFIER_CREATOR_CONTROLLER("modifier.creator.controller"),
237 
238 	/***
239 	 * The modifier creator card (may be different from OWNER).
240 	 */
241 	MODIFIER_CREATOR_OWNER("modifier.creator.owner"),
242 
243 	/***
244 	 * The opponent.
245 	 */
246 	OPPONENT("opponent"),
247 
248 	/***
249 	 * The card's owner.
250 	 */
251 	OWNER("owner"),
252 
253 	/***
254 	 * Saved component
255 	 */
256 	SAVED("saved"),
257 
258 	/***
259 	 * Saved component(2)
260 	 */
261 	SAVED2("saved2"),
262 
263 	/***
264 	 * Controller of saved component
265 	 */
266 	SAVED_CONTROLLER("saved.controller"),
267 
268 	/***
269 	 * Owner of saved component
270 	 */
271 	SAVED_OWNER("saved.owner"),
272 
273 	/***
274 	 * Controller of saved component(2)
275 	 */
276 	SAVED2_CONTROLLER("saved2.controller"),
277 
278 	/***
279 	 * Owner of saved component(2)
280 	 */
281 	SAVED2_OWNER("saved2.controller"),
282 
283 	/***
284 	 * The card to use for the test with 'super.tested' is like 'tested' it's the
285 	 * tested card outside the current 'counter' block.
286 	 */
287 	SUPER("super.tested"),
288 
289 	/***
290 	 * The current card's controller. May be different from the controller of
291 	 * current ability.
292 	 */
293 	TARGET_CONTROLLER("target.controller"),
294 
295 	/***
296 	 * The current card's owner. May be different from the owner of current
297 	 * ability.
298 	 */
299 	TARGET_OWNER("target.owner"),
300 
301 	/***
302 	 * The card to use for the test with 'tested' is the current tested card. It's
303 	 * the tested card for counter, or the main card of an event.
304 	 */
305 	TESTED("tested"),
306 
307 	/***
308 	 * The card to use for the test with 'me', 'myself' is the card owning the
309 	 * test.
310 	 */
311 	THIS("this"),
312 
313 	/***
314 	 * The controller of current ability. May be a bit different from card's
315 	 * 'controller'
316 	 */
317 	YOU("you");
318 
319 	private final String xsdName;
320 
321 	private TestOn(String xsdName) {
322 		this.xsdName = xsdName;
323 	}
324 
325 	/***
326 	 * Return the targetable on which the test would be applied
327 	 * 
328 	 * @param ability
329 	 *          is the ability owning this test. The card component of this
330 	 *          ability should correspond to the card owning this test too.
331 	 * @param tested
332 	 *          the tested targetable
333 	 * @return the targetable to use for the test
334 	 */
335 	public Targetable getTargetable(Ability ability, Targetable tested) {
336 		return getTargetable(ability, null, tested);
337 	}
338 
339 	/***
340 	 * Return the targetable on which the test would be applied
341 	 * 
342 	 * @param ability
343 	 *          is the ability owning this test. The card component of this
344 	 *          ability should correspond to the card owning this test too.
345 	 * @param tested
346 	 *          the tested targetable
347 	 * @return the targetable to use for the test
348 	 */
349 	public Player getPlayer(Ability ability, Targetable tested) {
350 		return (Player) getTargetable(ability, null, tested);
351 	}
352 
353 	/***
354 	 * Return the targetable on which the test would be applied
355 	 * 
356 	 * @param ability
357 	 *          is the ability owning this test. The card component of this
358 	 *          ability should correspond to the card owning this test too.
359 	 * @param context
360 	 *          the current context.
361 	 * @param tested
362 	 *          the tested targetable
363 	 * @return the targetable to use for the test
364 	 */
365 	public Targetable getTargetable(Ability ability,
366 			ContextEventListener context, Targetable tested) {
367 		if (ability == null)
368 			return getTargetable(null, SystemCard.instance, context, tested);
369 		return getTargetable(ability, ability.getCard(), context, tested);
370 	}
371 
372 	/***
373 	 * Return the targetable on which the test would be applied
374 	 * 
375 	 * @param ability
376 	 *          is the ability owning this test. The card component of this
377 	 *          ability should correspond to the card owning this test too.
378 	 * @param context
379 	 *          the current context.
380 	 * @param tested
381 	 *          the tested targetable
382 	 * @return the targetable to use for the test
383 	 */
384 	public Player getPlayer(Ability ability, ContextEventListener context,
385 			Targetable tested) {
386 		return (Player) getTargetable(ability, context, tested);
387 	}
388 
389 	/***
390 	 * Return the targetable on which the test would be applied
391 	 * 
392 	 * @param ability
393 	 *          is the ability owning this test. The card component of this
394 	 *          ability should correspond to the card owning this test too.
395 	 * @param card
396 	 *          is the card owning the current ability.
397 	 * @param context
398 	 *          the current context.
399 	 * @param tested
400 	 *          the tested targetable
401 	 * @return the targetable to use for the test
402 	 */
403 	public Targetable getTargetable(Ability ability, MCard card,
404 			ContextEventListener context, Targetable tested) {
405 		switch (this) {
406 		case ATTACHED_TO:
407 			if (card.getParent() instanceof MCard) {
408 				return (MCard) card.getParent();
409 			}
410 			return SystemCard.instance;
411 		case ATTACHED_TO_CONTROLLER:
412 			if (card.getParent() instanceof MCard) {
413 				return ((MCard) card.getParent()).controller;
414 			}
415 			return SystemCard.instance;
416 		case ATTACHED_TO_OWNER:
417 			if (card.getParent() instanceof MCard) {
418 				return ((MCard) card.getParent()).getOwner();
419 			}
420 			return SystemCard.instance;
421 		case ATTACHED_TO_OF_TESTED:
422 			if (tested instanceof MCard && tested.getParent() instanceof MCard) {
423 				return (MCard) tested.getParent();
424 			}
425 			return null;
426 		case CURRENT_PLAYER:
427 			return StackManager.currentPlayer();
428 		case CURRENT_PLAYER_OPPONENT:
429 			return StackManager.currentPlayer().getOpponent();
430 		case CURRENT_CARD:
431 			return StackManager.getInstance().getSourceCard();
432 		case CONTEXT_INT:
433 			return StackManager.PLAYERS[((MContextCardCardIntInt) getContext(context))
434 					.getValue()];
435 		case CONTEXT_INT2:
436 			return StackManager.PLAYERS[((MContextCardCardIntInt) getContext(context))
437 					.getValue2()];
438 		case CONTEXT_TARGETABLE:
439 		case CONTEXT_PLAYER:
440 		case CONTEXT_CARD1:
441 			return ((MContextMtargetable) getContext(context)).getTargetable();
442 		case CONTEXT_CARD2:
443 			return ((MContextCardCardIntInt) getContext(context)).getCard2();
444 		case CONTEXT_CARD1_CONTROLLER:
445 			return ((MContextMtargetable) getContext(context)).getCard()
446 					.getController();
447 		case CONTEXT_CARD2_CONTROLLER:
448 			return ((MContextCardCardIntInt) getContext(context)).getCard2()
449 					.getController();
450 		case CONTEXT_CARD1_OWNER:
451 			return ((MContextMtargetable) getContext(context)).getCard().getOwner();
452 		case CONTEXT_CARD2_OWNER:
453 			return ((MContextCardCardIntInt) getContext(context)).getCard2()
454 					.getOwner();
455 		case CONTEXT_CARD_SHARE:
456 			return ((MContextMtargetable) getContext(context)).getOriginalCard();
457 		case EVENT_SOURCE:
458 			return getContext(context).getEventSource();
459 		case CREATOR:
460 			return card.getCreator();
461 		case FIRST_TARGET:
462 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
463 				return null;
464 			}
465 			return StackManager.getInstance().getTargetedList().getFirst();
466 		case FIRST_TARGET_CONTROLLER:
467 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
468 				return null;
469 			}
470 			return ((MCard) StackManager.getInstance().getTargetedList().getFirst())
471 					.getController();
472 		case FIRST_TARGET_OWNER:
473 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
474 				return null;
475 			}
476 			return ((MCard) StackManager.getInstance().getTargetedList().getFirst())
477 					.getOwner();
478 		case FIRST_TARGET_ATTACHED_TO:
479 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
480 				return null;
481 			}
482 			return (MCard) ((MCard) StackManager.getInstance().getTargetedList()
483 					.getFirst()).getParent();
484 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
485 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
486 				return null;
487 			}
488 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
489 					.getFirst()).getParent()).getController();
490 		case FIRST_TARGET_ATTACHED_TO_OWNER:
491 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
492 				return null;
493 			}
494 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
495 					.getFirst()).getParent()).getOwner();
496 		case LAST_TARGET:
497 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
498 				return null;
499 			}
500 			return StackManager.getInstance().getTargetedList().getLast();
501 		case LAST_TARGET_CONTROLLER:
502 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
503 				return null;
504 			}
505 			return ((MCard) StackManager.getInstance().getTargetedList().getLast())
506 					.getController();
507 		case LAST_TARGET_OWNER:
508 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
509 				return null;
510 			}
511 			return ((MCard) StackManager.getInstance().getTargetedList().getLast())
512 					.getOwner();
513 		case LAST_TARGET_ATTACHED_TO:
514 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
515 				return null;
516 			}
517 			return (MCard) ((MCard) StackManager.getInstance().getTargetedList()
518 					.getLast()).getParent();
519 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
520 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
521 				return null;
522 			}
523 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
524 					.getLast()).getParent()).getController();
525 		case LAST_TARGET_ATTACHED_TO_OWNER:
526 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
527 				return null;
528 			}
529 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
530 					.getLast()).getParent()).getOwner();
531 		case MODIFIER_CREATOR:
532 			if (ability instanceof RemoveModifier) {
533 				return ((RemoveModifier) ability).modifier.getCard();
534 			}
535 			return ability.getCard();
536 		case MODIFIER_CREATOR_CONTROLLER:
537 			if (ability instanceof RemoveModifier) {
538 				return ((RemoveModifier) ability).modifier.getCard().getController();
539 			}
540 			return ability.getCard().getController();
541 		case MODIFIER_CREATOR_OWNER:
542 			if (ability instanceof RemoveModifier) {
543 				return ((RemoveModifier) ability).modifier.getCard().getOwner();
544 			}
545 			return ability.getCard().getOwner();
546 		case OWNER:
547 			return card.getOwner();
548 		case OPPONENT:
549 			return card.getController().getOpponent();
550 		case SAVED:
551 			return ((TriggeredAbility) ability).getDelayedCard().saved;
552 		case SAVED2:
553 			return ((TriggeredAbility) ability).getDelayedCard().saved2;
554 		case SAVED_CONTROLLER:
555 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved)
556 					.getController();
557 		case SAVED2_CONTROLLER:
558 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved2)
559 					.getController();
560 		case SAVED_OWNER:
561 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved)
562 					.getOwner();
563 		case SAVED2_OWNER:
564 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved2)
565 					.getOwner();
566 		case SUPER:
567 			if (net.sf.magicproject.expression.Counter.superTested != null) {
568 				return net.sf.magicproject.expression.Counter.superTested;
569 			}
570 			return tested;
571 		case TARGET_CONTROLLER:
572 			return card.getController();
573 		case TARGET_OWNER:
574 			return card.getOwner();
575 		case TESTED:
576 			if (tested == null) {
577 				throw new InternalError("The tested card is null");
578 			}
579 			return tested;
580 		case THIS:
581 			return card;
582 		case YOU:
583 			if (ability != null && ability.getCard() != SystemCard.instance)
584 				return ability.getCard().getController();
585 			return card.getController();
586 		case CONTROLLER:
587 			return card.getController();
588 		default:
589 			return null;
590 		}
591 	}
592 
593 	/***
594 	 * Return the given context if not null. Returns the context of current
595 	 * ability otherwise.
596 	 * 
597 	 * @param currentContext
598 	 *          the known context.
599 	 * @return the given context if not null. Returns the context of current
600 	 *         ability otherwise.
601 	 */
602 	private ContextEventListener getContext(ContextEventListener currentContext) {
603 		if (currentContext == null)
604 			return StackManager.getInstance().getAbilityContext();
605 		return currentContext;
606 	}
607 
608 	/***
609 	 * Return the targetable instance cast in Card instance.
610 	 * 
611 	 * @param ability
612 	 *          is the ability owning this test. The card component of this
613 	 *          ability should correspond to the card owning this test too.
614 	 * @param tested
615 	 *          the tested targetable
616 	 * @return the card to use for the test
617 	 */
618 	public MCard getCard(Ability ability, Targetable tested) {
619 		return getCard(ability, null, tested);
620 	}
621 
622 	/***
623 	 * Return the targetable instance cast in Card instance.
624 	 * 
625 	 * @param ability
626 	 *          is the ability owning this test. The card component of this
627 	 *          ability should correspond to the card owning this test too.
628 	 * @param context
629 	 *          the current context.
630 	 * @param tested
631 	 *          the tested targetable
632 	 * @return the card to use for the test
633 	 */
634 	public MCard getCard(Ability ability, ContextEventListener context,
635 			Targetable tested) {
636 		return (MCard) getTargetable(ability, context, tested);
637 	}
638 
639 	/***
640 	 * Is this always referring to a card.
641 	 * 
642 	 * @return true if this is always referring to a card.
643 	 */
644 	public boolean isCard() {
645 		switch (this) {
646 		case ATTACHED_TO:
647 		case ATTACHED_TO_OF_TESTED:
648 		case CURRENT_CARD:
649 		case CONTEXT_CARD1:
650 		case CONTEXT_CARD2:
651 		case CONTEXT_CARD_SHARE:
652 		case EVENT_SOURCE:
653 		case CREATOR:
654 		case FIRST_TARGET_ATTACHED_TO:
655 		case LAST_TARGET_ATTACHED_TO:
656 		case THIS:
657 			return true;
658 		default:
659 			return false;
660 		}
661 	}
662 
663 	/***
664 	 * Is this always referring to a player.
665 	 * 
666 	 * @return true if this is always referring to a player.
667 	 */
668 	public boolean isPlayer() {
669 		switch (this) {
670 		case FIRST_TARGET_CONTROLLER:
671 		case FIRST_TARGET_OWNER:
672 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
673 		case FIRST_TARGET_ATTACHED_TO_OWNER:
674 		case LAST_TARGET_CONTROLLER:
675 		case LAST_TARGET_OWNER:
676 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
677 		case LAST_TARGET_ATTACHED_TO_OWNER:
678 		case ATTACHED_TO_CONTROLLER:
679 		case ATTACHED_TO_OWNER:
680 		case CURRENT_PLAYER:
681 		case CURRENT_PLAYER_OPPONENT:
682 		case CONTEXT_PLAYER:
683 		case CONTEXT_CARD1_CONTROLLER:
684 		case CONTEXT_CARD2_CONTROLLER:
685 		case CONTEXT_CARD1_OWNER:
686 		case CONTEXT_CARD2_OWNER:
687 		case OWNER:
688 		case OPPONENT:
689 		case SAVED_CONTROLLER:
690 		case SAVED2_CONTROLLER:
691 		case SAVED_OWNER:
692 		case SAVED2_OWNER:
693 		case TARGET_CONTROLLER:
694 		case TARGET_OWNER:
695 		case YOU:
696 		case CONTROLLER:
697 			return true;
698 		default:
699 			return false;
700 		}
701 	}
702 
703 	/***
704 	 * Return true if the associated value can be evaluated without ability
705 	 * context.
706 	 * 
707 	 * @return true if the associated value can be evaluated without ability
708 	 *         context.
709 	 */
710 	public boolean canBePreempted() {
711 		switch (this) {
712 		case FIRST_TARGET_ATTACHED_TO:
713 		case LAST_TARGET_ATTACHED_TO:
714 		case FIRST_TARGET:
715 		case FIRST_TARGET_CONTROLLER:
716 		case FIRST_TARGET_OWNER:
717 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
718 		case FIRST_TARGET_ATTACHED_TO_OWNER:
719 		case LAST_TARGET:
720 		case LAST_TARGET_CONTROLLER:
721 		case LAST_TARGET_OWNER:
722 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
723 		case LAST_TARGET_ATTACHED_TO_OWNER:
724 			return false;
725 		default:
726 			return true;
727 		}
728 	}
729 
730 	/***
731 	 * Return the value corresponding to the true register index exactly as it
732 	 * will be when the ability will be executed. return the real number of a
733 	 * specifid idNumber. Since this number may reference to a token, a code
734 	 * matching is ran to determine which is the associated value.
735 	 * 
736 	 * @param ability
737 	 *          is the ability owning this test. The card component of this
738 	 *          ability should correspond to the card owning this test too.
739 	 * @param index
740 	 *          is the number where the real value will be extracted
741 	 * @return the real number associated to the specified idNumber
742 	 */
743 	public int getPreemptedValue(Ability ability, int index) {
744 		if (canBePreempted()) {
745 			return getTargetable(ability, null).getValue(index);
746 		}
747 		return -1;
748 	}
749 
750 	/***
751 	 * Write this enum to the given outputstream.
752 	 * 
753 	 * @param out
754 	 *          the stream ths enum would be written.
755 	 * @param xsdName
756 	 *          the Xsd name of this TestOn.
757 	 * @throws IOException
758 	 *           If some other I/O error occurs
759 	 */
760 	public static void serialize(OutputStream out, String xsdName)
761 			throws IOException {
762 		for (TestOn testOn : values())
763 			if (testOn.xsdName.equals(xsdName)) {
764 				testOn.serialize(out);
765 				return;
766 			}
767 		throw new IllegalArgumentException("Invalid xsd attribute name : "
768 				+ xsdName);
769 	}
770 
771 	/***
772 	 * Return null of enum value corresponding to the given Xsd name.
773 	 * 
774 	 * @param xsdName
775 	 *          the Xsd name of this TestOn.
776 	 * @return null of enum value corresponding to the given Xsd name.
777 	 */
778 	public static TestOn valueOfXsd(String xsdName) {
779 		for (TestOn value : values()) {
780 			if (value.xsdName.equals(xsdName)) {
781 				return value;
782 			}
783 		}
784 		return null;
785 	}
786 
787 	/***
788 	 * Write this enum to the given outputstream.
789 	 * 
790 	 * @param out
791 	 *          the stream ths enum would be written.
792 	 * @throws IOException
793 	 *           If some other I/O error occurs
794 	 */
795 	public void serialize(OutputStream out) throws IOException {
796 		out.write(ordinal());
797 	}
798 
799 	/***
800 	 * Read and return the enum from the given inputstream.
801 	 * 
802 	 * @param input
803 	 *          the stream containing the enum to read.
804 	 * @return the enum from the given inputstream.
805 	 * @throws IOException
806 	 *           If some other I/O error occurs
807 	 */
808 	public static TestOn deserialize(InputStream input) throws IOException {
809 		return values()[input.read()];
810 	}
811 
812 	/***
813 	 * Return the HTML code representing this action. If no picture is associated
814 	 * to this action, only text will be returned.
815 	 * 
816 	 * @param ability
817 	 *          is the ability owning this test. The card component of this
818 	 *          ability should correspond to the card owning this test too.
819 	 * @param context
820 	 *          is the context attached to this action.
821 	 * @return the HTML code representing this action. If no picture is associated
822 	 *         to this action, only text will be returned.
823 	 */
824 	public String toHtmlString(Ability ability, ContextEventListener context) {
825 		switch (this) {
826 		case THIS:
827 			return null;
828 		default:
829 			return toString().toLowerCase();
830 		}
831 	}
832 
833 }