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.clickable.targetable.card;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import net.sf.magicproject.action.MoveCard;
27  import net.sf.magicproject.clickable.ability.Ability;
28  import net.sf.magicproject.clickable.ability.DetachmentAbility;
29  import net.sf.magicproject.clickable.ability.RemoveModifier;
30  import net.sf.magicproject.event.AttachedEvent;
31  import net.sf.magicproject.event.MEventListener;
32  import net.sf.magicproject.event.MovedCard;
33  import net.sf.magicproject.event.context.ContextEventListener;
34  import net.sf.magicproject.modifier.ModifierFactory;
35  import net.sf.magicproject.modifier.ModifierModel;
36  import net.sf.magicproject.test.And;
37  import net.sf.magicproject.test.InZone;
38  import net.sf.magicproject.test.IsTested;
39  import net.sf.magicproject.test.Not;
40  import net.sf.magicproject.test.ReplaceTested;
41  import net.sf.magicproject.test.Test;
42  import net.sf.magicproject.test.TestFactory;
43  import net.sf.magicproject.test.TestOn;
44  import net.sf.magicproject.token.IdPositions;
45  import net.sf.magicproject.token.IdZones;
46  
47  /***
48   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
49   * @since 0.91
50   */
51  public class Attachment {
52  
53  	private final Test validTarget;
54  
55  	private final Test validAttachment;
56  
57  	/***
58  	 * The test making valind the attachment with another component.
59  	 */
60  	private final List<MEventListener> linkedEvents;
61  
62  	/***
63  	 * The modifiers brought by this attachment.
64  	 */
65  	private final ModifierModel[] modifiers;
66  
67  	/***
68  	 * Creates a new instance of AttachList <br>
69  	 * <ul>
70  	 * Structure of stream : Data[size]
71  	 * <li>nb modifiers [1]</li>
72  	 * <li>modifiers [...]</li>
73  	 * <li>test validating the attachment [...]</li>
74  	 * </ul>
75  	 * 
76  	 * @param inputFile
77  	 *          file containing this action
78  	 * @throws IOException
79  	 */
80  	Attachment(InputStream inputFile) throws IOException {
81  		modifiers = new ModifierModel[inputFile.read()];
82  		for (int i = 0; i < modifiers.length; i++) {
83  			modifiers[i] = ModifierFactory.readModifier(inputFile);
84  		}
85  		linkedEvents = new ArrayList<MEventListener>(5);
86  		validTarget = TestFactory.readNextTest(inputFile);
87  		validAttachment = TestFactory.readNextTest(inputFile);
88  		validAttachment.extractTriggeredEvents(linkedEvents, SystemCard.instance,
89  				new Not(new ReplaceTested(TestOn.ATTACHED_TO, validAttachment)));
90  	}
91  
92  	/***
93  	 * Returns the modifiers brought by this attachment.
94  	 * 
95  	 * @return the modifiers brought by this attachment.
96  	 */
97  	public ModifierModel[] getModifiers() {
98  		return modifiers;
99  	}
100 
101 	/***
102 	 * Returns the initial test making valid the attachment with another
103 	 * component.
104 	 * 
105 	 * @return the initial test making valid the attachment with another
106 	 *         component.
107 	 */
108 	public Test getValidTarget() {
109 		return validTarget;
110 	}
111 
112 	/***
113 	 * Returns the test maintening the attachment with another component.
114 	 * 
115 	 * @return the test maintening the attachment with another component.
116 	 */
117 	public Test getValidAttachment() {
118 		return validAttachment;
119 	}
120 
121 	/***
122 	 * @param context
123 	 *          the context of playing ability.
124 	 * @param ability
125 	 *          the playing ability.
126 	 * @param from
127 	 *          the card to attach.
128 	 * @param to
129 	 *          the attchment destination.
130 	 */
131 	public void attach(ContextEventListener context, Ability ability, MCard from,
132 			MCard to) {
133 		AttachedEvent.dispatchEvent(to, from);
134 		MoveCard.moveCard(from, TestOn.CONTROLLER, to.getIdZone()
135 				| (to.tapped ? IdZones.PLAY_TAPPED : 0), null, IdPositions.ON_THE_TOP,
136 				ability,false);
137 		AttachedEvent.dispatchEvent(to, from);
138 
139 		// add the clean up ability to remove abilities during the detachment
140 		for (MEventListener listener : linkedEvents) {
141 			if (from.isAttached()) {
142 				// This card was already attached, we update the events
143 				for (Ability registeredAbility : MEventListener.TRIGGRED_ABILITIES
144 						.get(listener.getIdEvent())) {
145 					if (registeredAbility instanceof DetachmentAbility
146 							&& ((DetachmentAbility) registeredAbility).getAttachedCard() == from) {
147 						registeredAbility.setEvent(listener.clone(from));
148 					}
149 				}
150 			} else {
151 				final Ability tmpAbility = new DetachmentAbility(listener.clone(from),
152 						from, to, validTarget);
153 				tmpAbility.registerToManager();
154 				new RemoveModifier(new MovedCard(IdZones.PLAY, And.append(
155 						IsTested.TESTED_IS_ATTACHED_TO, new InZone(IdZones.PLAY,
156 								TestOn.ATTACHED_TO)), new Not(new InZone(IdZones.PLAY,
157 						TestOn.ATTACHED_TO)), ability.getCard()), tmpAbility)
158 						.registerToManager();
159 			}
160 		}
161 		for (ModifierModel modifier : modifiers) {
162 			if (from == ability.getCard()) {
163 				modifier.addModifierFromModel(ability, to);
164 			} else {
165 				modifier.addModifierFromModel(from.getDummyAbility(), to);
166 			}
167 		}
168 		from.getContainer().remove(from);
169 		to.add(from);
170 	}
171 
172 }