package jadex.tools.convcenter;
import jadex.base.fipa.SFipa;
import jadex.base.gui.componenttree.ComponentTreePanel;
import jadex.base.gui.componenttree.IActiveComponentTreeNode;
import jadex.base.gui.componenttree.IComponentTreeNode;
import jadex.base.gui.componenttree.INodeHandler;
import jadex.base.gui.plugin.AbstractJCCPlugin;
import jadex.bdi.runtime.AgentEvent;
import jadex.bdi.runtime.IBDIInternalAccess;
import jadex.bdi.runtime.IMessageEvent;
import jadex.bdi.runtime.IMessageEventListener;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IComponentManagementService;
import jadex.bridge.IComponentStep;
import jadex.bridge.IInternalAccess;
import jadex.commons.Properties;
import jadex.commons.SGUI;
import jadex.commons.concurrent.SwingDefaultResultListener;
import jadex.commons.service.SServiceProvider;
import jadex.tools.jcc.AgentControlCenter;
import jadex.tools.starter.StarterPlugin;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JSplitPane;
import javax.swing.UIDefaults;
import javax.swing.tree.TreePath;
/**
* The conversation plugin
*/
public class ConversationPlugin extends AbstractJCCPlugin
{
//-------- constants --------
/** The property storing the last state of the message panel. */
public static final String LAST_MESSAGE = "lastmessage";
/** The property storing sent messages (from 0..4). */
public static final String SENT_MESSAGE = "sentmessage";
// /** String used to store the message type in encoded messages. */
// public static final String ENCODED_MESSAGE_TYPE = "convcenter-encoded-message-type";
/** The image icons. */
protected static final UIDefaults icons = new UIDefaults(new Object[]
{
"conversation", SGUI.makeIcon(ConversationPlugin.class, "/jadex/tools/common/images/new_conversation.png"),
"message", SGUI.makeIcon(ConversationPlugin.class, "/jadex/tools/common/images/message_small.png"),
"message_overlay", SGUI.makeIcon(ConversationPlugin.class, "/jadex/tools/common/images/overlay_message.png"),
"conversation_sel", SGUI.makeIcon(StarterPlugin.class, "/jadex/tools/common/images/new_conversation_sel.png"),
"help", SGUI.makeIcon(ConversationPlugin.class, "/jadex/tools/common/images/help.gif"),
});
//-------- attributes --------
/** The agent tree table. */
protected ComponentTreePanel comptree;
/** The conversation center panel. */
protected FipaConversationPanel convcenter;
/**
* @return "Conversation Center"
* @see jadex.base.gui.plugin.IControlCenterPlugin#getName()
*/
public String getName()
{
return "Conversation Center";
}
/**
* @return the conversation icon
* @see jadex.base.gui.plugin.IControlCenterPlugin#getToolIcon()
*/
public Icon getToolIcon(boolean selected)
{
return selected? icons.getIcon("conversation_sel"): icons.getIcon("conversation");
}
final AbstractAction SEND_MESSAGE = new AbstractAction("Send Message", icons.getIcon("conversation"))
{
public void actionPerformed(ActionEvent e)
{
TreePath[] paths = comptree.getTree().getSelectionPaths();
for(int i=0; paths!=null && i<paths.length; i++)
{
if(paths[i].getLastPathComponent() instanceof IActiveComponentTreeNode)
{
final IActiveComponentTreeNode node = (IActiveComponentTreeNode)paths[i].getLastPathComponent();
final IComponentIdentifier rec = node.getDescription().getName();
// Use clone, as added component id might be modified by user.
SServiceProvider.getServiceUpwards(jcc.getServiceProvider(), IComponentManagementService.class).addResultListener(new SwingDefaultResultListener(comptree)
{
public void customResultAvailable(Object source, Object result)
{
IComponentManagementService cms = (IComponentManagementService)result;
IComponentIdentifier receiver = cms.createComponentIdentifier(rec.getName(), false, rec.getAddresses());
Map message = convcenter.getMessagePanel().getMessage();
IComponentIdentifier[] recs = (IComponentIdentifier[])message.get(SFipa.RECEIVERS);
List lrecs = recs!=null ? new ArrayList(Arrays.asList(recs)) : new ArrayList();
if(lrecs.contains(receiver))
{
lrecs.remove(receiver);
}
else
{
lrecs.add(receiver);
}
message.put(SFipa.RECEIVERS, (IComponentIdentifier[])lrecs.toArray(new IComponentIdentifier[lrecs.size()]));
convcenter.getMessagePanel().setMessage(message);
comptree.getModel().fireNodeChanged(node);
}
});
}
}
}
};
/**
* Create main panel.
* @return The main panel.
*/
public JComponent createView()
{
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
split.setOneTouchExpandable(true);
comptree = new ComponentTreePanel(getJCC().getServiceProvider());
comptree.setMinimumSize(new Dimension(0, 0));
split.add(comptree);
convcenter = new FipaConversationPanel(((AgentControlCenter)getJCC()).getAgent(), comptree);
comptree.addNodeHandler(new INodeHandler()
{
public Action[] getPopupActions(IComponentTreeNode[] nodes)
{
Action[] ret = null;
boolean allcomp = true;
for(int i=0; allcomp && i<nodes.length; i++)
{
allcomp = nodes[i] instanceof IActiveComponentTreeNode;
}
if(allcomp)
{
Action a = new AbstractAction((String)SEND_MESSAGE.getValue(Action.NAME), icons.getIcon("message"))
{
public void actionPerformed(ActionEvent e)
{
SEND_MESSAGE.actionPerformed(e);
}
};
ret = new Action[]{a};
}
return ret;
}
public Icon getOverlay(IComponentTreeNode node)
{
Icon ret = null;
if(node instanceof IActiveComponentTreeNode)
{
IComponentIdentifier id = ((IActiveComponentTreeNode)node).getDescription().getName();
IComponentIdentifier[] recs = (IComponentIdentifier[])convcenter.getMessagePanel().getReceivers();
if(recs!=null && Arrays.asList(recs).contains(id))
{
ret = icons.getIcon("message_overlay");
}
}
return ret;
}
public Action getDefaultAction(IComponentTreeNode node)
{
Action a = null;
if(node instanceof IActiveComponentTreeNode)
{
a = SEND_MESSAGE;
}
return a;
}
});
split.add(convcenter);
// SHelp.setupHelp(split, "tools.conversationcenter");
split.setDividerLocation(150);
final IMessageEventListener lis = new IMessageEventListener()
{
public void messageEventSent(AgentEvent ae)
{
// System.out.println("messageEventSent");
}
public void messageEventReceived(AgentEvent ae)
{
processMessage((IMessageEvent)ae.getSource());
}
};
((AgentControlCenter)getJCC()).getAgent().scheduleStep(new IComponentStep()
{
public Object execute(IInternalAccess ia)
{
IBDIInternalAccess scope = (IBDIInternalAccess)ia;
scope.getEventbase().addMessageEventListener("fipamsg", lis);
scope.getEventbase().addMessageEventListener("component_inform", lis);
return null;
}
});
// ((AgentControlCenter)jcc).getAgent().getEventbase().addMessageEventListener("component_inform", lis);
return split;
}
/**
* @param me
* @return true if the message event is not from tool_management ontology
*/
public void processMessage(final IMessageEvent message)
{
((AgentControlCenter)getJCC()).getAgent().scheduleStep(new IComponentStep()
{
public Object execute(IInternalAccess ia)
{
IBDIInternalAccess scope = (IBDIInternalAccess)ia;
Map msg = convcenter.createMessageMap(scope, message);
String onto = (String)msg.get(SFipa.ONTOLOGY);
if(onto==null || !onto.startsWith("jadex.tools"))
{
convcenter.addMessage(msg);
}
return null;
}
});
}
/**
* The actions.
*/
public JComponent[] createToolBar()
{
List components = new ArrayList();
JButton b = new JButton(SEND_MESSAGE);
b.setBorder(null);
b.setToolTipText(b.getText());
b.setText(null);
b.setEnabled(true);
components.add(b);
return (JComponent[])components.toArray((new JComponent[components.size()]));
}
/**
* Set properties loaded from project.
*/
public void setProperties(Properties props)
{
Properties ps = props.getSubproperty("convcenter");
if(ps!=null)
convcenter.setProperties(ps);
}
/**
* Return properties to be saved in project.
*/
public Properties getProperties()
{
Properties props = new Properties();
addSubproperties(props, "convcenter", convcenter.getProperties());
return props;
}
/**
* @return the help id of the perspective
* @see jadex.base.gui.plugin.AbstractJCCPlugin#getHelpID()
*/
public String getHelpID()
{
return "tools.conversationcenter";
}
/**
* Reset the conversation center to an initial state
*/
public void reset()
{
convcenter.reset();
}
/**
* Test if this plugin should be initialized lazily.
* @return True, if lazy.
*/
public boolean isLazy()
{
return false;
}
}