package comms.view.chat;
import java.util.ArrayList;
import java.util.Iterator;
import comms.model.chat.CallRequest;
import comms.model.chat.Conversation;
import comms.model.chat.Participant;
import comms.view.FeeddexApplication;
import comms.view.FeeddexPage;
import comms.view.FeeddexSession;
import comms.bus.CallRequestService;
import comms.bus.ChatService;
import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.AbstractReadOnlyModel;
/**
*
* This page contains a regular Wicket component showing the available agents and
* a separate component timer with AbstractAjaxTimerBehavior. This timer will
* will each time send a piece of JavaScript containing list of the current
* conversations and a function call to update the DOM to match this list.
*
*
* In this (awkward) way we try to avoid focus issues with popup windows originating from
* a dynamically created html element.
*
*
* NOTE: Just recently I learned that AjaxRequestTarget.setFocus(null) is supposed
* to avoid any focus issues. Maybe with that the whole script hassle could be avoided
*
*
*/
public class Conversations extends FeeddexPage implements IHeaderContributor {
//FIXME Check access to this page
// public Conversations( PageParameters pars ) {
// this( pars.getString( "service" ), pars.getString("participant"));
// }
public Conversations() {
this(FeeddexSession.get().getOrganisationId().toString(),
FeeddexSession.getMe().getChatName());
}
public Conversations(final String serviceId, final Object participant) {
add(createUpdater("timer", serviceId, participant));
add(createAvailableAgents("availableAgents", serviceId ));
}
private Component createAvailableAgents(String id, final String serviceId) {
final WebMarkupContainer agents = new WebMarkupContainer( id );
agents.setOutputMarkupId(true);
ListView list = new ListView( "list", new AbstractReadOnlyModel(){
@Override
public Object getObject() {
return new ArrayList(ChatService.getInstance(serviceId).getAvailableAgents());
}
} ){
@Override
protected void populateItem(final ListItem item) {
item.add( new Label( "agent", new AbstractReadOnlyModel() {
@Override
public Object getObject() {
return item.getModelObject().toString();
}
}));
}
};
agents.add( list );
WebMarkupContainer myAvailability = new WebMarkupContainer( "myAvailability" );
myAvailability.add(new Label("description", new AbstractReadOnlyModel() {
@Override
public Object getObject() {
String key = ChatService.getInstance(serviceId).isAvailable(
FeeddexSession.get().getChatParticipant()) ? "available"
: "not_available";
return getString(key);
}
}));
myAvailability.add(new AjaxLink("toggle") {
@Override
public void onClick(AjaxRequestTarget target) {
ChatService service = ChatService.getInstance(serviceId);
Participant participant = FeeddexSession.get().getChatParticipant();
service.setAvailable(participant, !service.isAvailable(participant));
target.addComponent(agents);
}
});
agents.add( myAvailability );
return agents;
}
/**
* An AjaxTimers that will return a list
* @param id
* @param serviceId
* @param participant
* @return
*/
private Component createUpdater(String id, final String serviceId,
final Object participant) {
Component timer = new WebMarkupContainer("timer");
timer.add(new AbstractAjaxTimerBehavior(ChatService.getPollInterval()) {
@Override
protected void onTimer(AjaxRequestTarget target) {
target.appendJavascript(createUpdateScript());
target.focusComponent(null);
}
private String createUpdateScript() {
StringBuffer buf = new StringBuffer();
appendConversationsUpdateScript(buf);
appendCallRequestsUpdateScript(buf);
return buf.toString();
}
private void appendConversationsUpdateScript(StringBuffer buf) {
String urlBase = FeeddexApplication.getUrlAgentChat()
+ "/service/" + serviceId + "/participant/"
+ participant + "/conversation/";
buf.append("var conversations = new Array(");
ChatService service = ChatService.getInstance(serviceId);
Iterator itr = service.getAllConversations()
.iterator();
if (itr.hasNext()) {
Conversation conversation = itr.next();
buf.append(toJavaScriptString(urlBase, conversation));
while (itr.hasNext()) {
buf.append(",");
conversation = itr.next();
buf.append(toJavaScriptString(urlBase, conversation));
}
}
buf.append(");");
buf.append("updateConversations('conversations', conversations );");
}
private void appendCallRequestsUpdateScript(StringBuffer buf) {
String urlBase = FeeddexApplication.getUrlCallRequest()
+ "/service/" + serviceId + "/transaction/";
buf.append("var callrequests = new Array(");
CallRequestService service = CallRequestService
.getInstance(serviceId);
Iterator itr = service.getAllCallRequests()
.iterator();
if (itr.hasNext()) {
CallRequest callrequest = itr.next();
buf.append(toJavaScriptString(urlBase, callrequest));
while (itr.hasNext()) {
buf.append(",");
callrequest = itr.next();
buf.append(toJavaScriptString(urlBase, callrequest));
}
}
buf.append(");");
buf
.append("updateCallrequests('callrequests', callrequests );");
}
private String toJavaScriptString(String urlBase,
Conversation conversation) {
return "{id:'" + conversation.getId() + "',url:'" + urlBase
+ conversation.getId() + "',name:'"
+ getDescription(conversation) + "',state:'" + "QUEUED"
+ // conversation.getStatus() +
"'}";
}
private String getDescription(Conversation conversation) {
return "Conversatie " + conversation.getId();
}
private String toJavaScriptString(String urlBase,
CallRequest callrequest) {
return "{id:'" + callrequest.getTransactionId() + "',url:'"
+ urlBase + callrequest.getTransactionId() + "',name:'"
+ getDescription(callrequest) + "'}";
}
private String getDescription(CallRequest callrequest) {
return "Call me (" + callrequest.getCreated() + ")"; // TODO
// Phone
// number
}
});
return timer;
}
public void renderHead(IHeaderResponse response) {
response.renderCSSReference(
new ResourceReference( this.getClass(), "Conversations.css"));
response.renderJavascriptReference(
new ResourceReference( this.getClass(), "Conversations.js"));
}
}