package kornell.gui.client.presentation.bar.generic;
import static kornell.core.util.StringUtils.mkurl;
import com.github.gwtbootstrap.client.ui.Icon;
import com.github.gwtbootstrap.client.ui.ProgressBar;
import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import kornell.api.client.KornellSession;
import kornell.core.entity.CourseClassState;
import kornell.core.entity.EnrollmentState;
import kornell.core.to.CourseClassTO;
import kornell.core.to.UserInfoTO;
import kornell.core.util.StringUtils;
import kornell.gui.client.ClientFactory;
import kornell.gui.client.KornellConstants;
import kornell.gui.client.event.HideSouthBarEvent;
import kornell.gui.client.event.NavigationAuthorizationEvent;
import kornell.gui.client.event.NavigationAuthorizationEventHandler;
import kornell.gui.client.event.ProgressEvent;
import kornell.gui.client.event.ProgressEventHandler;
import kornell.gui.client.event.ShowChatDockEvent;
import kornell.gui.client.event.ShowChatDockEventHandler;
import kornell.gui.client.event.ShowDetailsEvent;
import kornell.gui.client.event.ShowDetailsEventHandler;
import kornell.gui.client.mvp.HistoryMapper;
import kornell.gui.client.presentation.bar.ActivityBarView;
import kornell.gui.client.presentation.classroom.generic.notes.NotesPopup;
import kornell.gui.client.sequence.NavigationRequest;
import kornell.gui.client.util.ClientConstants;
public class GenericActivityBarView extends Composite implements ActivityBarView, ProgressEventHandler,
ShowDetailsEventHandler, ShowChatDockEventHandler, NavigationAuthorizationEventHandler {
interface MyUiBinder extends UiBinder<Widget, GenericActivityBarView> {
}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
private String page;
private NotesPopup notesPopup;
private FlowPanel progressBarPanel;
private final HistoryMapper historyMapper = GWT.create(HistoryMapper.class);
private static KornellConstants constants = GWT.create(KornellConstants.class);
private static String BUTTON_PREVIOUS = constants.previous();
private static String BUTTON_NEXT = constants.next();
private static String BUTTON_DETAILS = constants.details();
private static String BUTTON_NOTES = constants.notes();
private static String BUTTON_CHAT = constants.chat();
private boolean showDetails = true;
private boolean chatDockEnabled = false;
private boolean enableNext = false;
private boolean enablePrev = false;
private boolean allowedNext = false;
private boolean allowedPrev = false;
@UiField
FocusPanel btnPrevious;
@UiField
FocusPanel btnNext;
@UiField
FocusPanel btnDetails;
@UiField
FocusPanel btnNotes;
@UiField
FocusPanel btnChat;
@UiField
FocusPanel btnProgress;
@UiField
FlowPanel activityBar;
private UserInfoTO user;
private ClientFactory clientFactory;
private Integer currentPage = 0, totalPages = 0, progressPercent = 0;
private boolean shouldShowActivityBar, isEnrolled;
private KornellSession session;
public GenericActivityBarView(ClientFactory clientFactory) {
this.clientFactory = clientFactory;
initWidget(uiBinder.createAndBindUi(this));
clientFactory.getEventBus().addHandler(ProgressEvent.TYPE, this);
clientFactory.getEventBus().addHandler(ShowDetailsEvent.TYPE, this);
clientFactory.getEventBus().addHandler(ShowChatDockEvent.TYPE, this);
clientFactory.getEventBus().addHandler(NavigationAuthorizationEvent.TYPE, this);
session = clientFactory.getKornellSession();
if (session.isAuthenticated()) {
user = clientFactory.getKornellSession().getCurrentUser();
}
display();
setupArrowsNavigation();
}
private void display() {
this.setVisible(false);
CourseClassTO courseClassTO = session.getCurrentCourseClass();
isEnrolled = courseClassTO != null && courseClassTO.getEnrollment() != null && EnrollmentState.enrolled.equals(courseClassTO.getEnrollment().getState());
shouldShowActivityBar = isEnrolled && session.getCurrentCourseClass() != null
&& !CourseClassState.inactive.equals(session.getCurrentCourseClass().getCourseClass().getState());
showDetails = !isEnrolled;
displayButton(btnPrevious, BUTTON_PREVIOUS, new Icon(IconType.CARET_LEFT));
displayButton(btnNext, BUTTON_NEXT, new Icon(IconType.CARET_RIGHT), true);
displayButton(btnDetails, showDetails ? constants.course() : BUTTON_DETAILS,
new Icon(IconType.BOOK));
setupBtnDetailsEvent(showDetails);
Icon iconChat = new Icon();
iconChat.setStyleName("fa fa-comments");
displayButton(btnChat, BUTTON_CHAT, iconChat);
btnChat.addStyleName("activityBarButtonChat");
Icon iconNotes = new Icon();
iconNotes.setStyleName("fa fa-sticky-note-o");
displayButton(btnNotes, BUTTON_NOTES, iconNotes);
if (session.getCurrentCourseClass().getCourseClass().isCourseClassChatEnabled() &&
!session.getCurrentCourseClass().getCourseClass().isChatDockEnabled()) {
btnChat.addStyleName("activityBarButtonSmall");
btnNotes.addStyleName("activityBarButtonSmall");
btnChat.removeStyleName("shy");
} else {
btnChat.addStyleName("shy");
}
displayProgressButton();
if (showDetails) {
btnDetails.addStyleName("btnAction");
enableButton(BUTTON_PREVIOUS, false);
enableButton(BUTTON_NEXT, false);
}
}
private void setupBtnDetailsEvent(boolean showDetails) {
btnDetails.getElement().setId("btnClassroomDetails");
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
setupBtnDetailsEventNative();
}
});
}
private static native void setupBtnDetailsEventNative() /*-{
var btnClassroomDetails = $wnd.document.getElementById("btnClassroomDetails");
btnClassroomDetails.addEventListener("click", courseClassDetailsShown, false);
function courseClassDetailsShown(e) {
e.preventDefault();
var courseClassDetailsShown = $wnd.document.getElementsByClassName("courseClassDetailsShown").length > 0;
if (window.CustomEvent) {
var event = new CustomEvent("courseClassDetailsShown", {
detail: {
courseClassDetailsShown: courseClassDetailsShown,
time: new Date(),
},
bubbles: true,
cancelable: true
});
e.currentTarget.dispatchEvent(event);
}
}
}-*/;
private void displayProgressButton() {
progressBarPanel = new FlowPanel();
progressBarPanel.addStyleName("progressBarPanel");
btnProgress.add(progressBarPanel);
btnProgress.removeStyleName("btn");
btnProgress.removeStyleName("btn-link");
}
private void updateProgressBarPanel(Integer currentPage, Integer totalPages, Integer progressPercent) {
this.currentPage = currentPage;
this.totalPages = totalPages;
this.progressPercent = progressPercent;
updateProgressBarPanel();
}
private void updateProgressBarPanel() {
progressBarPanel.clear();
ProgressBar progressBar = new ProgressBar();
progressBar.setPercent(progressPercent);
FlowPanel pagePanel = new FlowPanel();
pagePanel.addStyleName("pagePanel");
pagePanel.addStyleName("activityBarButtonItem");
if (showDetails) {
pagePanel.add(createSpan(progressPercent + "%", true, false));
pagePanel.add(createSpan(constants.completed(), false, true));
} else {
pagePanel.add(createSpan(constants.pageForPagination(), false, true));
pagePanel.add(createSpan(currentPage == 0 ? "-" : "" + currentPage, true, false));
pagePanel.add(createSpan("/", false, false));
pagePanel.add(createSpan("" + totalPages, false, false));
}
progressBarPanel.add(pagePanel);
progressBarPanel.add(progressBar);
}
private HTMLPanel createSpan(String text, boolean isHighlighted, boolean hideWhenSmall) {
HTMLPanel pageCaption = new HTMLPanel(text);
pageCaption.addStyleName("marginLeft7");
if (isHighlighted) {
pageCaption.addStyleName("highlightText");
}
if (hideWhenSmall) {
pageCaption.addStyleName("hideSmall");
}
return pageCaption;
}
private void displayButton(final FocusPanel btn, final String buttonType, Icon icon) {
displayButton(btn, buttonType, icon, false);
}
private void displayButton(final FocusPanel btn, final String buttonType, Icon icon, boolean invertIcon) {
btn.clear();
FlowPanel buttonPanel = new FlowPanel();
buttonPanel.addStyleName("btnPanel");
buttonPanel.addStyleName(getItemName(buttonType));
icon.addStyleName("activityBarButtonItem font16");
Label label = new Label(buttonType.toUpperCase());
label.addStyleName("activityBarButtonItem label");
if (invertIcon) {
buttonPanel.add(label);
buttonPanel.add(icon);
} else {
buttonPanel.add(icon);
buttonPanel.add(label);
}
btn.add(buttonPanel);
}
private String getItemName(String constant) {
if (constant.equals(BUTTON_NEXT)) {
return "next";
} else if (constant.equals(BUTTON_PREVIOUS)) {
return "previous";
} else if (constant.equals(BUTTON_DETAILS)) {
return "details";
} else if (constant.equals(BUTTON_CHAT)) {
return "chat";
} else {
return "notes";
}
}
private static native void setupArrowsNavigation() /*-{
$doc.onkeydown = function() {
if ($wnd.event && $wnd.event.target
&& $wnd.event.target.nodeName != "TEXTAREA") {
switch ($wnd.event.keyCode) {
case 37: //LEFT ARROW
$doc.getElementsByClassName("btnPanel previous")[0].click();
break;
case 39: //RIGHT ARROW
$doc.getElementsByClassName("btnPanel next")[0].click();
break;
}
}
};
}-*/;
@UiHandler("btnNext")
public void btnNextClicked(ClickEvent e) {
if (!showDetails && btnNext.getStyleName().indexOf("disabled") < 0){
clientFactory.getEventBus().fireEvent(NavigationRequest.next());
clientFactory.getEventBus().fireEvent(new ShowChatDockEvent(chatDockEnabled));
}
}
@UiHandler("btnPrevious")
public void btnPrevClicked(ClickEvent e) {
if (!showDetails && btnPrevious.getStyleName().indexOf("disabled") < 0){
clientFactory.getEventBus().fireEvent(NavigationRequest.prev());
clientFactory.getEventBus().fireEvent(new ShowChatDockEvent(chatDockEnabled));
}
}
@UiHandler("btnNotes")
void handleClickBtnNotes(ClickEvent e) {
if (notesPopup == null) {
notesPopup = new NotesPopup(clientFactory.getKornellSession(), session.getCurrentCourseClass()
.getCourseClass().getUUID(), session.getCurrentCourseClass().getEnrollment().getNotes());
notesPopup.show();
} else {
notesPopup.show();
}
}
@UiHandler("btnChat")
void handleClickBtnChat(ClickEvent e) {
if(!(chatDockEnabled && session.getCurrentCourseClass().getCourseClass().isChatDockEnabled()) && !showDetails && btnChat.getStyleName().indexOf("disabled") < 0){
clientFactory.getEventBus().fireEvent(new ShowChatDockEvent(!chatDockEnabled));
}
}
private void enableButton(String btn, boolean enable) {
if (BUTTON_NEXT.equals(btn)) {
if (enable && !showDetails) {
btnNext.removeStyleName("disabled");
} else {
btnNext.addStyleName("disabled");
}
} else if (BUTTON_PREVIOUS.equals(btn)) {
if (enable && !showDetails) {
btnPrevious.removeStyleName("disabled");
} else {
btnPrevious.addStyleName("disabled");
}
} else if (BUTTON_CHAT.equals(btn)) {
if (enable && !showDetails) {
btnChat.removeStyleName("disabled");
} else {
btnChat.addStyleName("disabled");
}
}
}
@Override
public void setPresenter(Presenter presenter) {
}
@Override
public void onProgress(ProgressEvent event) {
boolean isMonoSCO = (event.getTotalPages() <= 1);
if (event.getCurrentPage() != 0) {
updateProgressBarPanel(event.getCurrentPage(), event.getTotalPages(), event.getProgressPercent());
enablePrev = event.hasPrevious();
enableNext = event.hasNext();
}
btnNext.setVisible(!isMonoSCO);
btnPrevious.setVisible(!isMonoSCO);
progressBarPanel.setVisible(!isMonoSCO);
if (isMonoSCO) {
btnDetails.addStyleName("firstMonoSCO");
btnNotes.addStyleName("last");
} else {
btnDetails.removeStyleName("firstMonoSCO");
btnNotes.removeStyleName("last");
}
shouldShowActivityBar = isEnrolled && session.getCurrentCourseClass() != null
&& !CourseClassState.inactive.equals(session.getCurrentCourseClass().getCourseClass().getState())
&& session.getCurrentCourseClass().getCourseVersionTO().getCourseVersion().getParentVersionUUID() == null;
clientFactory.getEventBus().fireEvent(new HideSouthBarEvent(!shouldShowActivityBar));
this.setVisible(shouldShowActivityBar);
}
@UiHandler("btnDetails")
void handleClickBtnDetails(ClickEvent e) {
if (shouldShowActivityBar)
clientFactory.getEventBus().fireEvent(new ShowDetailsEvent(!showDetails));
}
@Override
public void onShowDetails(ShowDetailsEvent event) {
this.showDetails = event.isShowDetails();
if (showDetails) {
clientFactory.getEventBus().fireEvent(new ShowChatDockEvent(false));
btnDetails.addStyleName("btnAction courseClassDetailsShown");
displayButton(btnDetails, constants.course(),
new Icon(IconType.BOOK));
} else {
if(!chatDockEnabled && session.getCurrentCourseClass() != null && session.getCurrentCourseClass().getCourseClass().isChatDockEnabled()){
clientFactory.getEventBus().fireEvent(new ShowChatDockEvent(true));
}
btnDetails.removeStyleName("btnAction");
btnDetails.removeStyleName("courseClassDetailsShown");
displayButton(btnDetails, BUTTON_DETAILS,
new Icon(IconType.BOOK));
}
enableButton(BUTTON_PREVIOUS, !showDetails && enablePrev && allowedPrev);
enableButton(BUTTON_NEXT, !showDetails && enableNext && allowedNext);
enableButton(BUTTON_CHAT, !showDetails);
updateProgressBarPanel();
}
@Override
public void onShowChatDock(ShowChatDockEvent event) {
this.chatDockEnabled = event.isShowChatDock();
if (chatDockEnabled) {
if(showDetails){
clientFactory.getEventBus().fireEvent(new ShowDetailsEvent(false));
}
btnChat.addStyleName("btnAction");
} else {
btnChat.removeStyleName("btnAction");
}
}
@Override
public void onNextActivityOK(NavigationAuthorizationEvent evt) {
allowedNext = true;
enableButton(BUTTON_NEXT, enableNext && allowedNext);
}
@Override
public void onNextActivityNotOK(NavigationAuthorizationEvent evt) {
allowedNext = false;
enableButton(BUTTON_NEXT, enableNext && allowedNext);
}
@Override
public void onPrevActivityOK(NavigationAuthorizationEvent evt) {
allowedPrev = true;
enableButton(BUTTON_PREVIOUS, enablePrev && allowedPrev);
}
@Override
public void onPrevActivityNotOK(NavigationAuthorizationEvent evt) {
allowedPrev = false;
enableButton(BUTTON_PREVIOUS, enablePrev && allowedPrev);
}
}