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.zone;
20  
21  import java.awt.Color;
22  import java.awt.Component;
23  import java.awt.Container;
24  import java.awt.FlowLayout;
25  import java.awt.Graphics;
26  import java.awt.Image;
27  import java.awt.LayoutManager;
28  import java.awt.Point;
29  import java.awt.event.MouseEvent;
30  import java.awt.event.MouseListener;
31  import java.io.File;
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.io.OutputStream;
35  import java.net.MalformedURLException;
36  import java.util.Arrays;
37  import java.util.Collections;
38  import java.util.List;
39  
40  import javax.swing.JComponent;
41  import javax.swing.JPanel;
42  import javax.swing.JScrollPane;
43  
44  import net.sf.magicproject.clickable.Clickable;
45  import net.sf.magicproject.clickable.ability.Ability;
46  import net.sf.magicproject.clickable.targetable.Targetable;
47  import net.sf.magicproject.clickable.targetable.card.AbstractCard;
48  import net.sf.magicproject.clickable.targetable.card.MCard;
49  import net.sf.magicproject.test.Test;
50  import net.sf.magicproject.token.IdPositions;
51  import net.sf.magicproject.token.Visibility;
52  import net.sf.magicproject.tools.Configuration;
53  import net.sf.magicproject.tools.Log;
54  import net.sf.magicproject.tools.MToolKit;
55  import net.sf.magicproject.tools.Pair;
56  import net.sf.magicproject.tools.Picture;
57  import net.sf.magicproject.ui.component.TableTop;
58  import net.sf.magicproject.ui.i18n.LanguageManagerMDB;
59  import net.sf.magicproject.ui.layout.FlowLayout2;
60  import net.sf.magicproject.ui.layout.WallpaperTypes;
61  
62  /***
63   * A zone is a cards container.
64   * 
65   * @author Fabrice Daugan
66   * @since 0.2c
67   * @since 0.3 feature "reverseImage" implemented
68   * @since 0.4 you can now change wallpaper/color of this MZone and setting
69   * @since 0.52 "enableReverse" option are saved.
70   * @since 0.71 visibility of cards can be set. Cards come into this zone
71   *        returned or not immediatly
72   */
73  public abstract class MZone extends JPanel implements MouseListener {
74  
75  	/***
76  	 * create an instance of MZone
77  	 * 
78  	 * @param idZone
79  	 *          id place of this panel
80  	 * @param layout
81  	 *          is it's layout
82  	 * @param superPanel
83  	 *          scroll panel containing this panel
84  	 * @param reverseImage
85  	 *          if true the backpicture will be reversed
86  	 * @param name
87  	 *          the untranslated zone name
88  	 * @see net.sf.magicproject.token.IdZones
89  	 */
90  	protected MZone(int idZone, LayoutManager layout, JScrollPane superPanel,
91  			boolean reverseImage, String name) {
92  		super(layout);
93  		setName(name);
94  		setBorder(null);
95  		this.superPanel = superPanel;
96  		this.reverseImage = reverseImage;
97  		this.idZone = idZone;
98  		String getter = "zones." + getZoneName() + "."
99  				+ (reverseImage ? "up" : "down");
100 		this.doMosaic = Configuration.getBoolean(getter + ".mosaic", true);
101 		setWallPaperFile(Configuration.getString(getter + ".wallpaper", ""));
102 		setBackground(new Color(Configuration.getInt(getter + ".background", 0)));
103 
104 		addMouseListener(this);
105 		if (superPanel != null) {
106 			superPanel.setOpaque(false);
107 			superPanel.setBorder(null);
108 			superPanel.setViewportView(this);
109 			((JComponent) getParent()).setOpaque(false);
110 			MToolKit.addOverlay(superPanel);
111 		}
112 	}
113 
114 	@Override
115 	public void paintComponent(Graphics g) {
116 		if (getImage() != null) {
117 			int width = getWidth();
118 			int height = getHeight();
119 			if (doMosaic && ZoneManager.bgDelegate != null) {
120 				// Delegate the painting to the L&F painter ignoring the reverse options
121 				super.paintComponent(g);
122 			} else {
123 				if (reverseImage
124 						&& (Configuration.getBoolean("reverseSide", false) || Configuration
125 								.getBoolean("reverseArt", true))) {
126 					if (doMosaic) {
127 						for (int y = height / picHeight + 1; y-- > 0;) {
128 							for (int x = width / picWidth + 1; x-- > 0;) {
129 								g.drawImage(getImage(), x * picWidth + picWidth, y * picHeight
130 										+ picHeight, x * picWidth, y * picHeight, 0, 0,
131 										picWidth - 1, picHeight - 1, null);
132 							}
133 						}
134 					} else {
135 						g.drawImage(getImage(), width, height, 0, 0, 0, 0, picWidth,
136 								picHeight, null);
137 					}
138 				} else {
139 					if (doMosaic) {
140 						for (int y = height / picHeight + 1; y-- > 0;) {
141 							for (int x = width / picWidth + 1; x-- > 0;) {
142 								g.drawImage(getImage(), x * picWidth, y * picHeight, picWidth,
143 										picHeight, null);
144 							}
145 						}
146 					} else {
147 						g.drawImage(getImage(), 0, 0, width, height, null);
148 					}
149 				}
150 			}
151 		} else if (ZoneManager.bgDelegate != null) {
152 			// Delegate the painting to the L&F painter ignoring the reverse options
153 			super.paintComponent(g);
154 		}
155 	}
156 
157 	/***
158 	 * return the card at index
159 	 * 
160 	 * @param index
161 	 *          is the index where is the element
162 	 * @return the card at the specified index
163 	 */
164 	public final MCard getCard(int index) {
165 		return (MCard) getComponent(index);
166 	}
167 
168 	/***
169 	 * return the last card (top)
170 	 * 
171 	 * @return the last card
172 	 */
173 	public MCard getTop() {
174 		return getCard(0);
175 	}
176 
177 	/***
178 	 * return the first card (bottom)
179 	 * 
180 	 * @return the first card
181 	 */
182 	public MCard getBottom() {
183 		return getCard(getComponentCount() - 1);
184 	}
185 
186 	/***
187 	 * Adds the specified card to this zone with the specified constraints at the
188 	 * specified index. Also notifies the layout manager to add the component to
189 	 * the this container's layout using the specified constraints object.
190 	 * 
191 	 * @param card
192 	 *          the card to be added
193 	 * @param constraints
194 	 *          an object expressing layout contraints for this
195 	 * @param position
196 	 *          the position in the container's list at which to insert the
197 	 *          component; <code>-1</code> means insert at the end card
198 	 * @see LayoutManager
199 	 */
200 	protected void add(MCard card, Object constraints, int position) {
201 		card.returnCard(visibility);
202 		card.getMUI().isAutoAlign = true;
203 		if (position == -1) {
204 			super.add(card, constraints);
205 		} else {
206 			super.add(card, constraints, position);
207 		}
208 		updatePanel();
209 	}
210 
211 	/***
212 	 * Indicates wether this card suits to the specified position code.
213 	 * 
214 	 * @param card
215 	 *          is the card to locate.
216 	 * @param position
217 	 *          the matching position code
218 	 * @return true if this card suits to the specified position code.
219 	 * @see net.sf.magicproject.token.IdPositions#ON_THE_BOTTOM
220 	 * @see net.sf.magicproject.token.IdPositions#ON_THE_TOP
221 	 */
222 	public final boolean isSamePosition(MCard card, int position) {
223 		if (getCardCount() == 0) {
224 			return false;
225 		}
226 		if (position == IdPositions.ON_THE_BOTTOM) {
227 			return getBottom() == card;
228 		}
229 		return getCardCount() > position && getCard(position) == card;
230 	}
231 
232 	/***
233 	 * Return the index of the specified card within this zone
234 	 * 
235 	 * @param card
236 	 *          the card to search
237 	 * @return the found index
238 	 */
239 	public Pair<Integer, Integer> getRealIndexOf(MCard card) {
240 		int index = super.getComponentZOrder(card);
241 		if (index != -1) {
242 			return new Pair<Integer, Integer>(index, 0);
243 		}
244 		// the card is not directly in play but maybe attached
245 		final Component[] components = getComponents();
246 		for (index = components.length; index-- > 0;) {
247 			final Component component = components[index];
248 			if (component instanceof Container) {
249 				final int subIndex = ((Container) component).getComponentZOrder(card);
250 				if (subIndex != -1) {
251 					return new Pair<Integer, Integer>(index, subIndex);
252 				}
253 			}
254 		}
255 		throw new InternalError("" + card + " has not been found in " + this);
256 	}
257 
258 	/***
259 	 * return the backImage to display in this JPanel
260 	 * 
261 	 * @return the backImage to display in this JPanel
262 	 */
263 	private Image getImage() {
264 		return backImage;
265 	}
266 
267 	/***
268 	 * return the translated name of this zone
269 	 * 
270 	 * @return the name of this panel
271 	 */
272 	@Override
273 	public String toString() {
274 		return LanguageManagerMDB.getString("zone." + getZoneName());
275 	}
276 
277 	/***
278 	 * This function returns the result of Component#getName() This will return
279 	 * the untranslated name of this zone. The toString()method returns the
280 	 * tanslated name of this zone
281 	 * 
282 	 * @return the result of Component#getName()
283 	 * @see #toString()
284 	 */
285 	public String getZoneName() {
286 		return getName();
287 	}
288 
289 	/***
290 	 * return the wallpaper file, return null if current panel is not in wallpaper
291 	 * mode.
292 	 * 
293 	 * @return current wallpaper file
294 	 */
295 	String getWallPaperFile() {
296 		String getter = "zones." + getZoneName() + "."
297 				+ (reverseImage ? "up" : "down");
298 		return Configuration.getString(getter + ".wallpaper", "");
299 	}
300 
301 	/***
302 	 * set the new wallpaper to the picture from a specified file. The current
303 	 * display mode of this panel will be now as "wallpaper"
304 	 * 
305 	 * @param newFile
306 	 *          the new wallpaper. If null or null sized, wallpaper is disabled
307 	 */
308 	void setWallPaperFile(String newFile) {
309 		String getter = "zones." + getZoneName() + "."
310 				+ (reverseImage ? "up" : "down");
311 		if (newFile != null && newFile.length() > 0) {
312 			Image backImage;
313 			try {
314 				backImage = Picture.loadImage(newFile);
315 				picWidth = backImage.getWidth(this);
316 				picHeight = backImage.getHeight(this);
317 				this.backImage = backImage;
318 				Configuration.setProperty(getter + ".wallpaper", newFile);
319 			} catch (MalformedURLException e) {
320 				// IGNORING
321 			}
322 			backImage = null;
323 		} else {
324 			Configuration.setProperty(getter + ".wallpaper", "");
325 			backImage = null;
326 		}
327 	}
328 
329 	/***
330 	 * Set the new wallpaper for the current game.
331 	 * 
332 	 * @param inputStream
333 	 *          the input Stream containing the wallpaper configuration.
334 	 * @throws IOException
335 	 *           If some other I/O error occurs
336 	 */
337 	public void readWallPaperConfiguration(InputStream inputStream)
338 			throws IOException {
339 		WallpaperTypes type = WallpaperTypes.values()[inputStream.read()];
340 		switch (type) {
341 		case color:
342 			backImage = null;
343 			setBackground(new Color(MToolKit.readInt24(inputStream)));
344 			break;
345 		case watermark:
346 			// ignore watermark of opponent
347 			break;
348 		case picture:
349 			doMosaic = false;
350 			backImage = MToolKit.readImage(inputStream);
351 			picWidth = backImage.getWidth(this);
352 			picHeight = backImage.getHeight(this);
353 			break;
354 		case mosaicPicture:
355 			doMosaic = true;
356 			backImage = MToolKit.readImage(inputStream);
357 			picWidth = backImage.getWidth(this);
358 			picHeight = backImage.getHeight(this);
359 			break;
360 		}
361 	}
362 
363 	/***
364 	 * Send the wallpaper configuration over the given output stream.
365 	 * 
366 	 * @param out
367 	 *          the output Stream containing the wallpaper configuration.
368 	 * @throws IOException
369 	 *           If some other I/O error occurs
370 	 */
371 	public void writeWallPaperConfiguration(OutputStream out) throws IOException {
372 		if (ZoneManager.bgDelegate != null) {
373 			out.write(WallpaperTypes.watermark.ordinal());
374 		} else if (backImage != null) {
375 			if (doMosaic) {
376 				out.write(WallpaperTypes.mosaicPicture.ordinal());
377 			} else {
378 				out.write(WallpaperTypes.picture.ordinal());
379 			}
380 
381 			// Send the picture data
382 			MToolKit.writeFile(new File(getWallPaperFile()), out);
383 		} else {
384 			out.write(WallpaperTypes.color.ordinal());
385 			MToolKit.writeInt24(out, getBackground().getRGB());
386 		}
387 	}
388 
389 	@Override
390 	public void removeAll() {
391 		super.removeAll();
392 		updatePanel();
393 	}
394 
395 	/***
396 	 * update this panel in fonction of it's components
397 	 */
398 	public void updatePanel() {
399 		// invalidate();
400 		doLayout();
401 		repaint();
402 	}
403 
404 	/***
405 	 * Shuffle the zone
406 	 */
407 	public void shuffle() {
408 		final List<Component> components = Arrays.asList(getComponents());
409 		Collections.shuffle(components, MToolKit.random);
410 		removeAll();
411 		for (Component component : components) {
412 			add(component);
413 		}
414 		updatePanel();
415 	}
416 
417 	public void mouseReleased(MouseEvent e) {
418 		mousePressed(e);
419 	}
420 
421 	public void mouseClicked(MouseEvent e) {
422 		// Ignore this event
423 	}
424 
425 	public void mouseEntered(MouseEvent e) {
426 		// Ignore this event
427 	}
428 
429 	// Ignore this event
430 	public void mouseExited(MouseEvent e) {
431 		// Ignore this event
432 	}
433 
434 	/***
435 	 * Update the "reversed" state of this component.
436 	 */
437 	public void updateReversed() {
438 		// Ignore this event
439 	}
440 
441 	/***
442 	 * Update the layout of this panel depending on the owner.
443 	 * 
444 	 * @param panel
445 	 *          the panel to update
446 	 * @param reverse
447 	 *          is this zone is reversed.
448 	 */
449 	protected static void updateLayouts(JComponent panel, boolean reverse) {
450 		if (reverse) {
451 			panel.setLayout(new FlowLayout2());
452 		} else {
453 			panel.setLayout(new FlowLayout(FlowLayout.LEFT));
454 		}
455 	}
456 
457 	/***
458 	 * is called when you click on me
459 	 * 
460 	 * @param e
461 	 *          is the mouse event
462 	 */
463 	public void mousePressed(MouseEvent e) {
464 		PopupManager.instance.mousePressed(e, this);
465 	}
466 
467 	/***
468 	 * Save wallpaper name, display options and back colors of this panel to a
469 	 * specified output stream
470 	 */
471 	void saveSettings() {
472 		String setter = "zones." + getZoneName() + "."
473 				+ (reverseImage ? "up" : "down");
474 		Configuration.setProperty(setter + ".mosaic", doMosaic);
475 		Configuration.setProperty(setter + ".background", getBackground().getRGB());
476 	}
477 
478 	/***
479 	 * Add a card to this panel. If tag 'returnedCards' is true, this card comes
480 	 * returned into this zone.
481 	 * 
482 	 * @param card
483 	 *          the card to add to this zone.
484 	 */
485 	public void remove(AbstractCard card) {
486 		super.remove(card);
487 		updatePanel();
488 	}
489 
490 	/***
491 	 * return the number of cards in this panel
492 	 * 
493 	 * @return the number of cards in this panel
494 	 */
495 	public int getCardCount() {
496 		return getComponentCount();
497 	}
498 
499 	/***
500 	 * Checks all cards corresponding to the specified constraints including
501 	 * attached cards.
502 	 * 
503 	 * @param test
504 	 *          applied to count valid cards
505 	 * @param ability
506 	 *          is the ability owning this test. The card component of this
507 	 *          ability should correspond to the card owning this test too.
508 	 * @return amount of card matching with the specified test
509 	 */
510 	public int countAllCardsOf(Test test, Ability ability) {
511 		int result = 0;
512 		for (Component component : getComponents()) {
513 			result += ((AbstractCard) component).countAllCardsOf(test, ability, true);
514 		}
515 		return result;
516 	}
517 
518 	/***
519 	 * Checks all cards corresponding to the specified constraints including
520 	 * attached cards.
521 	 * 
522 	 * @param test
523 	 *          applied to count valid cards
524 	 * @param ability
525 	 *          is the ability owning this test. The card component of this
526 	 *          ability should correspond to the card owning this test too.
527 	 * @param limit
528 	 *          is the desired count.
529 	 * @param canBePreempted
530 	 *          <code>true</code> if the valid targets can be derterminated
531 	 *          before runtime.
532 	 * @return amount of cards matching with the specified test. Highest value is
533 	 *         <code>limit</code>.
534 	 */
535 	public int countAllCardsOf(Test test, Ability ability, int limit,
536 			boolean canBePreempted) {
537 		int result = 0;
538 		int index = getCardCount();
539 		while (index-- > 0 && result < limit) {
540 			result += ((AbstractCard) getComponent(index)).countAllCardsOf(test,
541 					ability, canBePreempted);
542 		}
543 		return result;
544 	}
545 
546 	/***
547 	 * Checks all cards corresponding to this constraints
548 	 * 
549 	 * @param test
550 	 *          applied to count valid cards
551 	 * @param list
552 	 *          the list containing the founded cards
553 	 * @param ability
554 	 *          is the ability owning this test. The card component of this
555 	 *          ability should correspond to the card owning this test too.
556 	 */
557 	public void checkAllCardsOf(Test test, List<Targetable> list, Ability ability) {
558 		for (Component component : getComponents()) {
559 			((AbstractCard) component).checkAllCardsOf(test, list, ability);
560 		}
561 	}
562 
563 	/***
564 	 * Dishighlight all cards of this zone manager
565 	 */
566 	public void disHighLightAll() {
567 		for (Component component : getComponents()) {
568 			if (component instanceof Clickable) {
569 				((Clickable) component).disHighLight();
570 			}
571 		}
572 		disHighLight();
573 	}
574 
575 	/***
576 	 * Dishighlight only this component, not the components of this zone.
577 	 */
578 	public void disHighLight() {
579 		// reset the tabbed panel backgroung of this panel
580 		int id = TableTop.getInstance().tabbedPane.indexOfComponent(superPanel);
581 		if (id == -1) {
582 			Log.debug("error");
583 			throw new InternalError("index=-1; zone=" + this);
584 		} else if (TableTop.getInstance().tabbedPane.getBackgroundAt(id) != null) {
585 			TableTop.getInstance().tabbedPane.setBackgroundAt(id, null);
586 		}
587 	}
588 
589 	/***
590 	 * Highlight only this component, not the components of this zone. Use instead
591 	 * the specific highlight color of the desired zone.
592 	 * 
593 	 * @param color
594 	 *          the color of highlight.
595 	 */
596 	public void highLight(Color color) {
597 		TableTop.getInstance().tabbedPane.setSelectedComponent(superPanel);
598 		TableTop.getInstance().tabbedPane.setBackgroundAt(
599 				TableTop.getInstance().tabbedPane.indexOfComponent(superPanel), color);
600 	}
601 
602 	/***
603 	 * Remove all cards of this zone
604 	 */
605 	public void reset() {
606 		removeAll();
607 	}
608 
609 	/***
610 	 * Set the visibility of this zone.
611 	 * 
612 	 * @param visibility
613 	 *          the new visibility for this zone.
614 	 */
615 	public void setVisibility(Visibility visibility) {
616 		if (this.visibility != visibility) {
617 			this.visibility = visibility;
618 			// update the cards
619 			for (Component component : getComponents()) {
620 				if (component instanceof MCard) {
621 					((MCard) component).returnCard(visibility);
622 				}
623 			}
624 			repaint();
625 		}
626 	}
627 
628 	/***
629 	 * Add a card at the bottom of this panel. If tag 'returnedCards' is true,
630 	 * this card comes returned into this zone.
631 	 * 
632 	 * @param card
633 	 *          the card to add to this zone.
634 	 */
635 	public void addBottom(MCard card) {
636 		add(card, -1);
637 	}
638 
639 	/***
640 	 * Add a card at the top of this panel. If tag 'returnedCards' is true, this
641 	 * card comes returned into this zone. Be carrefull, you can use this function
642 	 * only if the specified component is not yet in this container.
643 	 * 
644 	 * @param card
645 	 *          the card to add to this zone.
646 	 */
647 	public void addTop(MCard card) {
648 		add(card, 0);
649 	}
650 
651 	/***
652 	 * Add a card to this panel. If tag 'returnedCards' is true, this card comes
653 	 * returned into this zone.
654 	 * 
655 	 * @param card
656 	 *          the card to add to this zone.
657 	 * @param position
658 	 *          the position index of insertion.
659 	 */
660 	public void add(MCard card, int position) {
661 		add(card, null, position);
662 	}
663 
664 	/***
665 	 * Return idplayer of controller of this zone.
666 	 * 
667 	 * @return idplayer of controller of this zone.
668 	 */
669 	public int getControllerIdPlayer() {
670 		return reverseImage ? 1 : 0;
671 	}
672 
673 	/***
674 	 * Returnn the zone identifiant
675 	 * 
676 	 * @return the zone identifiant
677 	 */
678 	public final int getZoneId() {
679 		return idZone;
680 	}
681 
682 	/***
683 	 * Start the drag and drop managment for the given card.
684 	 * 
685 	 * @param card
686 	 *          The d&d component.
687 	 * @param mousePoint
688 	 *          The d&d starting point.
689 	 * @return <code>true</code> if the drag and drop is managed by this zone.
690 	 */
691 	public boolean startDragAndDrop(MCard card, Point mousePoint) {
692 		dragAndDropComponent = card;
693 		this.mousePoint = mousePoint;
694 		return true;
695 	}
696 
697 	/***
698 	 * Return <code>true</code> if the given card should be painted as reversed
699 	 * card.
700 	 * 
701 	 * @param card
702 	 *          the card to draw.
703 	 * @return <code>true</code> if the given card should be painted as reversed
704 	 *         card.
705 	 */
706 	public boolean isMustBePaintedReversed(MCard card) {
707 		return card.reversed && Configuration.getBoolean("reverseArt", true);
708 	}
709 
710 	/***
711 	 * Return <code>true</code> if the given card should be painted entirely.
712 	 * 
713 	 * @param card
714 	 *          the card to draw.
715 	 * @return <code>true</code> if the given card should be painted entirely.
716 	 */
717 	public boolean isMustBePainted(MCard card) {
718 		return true;
719 	}
720 
721 	/***
722 	 * Is this zone is shared with all players.
723 	 * 
724 	 * @return <code>true</code> if this zone is shared with all players.
725 	 */
726 	public boolean isShared() {
727 		return false;
728 	}
729 
730 	/***
731 	 * picture displayed in the panel
732 	 */
733 	protected Image backImage = null;
734 
735 	/***
736 	 * The picture's height
737 	 */
738 	private int picHeight;
739 
740 	/***
741 	 * The picture's width
742 	 */
743 	private int picWidth;
744 
745 	/***
746 	 * Is the backgroud picture is drawn as mosaic. Otherwise, is centered.
747 	 */
748 	boolean doMosaic;
749 
750 	/***
751 	 * Are the images are reversed in this zone.
752 	 */
753 	protected boolean reverseImage;
754 
755 	/***
756 	 * Indicates all cards of this zone are returned or not. All cards comming
757 	 * into this zone would be returned or not depending this flag.
758 	 * 
759 	 * @since 0.80 cards are hidden by default
760 	 * @since 0.90 use Visibility class instead of boolean
761 	 */
762 	public Visibility visibility = Visibility.HIDDEN;
763 
764 	/***
765 	 * the parent scrollpane
766 	 */
767 	public final JScrollPane superPanel;
768 
769 	/***
770 	 * The zone identifiant.
771 	 */
772 	private final int idZone;
773 
774 	/***
775 	 * The d&d starting point
776 	 */
777 	public Point mousePoint;
778 
779 	/***
780 	 * The d&d component.
781 	 */
782 	public MCard dragAndDropComponent = null;
783 
784 }