package adecWatt.control;

import java.awt.Container;
import java.awt.Desktop;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.TreeSet;
import java.util.Vector;
import javax.swing.AbstractButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import misc.ApplicationManager;
import misc.Config;
import misc.HtmlDialog;
import misc.RemoteUpdateManager;
import misc.Story;
import misc.StoryManager;
import misc.Util;

import adecWatt.model.Acc;
import adecWatt.model.AdecWatt;
import adecWatt.model.Editable;
import adecWatt.model.ImageDB;
import adecWatt.model.Item;
import adecWatt.model.PermanentDB;
import adecWatt.model.Unit;
import adecWatt.model.unit.Workspace;
import adecWatt.view.JAdecWatt;
import adecWatt.view.JAdecWattDialog;
import adecWatt.view.JWorkspaceSlidersToolBar;
import adecWatt.view.JWorkspaceView;
import adecWatt.view.PrintWorkspace;

public class AdecWattManager implements ApplicationManager, ActionListener {

    // ========================================
    public static String protocol = "https";
    public static String remoteServerName = "adecwatt.parlenet.org";
    public String testedServerName = "adecwatt.parlenet.local";
    public String currentServerName = remoteServerName;
    public static String stableVersion = "v3";
    public String testedVersion = "test";
    public String currentVersion = stableVersion;
    public static String
	urlModel = "/lib/plugins/adecwatt/adecWattBD.php?version={0}&action={1}&name={2}";

    // ========================================
    static public final String
	actionChangeRole		= "ChangeRole",
	actionRestart			= "Restart",
	actionSave			= "Save",
	actionSaveAll			= "SaveAll",
	actionImport			= "Import",
	actionExport			= "Export",
	actionPageSetup			= "PageSetup",
	actionPrint			= "Print",
	actionExportPDF			= "ExportPDF",
	actionClose			= "Close",
	actionCloseAll			= "CloseAll",

	actionSelectAll			= "SelectAll",
	actionCut			= "Cut",
	actionCopy			= "Copy",
	actionPaste			= "Paste",
	actionMagnetPolicies		= "MagnetPolicies",
	actionPatch			= "Patch",

	actionHorizontalLeft		= "HorizontalLeft",
	actionHorizontalCenter		= "HorizontalCenter",
	actionHorizontalRight		= "HorizontalRight",
	actionVerticalTop		= "VerticalTop",
	actionVerticalCenter		= "VerticalCenter",
	actionVerticalBottom		= "VerticalBottom",

	actionHorizontalSpace		= "HorizontalSpace",
	actionHorizontalDistrib		= "HorizontalDistrib",
	actionVerticalSpace		= "VerticalSpace",
	actionVerticalDistrib		= "VerticalDistrib",
	actionWizard			= "Wizard",
	actionHttpServer		= "HttpServer",
	actionLocalServer		= "LocalServer",
	actionTestedServer		= "TestedServer",
	actionServerName		= "ServerName",
	actionManual			= "Manual";

    static public Util.ActionControl[] actionsControl = {
	new Util.ActionControl (actionSave, KeyEvent.VK_S),
	new Util.ActionControl (actionSelectAll, KeyEvent.VK_A),
	new Util.ActionControl (actionCut, KeyEvent.VK_X),
	// new Util.ActionControl (actionCut, KeyEvent.VK_DELETE, false),
	// new Util.ActionControl (actionCut, KeyEvent.VK_BACK_SPACE, false),
	new Util.ActionControl (actionCopy, KeyEvent.VK_C),
	new Util.ActionControl (actionPaste, KeyEvent.VK_V),
	new Util.ActionControl (StoryManager.actionUndo, KeyEvent.VK_Z),
	new Util.ActionControl (StoryManager.actionRedo, KeyEvent.VK_Y),
    };

    // ========================================
    /** popup Menu. */
    static public final String
	actionDisplayUnit		= "DisplayUnit",
	actionModifyUnit		= "ModifyUnit",
	actionRenameUnit		= "RenameUnit",
	actionTransformUnit		= "TransformUnit",
	actionCopyUnit			= "CopyUnit",
	actionNewUnit			= "NewUnit",
	actionPromoteUnit		= "PromoteUnit",
	actionRemoveUnit		= "RemoveUnit",
	actionRemoveImage		= "RemoveImage",
	actionChangeImage		= "ChangeImage",
	actionUnchange			= "Unchange";

    static public final String
	actionDisplayItem		= "DisplayItem",
	actionModifyItem		= "ModifyItem",
	actionHideItem			= "HideItem",
	actionShowItem			= "ShowItem",
	actionTransformItem		= "TransformItem",
	actionCopyItem			= "CopyItem",
	actionRemoveItem		= "RemoveItem",

	actionHideShowItem		= "HideShowItem";

    static public final String
	actionDisplayAcc		= "DisplayAcc",
	actionModifyAcc			= "ModifyAcc",
	actionTransformAcc		= "TransformAcc",
	actionRemoveAcc			= "RemoveAcc";

    // ========================================
    static public final List<String>
	fileActionsNames		= Arrays.asList (actionChangeRole, actionRestart,
							 actionSave, actionSaveAll, actionImport, actionExport,
							 actionPageSetup, actionPrint, //actionExportPDF,
							 actionClose, actionCloseAll),
	editActionsNames		= Arrays.asList (actionSelectAll, actionCut, actionCopy, actionPaste, actionMagnetPolicies, actionPatch),
	placementActionsNames		= Arrays.asList (actionHorizontalLeft, actionHorizontalCenter, actionHorizontalRight,
							 actionVerticalTop, actionVerticalCenter, actionVerticalBottom,
							 actionHorizontalSpace, actionHorizontalDistrib,
							 actionVerticalSpace, actionVerticalDistrib),
	yodaActionsNames		= Arrays.asList (actionHttpServer, actionLocalServer, actionTestedServer, actionServerName, actionWizard),
	yodaNoCheckActionsNames		= Arrays.asList (actionServerName, actionWizard),
	helpActionsNames		= Arrays.asList (actionManual);

    // ========================================
    @SuppressWarnings ("unchecked")
    static public final Hashtable<String, Method> actionsMethod =
	Util.collectMethod (AdecWattManager.class,
			    fileActionsNames, editActionsNames, placementActionsNames, yodaActionsNames, helpActionsNames);

    public void  actionPerformed (ActionEvent e) {
	Util.actionPerformed (actionsMethod, e, this);
    }

    // ========================================
    AdecWatt adecWatt;
    PermanentDB permanentDB;
    StoryManager storyManager;
    RemoteUpdateManager remoteUpdateManager;

    JAdecWatt jAdecWatt;
    JWorkspaceSlidersToolBar jWorkspaceSlidersToolBar;
    JAdecWattDialog jAdecWattDialog;
    HtmlDialog manualDialog;
    JCheckBoxMenuItem httpServerCB;
    JCheckBoxMenuItem localServerCB;
    JCheckBoxMenuItem testedServerCB;

    // ========================================
    public AdecWattManager (AdecWatt adecWatt, StoryManager storyManager, RemoteUpdateManager remoteUpdateManager,
			    JAdecWatt jAdecWatt, JWorkspaceSlidersToolBar jWorkspaceSlidersToolBar, JAdecWattDialog jAdecWattDialog,
			    HtmlDialog manualDialog) {
	this.adecWatt= adecWatt;
	permanentDB = adecWatt.getPermanentDB ();
	this.storyManager = storyManager;
	this.jAdecWatt = jAdecWatt;
	this.jWorkspaceSlidersToolBar = jWorkspaceSlidersToolBar;
	this.jAdecWattDialog = jAdecWattDialog;
	this.manualDialog = manualDialog;
	this.remoteUpdateManager = remoteUpdateManager;

	jAdecWatt.stateNotifier.addUpdateObserver (this, JAdecWatt.BroadcastWorkspace, JAdecWatt.BroadcastSelection);
	jAdecWatt.stateNotifier.addMsgObserver (this, JAdecWatt.BroadcastUnitStory); //, JAdecWatt.BroadcastEditableSelection);

	adecWatt.addUpdateObserver (this,
				    AdecWatt.BroadcastStory);
	adecWatt.addMsgObserver (this,
				 AdecWatt.BroadcastUnitStory,
				 actionClose,
				 actionDisplayUnit, actionModifyUnit, actionRenameUnit, actionTransformUnit,
				 actionCopyUnit, actionNewUnit, actionPromoteUnit, actionRemoveUnit,
				 actionDisplayItem, actionModifyItem, actionHideShowItem, actionTransformItem, actionCopyItem, actionRemoveItem,
				 Unit.BroadcastSetSelectionItems, Unit.BroadcastConnection,
				 actionDisplayAcc, actionModifyAcc, actionTransformAcc, actionRemoveAcc);
    }

    // ========================================
    public void addMenuItem (JMenu... jMenu) {
	int idx = 0;
	Util.addMenuItem (fileActionsNames, this, jMenu[idx++]);
	Util.addMenuItem (editActionsNames, this, jMenu[idx++]);
	Util.addMenuItem (placementActionsNames, this, jMenu[idx++]);
	httpServerCB = Util.addCheckMenuItem (actionHttpServer, this, false, jMenu[idx]);
	localServerCB = Util.addCheckMenuItem (actionLocalServer, this, false, jMenu[idx]);
	testedServerCB = Util.addCheckMenuItem (actionTestedServer, this, false, jMenu[idx]);
	actionHttpServer ();
	actionLocalServer ();
	actionTestedServer ();
	Util.addMenuItem (yodaNoCheckActionsNames, this, jMenu[idx++]);
	Util.addMenuItem (helpActionsNames, this, jMenu[idx++]);
    }

    // ========================================
    public void addIconButtons (Container... containers) {
	int idx = 0;
	Util.addIconButton (fileActionsNames, this, containers[idx++]);
	Util.addIconButton (editActionsNames, this, containers[idx++]);
	Util.addIconButton (placementActionsNames, this, containers[idx++]);
	idx++;
	idx++;
	Util.addIconButton (helpActionsNames, this, containers[idx++]);
    }

    // ========================================
    private ArrayList<AbstractButton> enabledSaveButtons = new ArrayList<AbstractButton> ();
    private ArrayList<AbstractButton> enabledSaveAllButtons = new ArrayList<AbstractButton> ();
    private ArrayList<AbstractButton> enabledCloseButtons = new ArrayList<AbstractButton> ();
    private ArrayList<AbstractButton> enabledPasteButtons = new ArrayList<AbstractButton> ();
    private ArrayList<AbstractButton> enabledSelectionButtons = new ArrayList<AbstractButton> ();
    private ArrayList<AbstractButton> enabledMultiSelectionButtons = new ArrayList<AbstractButton> ();
    public void addActiveButtons (Hashtable<String, AbstractButton> buttons) {
	enabledSaveButtons.add (buttons.get (actionSave));
	enabledSaveAllButtons.add (buttons.get (actionSaveAll));
	enabledCloseButtons.add (buttons.get (actionPrint));
	//enabledCloseButtons.add (buttons.get (actionExportPDF));
	enabledCloseButtons.add (buttons.get (actionPatch));
	enabledCloseButtons.add (buttons.get (actionExport));
	enabledCloseButtons.add (buttons.get (actionClose));
	enabledCloseButtons.add (buttons.get (actionCloseAll));
	enabledCloseButtons.add (buttons.get (actionSelectAll));
	enabledPasteButtons.add (buttons.get (actionPaste));
	enabledSelectionButtons.add (buttons.get (actionCopy));
	enabledSelectionButtons.add (buttons.get (actionCut));
	for (String action : placementActionsNames)
	    enabledMultiSelectionButtons.add (buttons.get (action));
	updateActiveButtons ();
    }

    public void updateActiveButtons () {
	remoteUpdateManager.updateActiveButtons ();
	updateStory ();
	updateWorkspace ();
	updatePaste ();
    }

    // ========================================
    Unit<?> sharedUnitStory;
    public Unit<?> getSharedUnitStory () { return sharedUnitStory; }
    public void displayUnitStory (Object... objects) {
	// if (objects[0] == null)
	//     return;
	sharedUnitStory = (Unit<?>) objects[0];
	adecWatt.broadcastUpdate (AdecWatt.BroadcastTitle);
	storyManager.setStory (sharedUnitStory == null ? null : sharedUnitStory.story);
	updateStory ();
    }
    public void updateStory () {
	boolean saveAll = permanentDB.isModifiedUnit ();
	boolean save = false;
	if (sharedUnitStory != null) {
	    Story story = sharedUnitStory.story;
	    save = story.isModified ();
	}
	for (AbstractButton button : enabledSaveButtons)
	    button.setEnabled (save);
	for (AbstractButton button : enabledSaveAllButtons)
	    button.setEnabled (saveAll);
	jAdecWatt.updateUnit (sharedUnitStory, false);
    }

    public void updateWorkspace () {
	boolean close = jAdecWatt.hasWorkspace ();
	for (AbstractButton button : enabledCloseButtons)
	    button.setEnabled (close);
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
	displayUnitStory (currentWorkspace);
	updateSelection ();
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	jWorkspaceSlidersToolBar.setJWorkspaceView (jWorkspaceView);
    }

    public void updateSelection () {
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	int nbSelection = jWorkspaceView == null ? 0 : jWorkspaceView.getNbSelectedItems ();
	boolean selection = nbSelection > 0;
	boolean multiSelection = nbSelection > 1;
	for (AbstractButton button : enabledSelectionButtons)
	    button.setEnabled (selection);
	for (AbstractButton button : enabledMultiSelectionButtons)
	    button.setEnabled (multiSelection);
    }

    // ========================================
    public void actionRestart () {
	if (adecWatt.getModified () && !jAdecWattDialog.abortModification ())
	    return;
	actionCloseAll ();
	adecWatt.reset ();
	jAdecWatt.stateNotifier.broadcastDisplay (JAdecWatt.BroadcastUnitStory, (Unit<?>) null);
    }

    public void actionSave () {
	if (sharedUnitStory == null)
	    return;
	sharedUnitStory.save ();
    }

    public void actionSaveAll () {
	adecWatt.saveAll ();
    }

    public void actionSelectAll () {
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	if (jWorkspaceView == null)
	    return;
	jWorkspaceView.selectAllItems ();
    }

    public void actionImport () {
	permanentDB.importFile (jAdecWattDialog.getChooseOpenFile (permanentDB.getLastExport ()));
    }

    public void actionExport () {
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
	if (currentWorkspace == null)
	    return;
	permanentDB.exportFile (currentWorkspace, jAdecWattDialog.getChooseSaveFile (permanentDB.getLastExport ()));
    }

    Vector<Item> clip = new Vector<Item> ();

    public void updatePaste () {
	boolean paste = clip.size () > 0;
	for (AbstractButton button : enabledPasteButtons)
	    button.setEnabled (paste);
    }

    public void actionCut () {
	actionCopy ();
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	if (jWorkspaceView == null)
	    return;
	jWorkspaceView.getWorkspace ().storyRemoveItems (clip);
    }

    public void actionCopy () {
	clip.clear ();
	try {
	    clip.addAll (jAdecWatt.getCurrentJWorkspace ().getSelectedItems ());
	} catch (Exception e) {
	}
	updatePaste ();
    }

    public void actionPaste () {
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
	if (currentWorkspace == null)
	    return;
	currentWorkspace.storyPasteItem (clip);
    }


    // ========================================
    public void displayClose (Object... objects) {
	if (objects[0] == null || ! (objects[0] instanceof Workspace))
	    return;
	Workspace workspace = (Workspace) objects[0];
	jAdecWattDialog.removeDisplay (workspace);
	jAdecWatt.closeWorkspace (workspace);
    }

    public void actionClose () {
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
	jAdecWattDialog.removeDisplay (currentWorkspace);
	jAdecWatt.closeWorkspace (currentWorkspace);
    }

    public void actionCloseAll () {
	jAdecWattDialog.removeAllDisplay ();
	jAdecWatt.closeWorkspaces ();
    }

    public void actionChangeRole () {
	jAdecWattDialog.checkAdmin (adecWatt.getUser (), remoteUpdateManager);
    }

    public void actionHorizontalLeft ()		{ align (Workspace.Alignment.LEFT); }
    public void actionHorizontalCenter ()	{ align (Workspace.Alignment.CENTER); }
    public void actionHorizontalRight ()	{ align (Workspace.Alignment.RIGHT); }
    public void actionVerticalTop ()		{ align (Workspace.Alignment.TOP); }
    public void actionVerticalCenter ()		{ align (Workspace.Alignment.MIDDLE); }
    public void actionVerticalBottom ()		{ align (Workspace.Alignment.BOTTOM); }
    public void actionHorizontalSpace ()	{ distrib (true, true); }
    public void actionHorizontalDistrib ()	{ distrib (true, false); }
    public void actionVerticalSpace () 		{ distrib (false, true); }
    public void actionVerticalDistrib ()	{ distrib (false, false); }


    public void distrib (boolean isHorizontal, boolean isSpace) {
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	if (jWorkspaceView == null)
	    return;
	Double value = jAdecWattDialog.getSpace ();
	if (value != null && value < 0)
	    return;
	Vector<Item> items = jWorkspaceView.getSelectedItems ();
	if (items == null || items.size () < 2)
	    return;
	Workspace workspace = jWorkspaceView.getWorkspace ();
	if (isSpace)
	    workspace.storySpaceItem (items, isHorizontal, value);
	else
	    workspace.storyDistributeItem (items, isHorizontal, value);
    }

    public void align (Workspace.Alignment alignment) {
	JWorkspaceView<?> jWorkspaceView = jAdecWatt.getCurrentJWorkspace ();
	if (jWorkspaceView == null)
	    return;
	Vector<Item> items = jWorkspaceView.getSelectedItems ();
	if (items == null || items.size () < 2)
	    return;
	jWorkspaceView.getWorkspace ().storyAlignItem (items, alignment);
    }

    // ========================================
    public void actionManual () {
	try {
	    Desktop.getDesktop ().browse (Config.getDataUrl ("data", "texts", "help-"+misc.Bundle.getLocale (), "index.html").toURI ());
	} catch (Exception e) {
	    e.printStackTrace ();
	    manualDialog.restart ();
	    manualDialog.setVisible (true);
	}
    }

    private PrinterJob printer = null;
    private PageFormat page = null;

    public void actionPageSetup() {
        if (printer == null)
            printer = PrinterJob.getPrinterJob ();
	if (page == null)
	    page = printer.defaultPage ();
	page = printer.pageDialog (page);
	printer.defaultPage (page);
    }

    public void actionPrint () {
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
        if (printer == null)
            printer = PrinterJob.getPrinterJob ();
        if (!printer.printDialog ())
	    return;
	PrintWorkspace.print (jAdecWattDialog.getOwnFrame (), printer, currentWorkspace);
    }

    public void actionExportPDF () {
	Workspace currentWorkspace = jAdecWatt.getCurrentWorkspace ();
        if (printer == null)
            printer = PrinterJob.getPrinterJob ();
        if (!printer.printDialog ())
	    return;
	PrintWorkspace.print (jAdecWattDialog.getOwnFrame (), printer, currentWorkspace);
    }

    public void actionMagnetPolicies () {
	jAdecWattDialog.magnetPolicies (adecWatt);
    }

    public void actionPatch () {
	jAdecWattDialog.patch (jAdecWatt.getCurrentWorkspace ());
    }

    public void actionHttpServer () {
	remoteUpdateManager.getRemoteUpdate ().protocol = 
	    httpServerCB.isSelected () ? "http" :  protocol;
	Config.setBoolean ("HttpServer"+Config.checkedPostfix, httpServerCB.isSelected ());
	// XXX ???
        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier (new javax.net.ssl.HostnameVerifier () {
		public boolean verify (String hostname, javax.net.ssl.SSLSession session) {
		    return true;
		}
	    });
    }
    public void actionLocalServer () {
	remoteUpdateManager.getRemoteUpdate ().serverName =
	    localServerCB.isSelected () ? testedServerName : remoteServerName;

        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier (new javax.net.ssl.HostnameVerifier () {
		public boolean verify (String hostname, javax.net.ssl.SSLSession session) {
		    return true;
		}
	    });
    }
    public void actionTestedServer () {
	remoteUpdateManager.getRemoteUpdate ().versionName =
	    testedServerCB.isSelected () ? testedVersion : stableVersion;

        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier (new javax.net.ssl.HostnameVerifier () {
		public boolean verify (String hostname, javax.net.ssl.SSLSession session) {
		    return true;
		}
	    });
    }
    public void actionServerName () {
	String newServer = jAdecWattDialog.getSimpleMessage ("ServerName", testedServerName);
	if (newServer != null)
	    testedServerName = newServer;
    }
    public void actionWizard () {
	try {
	    System.err.println ("coucou: wizard");
	    java.net.URL newURL = Config.getDataUrl ("data", "texts", "help-"+misc.Bundle.getLocale (), "index.html");
	    System.err.println ("coucou file:"+newURL+" --- "+newURL.toURI ());

	    java.awt.Desktop.getDesktop ().browse (newURL.toURI ());
	    // XXX
	} catch (Exception e) {
	    e.printStackTrace ();
	}
    }

    // ========================================
    public void displayDisplayUnit (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?,?,?,?>> selectedUnits = (List<Editable<?,?,?,?>>) objects[0];
	jAdecWattDialog.display (false, selectedUnits);
    }
    public void displayModifyUnit (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?,?,?,?>> selectedUnits = (List<Editable<?,?,?,?>>) objects[0];
	jAdecWattDialog.display (true, selectedUnits);
    }
    public void displayRenameUnit (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?,?,?,?>> selectedUnits = (List<Editable<?,?,?,?>>) objects[0];
	if (selectedUnits.size () != 1) {
	    System.err.println ("coucou pb selectedUnits:"+selectedUnits);
	    return;
	}
	Unit<?> unit = (Unit<?>) selectedUnits.get (0);
	if (unit.getParent () == null)
	    return;
	String name = jAdecWattDialog.getName (unit.getName ());
	unit.storyTransform (null, null, name, null);
    }
    public void displayTransformUnit (Object... objects) {
	jAdecWattDialog.transform ((Unit<?>) objects[0]);
    }
    public void displayCopyUnit (Object... objects) {
	Unit<?> unit = (Unit<?>) objects[0];
	String name = jAdecWattDialog.getName (unit.getName ());
	if (name == null)
	    return;
	unit.getCopy (name);
    }
    public void displayNewUnit (Object... objects) {
	Unit<?> unit = (Unit<?>) objects[0];
	String name = jAdecWattDialog.getName (unit.getName ());
	if (name == null)
	    return;
	unit.getNewChild (name);
    }
    public void displayPromoteUnit (Object... objects) {
	Unit<?> unit = (Unit<?>) objects[0];
	ImageDB iconDB = adecWatt.getIconDB ();
	ImageDB imageDB = adecWatt.getImageDB ();
	HashSet<Unit<?>> units = new HashSet<Unit<?>> ();
	TreeSet<String> icons = new TreeSet<String> ();
	TreeSet<String> images = new TreeSet<String> ();
	unit.findPromote (units, icons, images);
	iconDB.renameVisitor (icons);
	imageDB.renameVisitor (images);
	permanentDB.renameVisitor (units);
	if (!jAdecWattDialog.validation ("PromoteConfirmation", unit.getLocalName (), unit.getLocation (),
					 units, icons, images))
	    return;
	iconDB.promote (icons);
	imageDB.promote (images);
	permanentDB.promote (units);
    }
    public void displayRemoveUnit (Object... objects) {
	Unit<?> unit = (Unit<?>) objects[0];
	if (!jAdecWattDialog.validation ("RemoveConfirmation", unit.getLocalName (), unit.getLocation ()))
	    return;
	unit.remove ();
    }
    public void displayConnection (Object... objects) {
	// XXX jAdecWatt.getJWorkspace ((Workspace) objects[0]).updateConnectionLayer ();
    }

    // ========================================
	
    public void displayDisplayItem (Object... objects) {
	@SuppressWarnings ("unchecked")
	    List<Editable<?, ?, ?, ?>> selectedItems = (List<Editable<?, ?, ?, ?>>) objects[0];
	jAdecWattDialog.display (false, selectedItems);
    }
    public void displayModifyItem (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?, ?, ?, ?>> selectedItems = (List<Editable<?, ?, ?, ?>>) objects[0];
	jAdecWattDialog.display (true, selectedItems);
    }
    public void displayHideShowItem (Object... objects) {
	JWorkspaceView<?> jWorkspaceView = (JWorkspaceView<?>) objects[0];
	@SuppressWarnings ("unchecked")
	    List<Item> selectedItems = (List<Item>) objects[1];
	Boolean hidden = (Boolean) objects[2];
	jWorkspaceView.hideShowItem (selectedItems, hidden);
    }
    public void displayTransformItem (Object... objects) {
	jAdecWattDialog.transform ((Item<?, ?, ?>) objects[0]);
    }
    public void displayCopyItem (Object... objects) {
	JWorkspaceView<?> jWorkspaceView = (JWorkspaceView<?>) objects[0];
	@SuppressWarnings ("unchecked")
	    List<Item> selectedItems = (List<Item>) objects[1];
	Point pos = (Point) objects[2];
	jWorkspaceView.cloneItem (selectedItems.get (0), pos);
    }
    public void displayRemoveItem (Object... objects) {
	JWorkspaceView<?> jWorkspaceView = (JWorkspaceView<?>) objects[0];
	@SuppressWarnings ("unchecked")
	    List<Item> selectedItems = (List<Item>) objects[1];
	jWorkspaceView.eraseItem (selectedItems);
    }
    @SuppressWarnings ("unchecked")
    public void displaySetSelectionItems (Object... objects) {
	try {
	    jAdecWatt.getJWorkspace ((Workspace) objects[0]).setSelectedItems ((List<Item>) objects[1]);
	} catch (Exception e) {
	}
    }

    // ========================================
    public void displayDisplayAcc (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?,?,?,?>> selectedAccs = (List<Editable<?,?,?,?>>) objects[0];
	jAdecWattDialog.display (false, selectedAccs);
    }
    public void displayModifyAcc (Object... objects) {
	@SuppressWarnings("unchecked")
	    List<Editable<?,?,?,?>> selectedAccs = (List<Editable<?,?,?,?>>) objects[0];
	jAdecWattDialog.display (true, selectedAccs);
    }
    public void displayTransformAcc (Object... objects) {
	jAdecWattDialog.transform ((Acc) objects[0]);
    }
    public void displayRemoveAcc (Object... objects) {
	JWorkspaceView<?> jWorkspaceView = (JWorkspaceView<?>) objects[0];
	Acc acc = (Acc) objects[1];
	jWorkspaceView.eraseAcc (acc);
    }

    // ========================================
    // private Editable<?, ?, ?, ?> lastSelection;
    // private Editable<?, ?, ?, ?> lastCopy;
    // public void displayEditableSelection (Object... objects) {
    // 	lastSelection = (Editable) objects[0];
    // }
    // YYY faire remove/copie/paste avec

    // ========================================
}

