package edu.washington.cs.oneswarm.ui.gwt.client.newui.friends.wizard;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
import com.google.gwt.gen2.table.client.FixedWidthGrid;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.datepicker.client.DatePicker;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmDialogBox;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmGWT;
import edu.washington.cs.oneswarm.ui.gwt.client.OneSwarmRPCClient;
import edu.washington.cs.oneswarm.ui.gwt.client.newui.HelpButton;
import edu.washington.cs.oneswarm.ui.gwt.rpc.FriendInvitationLite;
import edu.washington.cs.oneswarm.ui.gwt.rpc.StringTools;
public class InvitationViewPanel extends FriendsImportWithBack {
private final InvitationViewStep firstStep;
public InvitationViewPanel(FriendsImportCallback fwCallback) {
super();
this.fwCallback = fwCallback;
firstStep = new InvitationViewStep();
setFirstStep(firstStep);
}
public void refresh() {
firstStep.refresh();
}
private class InvitationViewStep extends FriendsImportWithBackStep {
private final VerticalPanel sentTablePanel = new VerticalPanel();
private final VerticalPanel redeemedTablePanel = new VerticalPanel();
public InvitationViewStep() {
/**
* The table for sent invitations
*/
Label sentLabel = new HTML(msg.add_friends_invite_view_sent_HTML());
sentLabel.addStyleName(FriendsImportWizard.CSS_DIALOG_HEADER);
sentLabel.setWidth(WIDTH + "px");
this.add(sentLabel);
sentTablePanel.setWidth(WIDTH + "px");
this.add(sentTablePanel);
/**
* The table for redeemed invitations
*/
Label redeemedLabel = new HTML(msg.add_friends_invite_view_redeemed_HTML());
redeemedLabel.addStyleName(FriendsImportWizard.CSS_DIALOG_HEADER);
redeemedLabel.setWidth(WIDTH + "px");
this.add(redeemedLabel);
redeemedTablePanel.setWidth(WIDTH + "px");
this.add(redeemedTablePanel);
}
public void refresh() {
sentTablePanel.clear();
OneSwarmRPCClient.getService().getSentFriendInvitations(
OneSwarmRPCClient.getSessionID(),
new AsyncCallback<ArrayList<FriendInvitationLite>>() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
public void onSuccess(ArrayList<FriendInvitationLite> result) {
FriendInvitationLite[] invitations = result
.toArray(new FriendInvitationLite[result.size()]);
if (invitations.length > 0) {
sentTablePanel.add(new InvitationTable(invitations, true) {
public void refresh() {
InvitationViewStep.this.refresh();
}
});
} else {
Label l = new Label(msg.add_friends_invite_view_no_sent());
sentTablePanel.add(l);
sentTablePanel.setCellHorizontalAlignment(l,
VerticalPanel.ALIGN_CENTER);
}
}
});
redeemedTablePanel.clear();
OneSwarmRPCClient.getService().getRedeemedFriendInvitations(
OneSwarmRPCClient.getSessionID(),
new AsyncCallback<ArrayList<FriendInvitationLite>>() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
public void onSuccess(ArrayList<FriendInvitationLite> result) {
FriendInvitationLite[] invitations = result
.toArray(new FriendInvitationLite[result.size()]);
if (invitations.length > 0) {
redeemedTablePanel.add(new InvitationTable(invitations, false) {
public void refresh() {
InvitationViewStep.this.refresh();
}
});
} else {
Label l = new Label(msg.add_friends_invite_view_no_redeemed());
redeemedTablePanel.add(l);
redeemedTablePanel.setCellHorizontalAlignment(l,
VerticalPanel.ALIGN_CENTER);
}
}
});
}
@Override
public FriendsImportWithBackStep createNextPanel() {
return null;
}
@Override
public String getNextButtonText() {
return msg.button_done();
}
}
private final FriendsImportCallback fwCallback;
private static class InvitationTable extends ScrollTable {
class FriendInvitationCheckBox extends CheckBox {
FriendInvitationLite f;
public FriendInvitationCheckBox(FriendInvitationLite f) {
super();
this.f = f;
}
public FriendInvitationLite getFriendInvitationLite() {
return f;
}
}
enum Column {
CHECKBOX("", 0, 10), NICKNAME(msg.add_friends_invite_view_table_nickname(), 1, 45), CREATED(
msg.add_friends_invite_view_table_created(), 2, 45), STATUS(msg
.add_friends_invite_view_table_status(), 3, 45), EXPIRES(msg
.add_friends_invite_view_table_expires(), 4, 45);
Column(String name, int column, int width) {
this.nickname = name;
this.width = width;
this.column = column;
}
final int width;
final int column;
final String nickname;
}
private ArrayList<FriendInvitationLite> getSelectedInvitations() {
ArrayList<FriendInvitationLite> out = new ArrayList<FriendInvitationLite>();
for (int i = 0; i < mData.getRowCount(); i++) {
FriendInvitationCheckBox cb = (FriendInvitationCheckBox) mData.getWidget(i, 0);
if (cb.getValue()) {
out.add(cb.f);
}
}
// for( int i=0; i<friends.length; i++ ) {
// if( selectors.get(i).getValue() ) {
// out.add(friends[i]);
// }
// }
return out;
}
public void removeClicked() {
ArrayList<FriendInvitationLite> selectedInvitations = getSelectedInvitations();
if (Window.confirm(msg.add_friends_invite_view_confirm_delete(selectedInvitations
.size()))) {
OneSwarmRPCClient.getService().deleteFriendInvitations(
OneSwarmRPCClient.getSessionID(), selectedInvitations,
new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
OneSwarmGWT.log("delete friend: got error");
}
public void onSuccess(Void result) {
OneSwarmGWT.log("friend deleted");
}
});
}
}
private final FixedWidthGrid mData;
private final FixedWidthFlexTable mHeader;
public InvitationTable(FriendInvitationLite[] invitations, boolean createdLocally) {
super(new FixedWidthGrid(0, createdLocally ? Column.values().length
: Column.values().length - 1), new FixedWidthFlexTable());
mData = getDataTable();
mHeader = getHeaderTable();
mData.setWidth("100%");
mHeader.setWidth("100%");
setScrollPolicy(ScrollPolicy.DISABLED);
mData.setSelectionPolicy(SelectionPolicy.MULTI_ROW);
setResizePolicy(ResizePolicy.FILL_WIDTH);
setupHeader(createdLocally);
TableListener listener = new TableListener() {
public void onCellClicked(SourcesTableEvents check, int row, int column) {
if (column >= 1) {
FriendInvitationLite invitation = ((FriendInvitationCheckBox) mData
.getWidget(row, 0)).f;
int width = InvitationTable.this.getOffsetWidth();
int height = InvitationTable.this.getOffsetHeight();
OneSwarmDialogBox dlg = new InvitationDialog(invitation, width, height) {
public void hide() {
refresh();
super.hide();
}
};
dlg.show();
dlg.setVisible(false);
dlg.center();
dlg.setPopupPosition(dlg.getAbsoluteLeft() + 40,
InvitationTable.this.getAbsoluteTop());
dlg.setVisible(true);
}
}
};
mData.addTableListener(listener);
for (int rowoffset = 0; rowoffset < invitations.length; rowoffset++) {
final FriendInvitationLite invitation = invitations[rowoffset];
FriendInvitationCheckBox selector = new FriendInvitationCheckBox(invitation);
mData.insertRow(rowoffset);
mData.setWidget(rowoffset, 0, selector);
mData.setText(rowoffset, Column.NICKNAME.column, invitation.getName());
mData.setText(rowoffset, Column.CREATED.column, StringTools.formatDateAppleLike(
new Date(invitation.getCreatedDate()), true));
String statusText = invitation.getStatusText();
mData.setText(rowoffset, Column.STATUS.column, statusText);
if (createdLocally) {
String expires;
if (invitation.getMaxAge() > 0) {
expires = StringTools.formatDateAppleLike(
new Date(invitation.getCreatedDate() + invitation.getMaxAge()),
true);
} else {
expires = "never";
}
mData.setText(rowoffset, 4, expires);
}
}
}
private void setupHeader(boolean useExpires) {
int numColumns = useExpires ? Column.values().length : Column.values().length - 1;
for (int i = 0; i < numColumns; i++) {
Column column = Column.values()[i];
mHeader.setText(0, i, column.nickname);
mHeader.setColumnWidth(i, column.width);
mData.setColumnWidth(i, column.width);
}
}
protected void refresh() {
}
}
@Override
protected void onLastBack() {
fwCallback.back();
}
@Override
protected void onLastNext() {
fwCallback.cancel();
}
static class InvitationDialog extends OneSwarmDialogBox {
private final Button cancelButton = new Button(msg.button_cancel());
private final Button saveButton = new Button(msg.button_save());
private final Button deleteButton = new Button(msg.add_friends_invite_view_delete());
private final InvitationDetailsPanel invPanel;
private final FriendInvitationLite invitation;
public InvitationDialog(FriendInvitationLite invitation, int width, int height) {
super(false, true, true);
this.invitation = invitation;
setText(msg.add_friends_invite_view_edit(invitation.getName()));
VerticalPanel p = new VerticalPanel();
invPanel = new InvitationDetailsPanel(invitation);
p.add(invPanel);
HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.setWidth("100%");
deleteButton.addClickHandler(this);
buttonPanel.add(deleteButton);
buttonPanel.setCellHorizontalAlignment(deleteButton, HorizontalPanel.ALIGN_LEFT);
HorizontalPanel okCancelPanel = new HorizontalPanel();
okCancelPanel.setSpacing(3);
cancelButton.addClickHandler(this);
okCancelPanel.add(cancelButton);
saveButton.addClickHandler(this);
okCancelPanel.add(saveButton);
buttonPanel.add(okCancelPanel);
buttonPanel.setCellHorizontalAlignment(okCancelPanel, HorizontalPanel.ALIGN_RIGHT);
p.add(buttonPanel);
super.setWidget(p);
super.setWidth(width + "px");
super.setHeight(height + "px");
}
public void onClick(ClickEvent event) {
if (event.getSource().equals(cancelButton)) {
hide();
} else if (event.getSource().equals(saveButton)) {
invPanel.save();
} else if (event.getSource().equals(deleteButton)) {
if (Window.confirm(msg.add_friends_invite_view_confirm_delete_single())) {
ArrayList<FriendInvitationLite> l = new ArrayList<FriendInvitationLite>();
l.add(invitation);
OneSwarmRPCClient.getService().deleteFriendInvitations(
OneSwarmRPCClient.getSessionID(), l, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
OneSwarmGWT.log("delete invite: got error");
}
public void onSuccess(Void result) {
OneSwarmGWT.log("invite deleted");
hide();
}
});
}
} else {
super.onClick(event);
}
}
class InvitationDetailsPanel extends VerticalPanel {
final TextBox nickBox = new TextBox();
final DatePickerTextBox expiresPicker;
private final FriendInvitationLite invitation;
public InvitationDetailsPanel(FriendInvitationLite invitation) {
this.invitation = invitation;
/**
* nickname
*/
HorizontalPanel nickPanel = new HorizontalPanel();
nickPanel.setSpacing(3);
nickPanel.setWidth(WIDTH + "px");
Label nickLabel = new Label(msg.friend_properties_nickname_label());
nickLabel.setWidth("100%");
nickPanel.add(nickLabel);
nickPanel.setCellVerticalAlignment(nickLabel, VerticalPanel.ALIGN_MIDDLE);
nickPanel.setCellWidth(nickLabel, "110px");
nickPanel.add(nickBox);
nickBox.setWidth("100%");
nickBox.setText(invitation.getName());
HelpButton nameHelp = new HelpButton(InvitationCreatePanel.FRIEND_INVITE_NAME_HELP);
nickPanel.add(nameHelp);
nickPanel.setCellVerticalAlignment(nameHelp, VerticalPanel.ALIGN_MIDDLE);
nickPanel.setCellHorizontalAlignment(nameHelp, HorizontalPanel.ALIGN_RIGHT);
this.add(nickPanel);
/**
* expires
*/
expiresPicker = new DatePickerTextBox(new Date(invitation.getCreatedDate()
+ invitation.getMaxAge()));
HorizontalPanel expiresPanel = new HorizontalPanel();
expiresPanel.setSpacing(3);
expiresPanel.setWidth(WIDTH + "px");
Label expiresLabel = new Label(msg.add_friends_invite_view_expires());
expiresLabel.setWidth("100%");
expiresPanel.add(expiresLabel);
expiresPanel.setCellVerticalAlignment(expiresLabel, VerticalPanel.ALIGN_MIDDLE);
expiresPanel.setCellWidth(expiresLabel, "110px");
expiresPanel.add(expiresPicker);
expiresPicker.setWidth("100%");
HelpButton expiresHelp = new HelpButton(msg.add_friends_invite_view_expires_help());
expiresPanel.add(expiresHelp);
expiresPanel.setCellVerticalAlignment(expiresHelp, VerticalPanel.ALIGN_MIDDLE);
expiresPanel.setCellHorizontalAlignment(expiresHelp, HorizontalPanel.ALIGN_RIGHT);
this.add(expiresPanel);
/**
* invitation key
*/
HTML invitationLabel = new HTML(msg.add_friends_invite_view_invitation_key());
invitationLabel.addStyleName(FriendsImportWizard.CSS_DIALOG_HEADER);
invitationLabel.setWidth(WIDTH + "px");
this.add(invitationLabel);
Label codeLabel = new Label("" + invitation.getKey());
codeLabel.addStyleName("friend_invitation-code");
codeLabel.addStyleName("friend_invitation-code-padding");
codeLabel.setWidth(WIDTH + "px");
this.add(codeLabel);
}
public void save() {
invitation.setName(nickBox.getText());
invitation.setMaxAge(Math.max(0,
expiresPicker.getValue().getTime() - invitation.getCreatedDate()));
OneSwarmRPCClient.getService().updateFriendInvitations(
OneSwarmRPCClient.getSessionID(), invitation, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
public void onSuccess(Void result) {
InvitationDialog.this.hide();
}
});
}
}
}
static class DatePickerTextBox extends VerticalPanel {
DatePicker datePicker = new DatePicker();
public DatePickerTextBox(Date defaultValue) {
final TextBox expiresText = new TextBox();
expiresText.setWidth("100%");
expiresText.addStyleName("os-date-picker-label");
expiresText.setReadOnly(true);
final PopupPanel p = new PopupPanel(true);
p.add(datePicker);
p.addStyleName("os-date-picker-popup");
expiresText.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
p.setPopupPosition(expiresText.getAbsoluteLeft(), expiresText.getAbsoluteTop());
p.show();
}
});
// Set the value in the text box when the user selects a date
datePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
public void onValueChange(ValueChangeEvent<Date> event) {
Date date = event.getValue();
String dateString = StringTools.formatDateAppleLike(date, true);
expiresText.setText(dateString);
p.hide();
}
});
// Set the default value
datePicker.setValue(defaultValue, true);
this.add(expiresText);
}
public Date getValue() {
return datePicker.getValue();
}
}
}