View Javadoc

1   /*
2    * Created on Sep 6, 2004 
3    * 
4    *   Magic-Project is a turn based strategy simulator
5    *   Copyright (C) 2003-2007 Fabrice Daugan
6    *
7    *   This program is free software; you can redistribute it and/or modify it 
8    * under the terms of the GNU General Public License as published by the Free 
9    * Software Foundation; either version 2 of the License, or (at your option) any
10   * later version.
11   *
12   *   This program is distributed in the hope that it will be useful, but WITHOUT 
13   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
15   * details.
16   *
17   *   You should have received a copy of the GNU General Public License along  
18   * with this program; if not, write to the Free Software Foundation, Inc., 
19   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   * 
21   */
22  package net.sf.magicproject.modifier;
23  
24  import java.util.List;
25  import java.util.Set;
26  
27  import net.sf.magicproject.clickable.ability.Ability;
28  import net.sf.magicproject.clickable.targetable.card.MCard;
29  import net.sf.magicproject.event.MEventListener;
30  import net.sf.magicproject.expression.Expression;
31  import net.sf.magicproject.stack.StackManager;
32  import net.sf.magicproject.test.Test;
33  import net.sf.magicproject.token.IdConst;
34  
35  /***
36   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
37   * @since 0.86 properties set is calculated as colors/idcard and register : they
38   *        follow timestamp rule.
39   */
40  public class PropertyModifier extends Modifier {
41  
42  	/***
43  	 * Creates a new instance of PropertyModifier <br>
44  	 * 
45  	 * @param name
46  	 *          the modifier name
47  	 * @param to
48  	 *          the component to be attached to
49  	 * @param ability
50  	 *          is the ability owning this test. The card component of this
51  	 *          ability should correspond to the card owning this test too.
52  	 * @param whileCondition
53  	 *          the test conditionning the activation of this modifier.
54  	 * @param linkedEvents
55  	 *          the events to be registered. This events would cause this modifier
56  	 *          to be updated.
57  	 * @param until
58  	 *          this modifier exists while this test is true.
59  	 * @param linked
60  	 *          is the creator is linked to this modifier.
61  	 * @param layer
62  	 *          is the strategy used to add this modifier within the existing
63  	 *          chain.
64  	 * @param propertyId
65  	 *          the propety to add/remove
66  	 * @param addProperty
67  	 *          Indicates if this modifier remove occurence of the given property.
68  	 *          If true, it adds one instance.
69  	 */
70  	PropertyModifier(String name, MCard to, Ability ability, Test whileCondition,
71  			List<MEventListener> linkedEvents, List<MEventListener> until,
72  			boolean linked, int layer, Expression propertyId, boolean addProperty) {
73  		super(name, to, ability, whileCondition, linkedEvents, until, linked, layer);
74  		this.propertyId = propertyId;
75  		this.addProperty = addProperty;
76  	}
77  
78  	@Override
79  	public Modifier removeModifier(Modifier modifier) {
80  		if (this == modifier) {
81  			if (activated) {
82  				StackManager.postRefreshProperties(to, propertyId.getValue(ability, to,
83  						null));
84  			}
85  			return next;
86  		}
87  		return super.removeModifier(modifier);
88  	}
89  
90  	@Override
91  	public final void removeFromManager() {
92  		super.removeFromManager();
93  		if (!unregisteredModifier) {
94  			to.removeModifier(this);
95  		}
96  		unregisteredModifier = true;
97  	}
98  
99  	/***
100 	 * Tells if this modifier add/remove the given property.
101 	 * 
102 	 * @param propertyId
103 	 *          the matched property
104 	 * @param found
105 	 *          indicates that the property has been previously found.
106 	 * @return true if this modifier add/remove the given property.
107 	 */
108 	public boolean hasProperty(int propertyId, boolean found) {
109 		if (activated) {
110 			int newPropertyId = this.propertyId.getValue(ability, to, null);
111 			if (newPropertyId == IdConst.ALL && !addProperty) {
112 				if (next != null) {
113 					return ((PropertyModifier) next).hasProperty(propertyId, addProperty);
114 				}
115 				return false;
116 			}
117 			if (newPropertyId == propertyId) {
118 				if (next != null) {
119 					return ((PropertyModifier) next).hasProperty(propertyId, addProperty);
120 				}
121 				return addProperty;
122 			}
123 		}
124 		if (next != null) {
125 			return ((PropertyModifier) next).hasProperty(propertyId, found);
126 		}
127 		return found;
128 	}
129 
130 	/***
131 	 * Tells if this modifier add/remove the given property ignoring these given
132 	 * by the specified card <code>creator</code>.
133 	 * 
134 	 * @param propertyId
135 	 *          the matched property
136 	 * @param found
137 	 *          indicates that the property has been previously found
138 	 * @param creator
139 	 *          is the card created modifiers would be ignored
140 	 * @return true if this modifier add/remove the given property ignoring these
141 	 *         given by the specified card <code>creator</code>.
142 	 */
143 	public boolean hasPropertyNotFromCreator(int propertyId, boolean found,
144 			MCard creator) {
145 		if (activated && creator != this.ability.getCard()) {
146 			int newPropertyId = this.propertyId.getValue(ability, to, null);
147 			if (newPropertyId == IdConst.ALL && !addProperty) {
148 				if (next != null) {
149 					return ((PropertyModifier) next).hasPropertyNotFromCreator(
150 							propertyId, addProperty, creator);
151 				}
152 				return false;
153 			}
154 			if (newPropertyId == propertyId) {
155 				if (next != null) {
156 					return ((PropertyModifier) next).hasPropertyNotFromCreator(
157 							propertyId, addProperty, creator);
158 				}
159 			}
160 			return addProperty;
161 		}
162 		if (next != null) {
163 			return ((PropertyModifier) next).hasPropertyNotFromCreator(propertyId,
164 					found, creator);
165 		}
166 		return found;
167 	}
168 
169 	/***
170 	 * Add/remove the specified set by the manipulated propoerties of this
171 	 * modifier.
172 	 * 
173 	 * @param workSet
174 	 *          the set of properties already found
175 	 */
176 	public void fillProperties(Set<Integer> workSet) {
177 		if (activated) {
178 			if (addProperty) {
179 				workSet.add(propertyId.getValue(ability, to, null));
180 			} else {
181 				final int propertyId = this.propertyId.getValue(ability, to, null);
182 				if (IdConst.ALL == propertyId)
183 					workSet.clear();
184 				else {
185 					workSet.remove(propertyId);
186 				}
187 			}
188 		}
189 		if (next != null) {
190 			((PropertyModifier) next).fillProperties(workSet);
191 		}
192 	}
193 
194 	@Override
195 	public void refresh() {
196 		final boolean oldActivated = activated;
197 		activated = whileCondition.test(ability, to);
198 
199 		// this property has changed
200 		if (oldActivated != activated) {
201 			StackManager.postRefreshProperties(to, propertyId.getValue(ability, to,
202 					null));
203 		}
204 	}
205 
206 	/***
207 	 * Indicates if this modifier remove occurence of the given property. If True,
208 	 * it adds one instance of this property.
209 	 */
210 	protected boolean addProperty;
211 
212 	/***
213 	 * Property to add/remove
214 	 */
215 	protected Expression propertyId;
216 
217 }