View Javadoc

1   /*
2    *   Firemox 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.firemox.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.firemox.clickable.ability.Ability;
27  import net.sf.firemox.clickable.ability.RemoveModifier;
28  import net.sf.firemox.clickable.ability.TriggeredAbility;
29  import net.sf.firemox.clickable.target.Target;
30  import net.sf.firemox.clickable.target.card.MCard;
31  import net.sf.firemox.clickable.target.card.SystemCard;
32  import net.sf.firemox.clickable.target.player.Player;
33  import net.sf.firemox.event.context.ContextEventListener;
34  import net.sf.firemox.event.context.MContextCardCardIntInt;
35  import net.sf.firemox.event.context.MContextTarget;
36  import net.sf.firemox.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.target' is the first target
82  	 * saved in the context.
83  	 */
84  	CONTEXT_TARGETABLE("context.target"),
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 target 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 target
333 	 * @return the target to use for the test
334 	 */
335 	public Target getTargetable(Ability ability, Target tested) {
336 		return getTargetable(ability, null, tested);
337 	}
338 
339 	/***
340 	 * Return the target 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 target
347 	 * @return the target to use for the test
348 	 */
349 	public Player getPlayer(Ability ability, Target tested) {
350 		return (Player) getTargetable(ability, null, tested);
351 	}
352 
353 	/***
354 	 * Return the target 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 target
363 	 * @return the target to use for the test
364 	 */
365 	public Target getTargetable(Ability ability, ContextEventListener context,
366 			Target 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 target 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 target
382 	 * @return the target to use for the test
383 	 */
384 	public Player getPlayer(Ability ability, ContextEventListener context,
385 			Target tested) {
386 		return (Player) getTargetable(ability, context, tested);
387 	}
388 
389 	/***
390 	 * Return the target 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 target
401 	 * @return the target to use for the test
402 	 */
403 	public Target getTargetable(Ability ability, MCard card,
404 			ContextEventListener context, Target 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 ((MContextTarget) getContext(context)).getTargetable();
442 		case CONTEXT_CARD2:
443 			return ((MContextCardCardIntInt) getContext(context)).getCard2();
444 		case CONTEXT_CARD1_CONTROLLER:
445 			return ((MContextTarget) getContext(context)).getCard().getController();
446 		case CONTEXT_CARD2_CONTROLLER:
447 			return ((MContextCardCardIntInt) getContext(context)).getCard2()
448 					.getController();
449 		case CONTEXT_CARD1_OWNER:
450 			return ((MContextTarget) getContext(context)).getCard().getOwner();
451 		case CONTEXT_CARD2_OWNER:
452 			return ((MContextCardCardIntInt) getContext(context)).getCard2()
453 					.getOwner();
454 		case CONTEXT_CARD_SHARE:
455 			return ((MContextTarget) getContext(context)).getOriginalCard();
456 		case EVENT_SOURCE:
457 			return getContext(context).getEventSource();
458 		case CREATOR:
459 			return card.getCreator();
460 		case FIRST_TARGET:
461 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
462 				return null;
463 			}
464 			return StackManager.getInstance().getTargetedList().getFirst();
465 		case FIRST_TARGET_CONTROLLER:
466 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
467 				return null;
468 			}
469 			return ((MCard) StackManager.getInstance().getTargetedList().getFirst())
470 					.getController();
471 		case FIRST_TARGET_OWNER:
472 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
473 				return null;
474 			}
475 			return ((MCard) StackManager.getInstance().getTargetedList().getFirst())
476 					.getOwner();
477 		case FIRST_TARGET_ATTACHED_TO:
478 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
479 				return null;
480 			}
481 			return (MCard) ((MCard) StackManager.getInstance().getTargetedList()
482 					.getFirst()).getParent();
483 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
484 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
485 				return null;
486 			}
487 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
488 					.getFirst()).getParent()).getController();
489 		case FIRST_TARGET_ATTACHED_TO_OWNER:
490 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
491 				return null;
492 			}
493 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
494 					.getFirst()).getParent()).getOwner();
495 		case LAST_TARGET:
496 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
497 				return null;
498 			}
499 			return StackManager.getInstance().getTargetedList().getLast();
500 		case LAST_TARGET_CONTROLLER:
501 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
502 				return null;
503 			}
504 			return ((MCard) StackManager.getInstance().getTargetedList().getLast())
505 					.getController();
506 		case LAST_TARGET_OWNER:
507 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
508 				return null;
509 			}
510 			return ((MCard) StackManager.getInstance().getTargetedList().getLast())
511 					.getOwner();
512 		case LAST_TARGET_ATTACHED_TO:
513 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
514 				return null;
515 			}
516 			return (MCard) ((MCard) StackManager.getInstance().getTargetedList()
517 					.getLast()).getParent();
518 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
519 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
520 				return null;
521 			}
522 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
523 					.getLast()).getParent()).getController();
524 		case LAST_TARGET_ATTACHED_TO_OWNER:
525 			if (StackManager.getInstance().getTargetedList().isEmpty()) {
526 				return null;
527 			}
528 			return ((MCard) ((MCard) StackManager.getInstance().getTargetedList()
529 					.getLast()).getParent()).getOwner();
530 		case MODIFIER_CREATOR:
531 			if (ability instanceof RemoveModifier) {
532 				return ((RemoveModifier) ability).modifier.getCard();
533 			}
534 			return ability.getCard();
535 		case MODIFIER_CREATOR_CONTROLLER:
536 			if (ability instanceof RemoveModifier) {
537 				return ((RemoveModifier) ability).modifier.getCard().getController();
538 			}
539 			return ability.getCard().getController();
540 		case MODIFIER_CREATOR_OWNER:
541 			if (ability instanceof RemoveModifier) {
542 				return ((RemoveModifier) ability).modifier.getCard().getOwner();
543 			}
544 			return ability.getCard().getOwner();
545 		case OWNER:
546 			return card.getOwner();
547 		case OPPONENT:
548 			return card.getController().getOpponent();
549 		case SAVED:
550 			return ((TriggeredAbility) ability).getDelayedCard().saved;
551 		case SAVED2:
552 			return ((TriggeredAbility) ability).getDelayedCard().saved2;
553 		case SAVED_CONTROLLER:
554 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved)
555 					.getController();
556 		case SAVED2_CONTROLLER:
557 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved2)
558 					.getController();
559 		case SAVED_OWNER:
560 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved)
561 					.getOwner();
562 		case SAVED2_OWNER:
563 			return ((MCard) ((TriggeredAbility) ability).getDelayedCard().saved2)
564 					.getOwner();
565 		case SUPER:
566 			if (net.sf.firemox.expression.Counter.superTested != null) {
567 				return net.sf.firemox.expression.Counter.superTested;
568 			}
569 			return tested;
570 		case TARGET_CONTROLLER:
571 			return card.getController();
572 		case TARGET_OWNER:
573 			return card.getOwner();
574 		case TESTED:
575 			if (tested == null) {
576 				throw new InternalError("The tested card is null");
577 			}
578 			return tested;
579 		case THIS:
580 			return card;
581 		case YOU:
582 			if (ability != null && ability.getCard() != SystemCard.instance)
583 				return ability.getCard().getController();
584 			return card.getController();
585 		case CONTROLLER:
586 			return card.getController();
587 		default:
588 			return null;
589 		}
590 	}
591 
592 	/***
593 	 * Return the given context if not null. Returns the context of current
594 	 * ability otherwise.
595 	 * 
596 	 * @param currentContext
597 	 *          the known context.
598 	 * @return the given context if not null. Returns the context of current
599 	 *         ability otherwise.
600 	 */
601 	private ContextEventListener getContext(ContextEventListener currentContext) {
602 		if (currentContext == null)
603 			return StackManager.getInstance().getAbilityContext();
604 		return currentContext;
605 	}
606 
607 	/***
608 	 * Return the target instance cast in Card instance.
609 	 * 
610 	 * @param ability
611 	 *          is the ability owning this test. The card component of this
612 	 *          ability should correspond to the card owning this test too.
613 	 * @param tested
614 	 *          the tested target
615 	 * @return the card to use for the test
616 	 */
617 	public MCard getCard(Ability ability, Target tested) {
618 		return getCard(ability, null, tested);
619 	}
620 
621 	/***
622 	 * Return the target instance cast in Card instance.
623 	 * 
624 	 * @param ability
625 	 *          is the ability owning this test. The card component of this
626 	 *          ability should correspond to the card owning this test too.
627 	 * @param context
628 	 *          the current context.
629 	 * @param tested
630 	 *          the tested target
631 	 * @return the card to use for the test
632 	 */
633 	public MCard getCard(Ability ability, ContextEventListener context,
634 			Target tested) {
635 		return (MCard) getTargetable(ability, context, tested);
636 	}
637 
638 	/***
639 	 * Is this always referring to a card.
640 	 * 
641 	 * @return true if this is always referring to a card.
642 	 */
643 	public boolean isCard() {
644 		switch (this) {
645 		case ATTACHED_TO:
646 		case ATTACHED_TO_OF_TESTED:
647 		case CURRENT_CARD:
648 		case CONTEXT_CARD1:
649 		case CONTEXT_CARD2:
650 		case CONTEXT_CARD_SHARE:
651 		case EVENT_SOURCE:
652 		case CREATOR:
653 		case FIRST_TARGET_ATTACHED_TO:
654 		case LAST_TARGET_ATTACHED_TO:
655 		case THIS:
656 			return true;
657 		default:
658 			return false;
659 		}
660 	}
661 
662 	/***
663 	 * Is this always referring to a player.
664 	 * 
665 	 * @return true if this is always referring to a player.
666 	 */
667 	public boolean isPlayer() {
668 		switch (this) {
669 		case FIRST_TARGET_CONTROLLER:
670 		case FIRST_TARGET_OWNER:
671 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
672 		case FIRST_TARGET_ATTACHED_TO_OWNER:
673 		case LAST_TARGET_CONTROLLER:
674 		case LAST_TARGET_OWNER:
675 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
676 		case LAST_TARGET_ATTACHED_TO_OWNER:
677 		case ATTACHED_TO_CONTROLLER:
678 		case ATTACHED_TO_OWNER:
679 		case CURRENT_PLAYER:
680 		case CURRENT_PLAYER_OPPONENT:
681 		case CONTEXT_PLAYER:
682 		case CONTEXT_CARD1_CONTROLLER:
683 		case CONTEXT_CARD2_CONTROLLER:
684 		case CONTEXT_CARD1_OWNER:
685 		case CONTEXT_CARD2_OWNER:
686 		case OWNER:
687 		case OPPONENT:
688 		case SAVED_CONTROLLER:
689 		case SAVED2_CONTROLLER:
690 		case SAVED_OWNER:
691 		case SAVED2_OWNER:
692 		case TARGET_CONTROLLER:
693 		case TARGET_OWNER:
694 		case YOU:
695 		case CONTROLLER:
696 			return true;
697 		default:
698 			return false;
699 		}
700 	}
701 
702 	/***
703 	 * Return true if the associated value can be evaluated without ability
704 	 * context.
705 	 * 
706 	 * @return true if the associated value can be evaluated without ability
707 	 *         context.
708 	 */
709 	public boolean canBePreempted() {
710 		switch (this) {
711 		case FIRST_TARGET_ATTACHED_TO:
712 		case LAST_TARGET_ATTACHED_TO:
713 		case FIRST_TARGET:
714 		case FIRST_TARGET_CONTROLLER:
715 		case FIRST_TARGET_OWNER:
716 		case FIRST_TARGET_ATTACHED_TO_CONTROLLER:
717 		case FIRST_TARGET_ATTACHED_TO_OWNER:
718 		case LAST_TARGET:
719 		case LAST_TARGET_CONTROLLER:
720 		case LAST_TARGET_OWNER:
721 		case LAST_TARGET_ATTACHED_TO_CONTROLLER:
722 		case LAST_TARGET_ATTACHED_TO_OWNER:
723 			return false;
724 		default:
725 			return true;
726 		}
727 	}
728 
729 	/***
730 	 * Return the value corresponding to the true register index exactly as it
731 	 * will be when the ability will be executed. return the real number of a
732 	 * specifid idNumber. Since this number may reference to a token, a code
733 	 * matching is ran to determine which is the associated value.
734 	 * 
735 	 * @param ability
736 	 *          is the ability owning this test. The card component of this
737 	 *          ability should correspond to the card owning this test too.
738 	 * @param index
739 	 *          is the number where the real value will be extracted
740 	 * @return the real number associated to the specified idNumber
741 	 */
742 	public int getPreemptedValue(Ability ability, int index) {
743 		if (canBePreempted()) {
744 			return getTargetable(ability, null).getValue(index);
745 		}
746 		return -1;
747 	}
748 
749 	/***
750 	 * Write the enum corresponding to the given xsd name to the given output
751 	 * stream.
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 		final TestOn value = valueOfXsd(xsdName);
763 		if (value == null) {
764 			throw new IllegalArgumentException("Invalid xsd attribute name : "
765 					+ xsdName);
766 		}
767 		value.serialize(out);
768 	}
769 
770 	/***
771 	 * Return null of enum value corresponding to the given Xsd name.
772 	 * 
773 	 * @param xsdName
774 	 *          the Xsd name of this TestOn.
775 	 * @return null of enum value corresponding to the given Xsd name.
776 	 */
777 	public static TestOn valueOfXsd(String xsdName) {
778 		for (TestOn value : values()) {
779 			if (value.xsdName.equals(xsdName)) {
780 				return value;
781 			}
782 		}
783 		return null;
784 	}
785 
786 	/***
787 	 * Write this enum to the given output stream.
788 	 * 
789 	 * @param out
790 	 *          the stream ths enum would be written.
791 	 * @throws IOException
792 	 *           If some other I/O error occurs
793 	 */
794 	public void serialize(OutputStream out) throws IOException {
795 		out.write(ordinal());
796 	}
797 
798 	/***
799 	 * Read and return the enum from the given stream.
800 	 * 
801 	 * @param input
802 	 *          the stream containing the enum to read.
803 	 * @return the enum from the given stream.
804 	 * @throws IOException
805 	 *           If some other I/O error occurs
806 	 */
807 	public static TestOn deserialize(InputStream input) throws IOException {
808 		return values()[input.read()];
809 	}
810 
811 	/***
812 	 * Return the HTML code representing this action. If no picture is associated
813 	 * to this action, only text will be returned.
814 	 * 
815 	 * @param ability
816 	 *          is the ability owning this test. The card component of this
817 	 *          ability should correspond to the card owning this test too.
818 	 * @param context
819 	 *          is the context attached to this action.
820 	 * @return the HTML code representing this action. If no picture is associated
821 	 *         to this action, only text will be returned.
822 	 */
823 	public String toHtmlString(Ability ability, ContextEventListener context) {
824 		switch (this) {
825 		case THIS:
826 			return null;
827 		default:
828 			return toString().toLowerCase();
829 		}
830 	}
831 
832 }