org.unitime.timetable.gwt.client.rooms.RoomFeaturesPage.java Source code

Java tutorial

Introduction

Here is the source code for org.unitime.timetable.gwt.client.rooms.RoomFeaturesPage.java

Source

/*
 * Licensed to The Apereo Foundation under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 *
 * The Apereo Foundation licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
*/
package org.unitime.timetable.gwt.client.rooms;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.unitime.timetable.gwt.client.Client;
import org.unitime.timetable.gwt.client.ToolBox;
import org.unitime.timetable.gwt.client.aria.AriaButton;
import org.unitime.timetable.gwt.client.events.AcademicSessionSelectionBox;
import org.unitime.timetable.gwt.client.page.UniTimeNotifications;
import org.unitime.timetable.gwt.client.page.UniTimePageHeader;
import org.unitime.timetable.gwt.client.page.UniTimePageLabel;
import org.unitime.timetable.gwt.client.rooms.RoomsPage.HistoryToken;
import org.unitime.timetable.gwt.client.rooms.RoomsTable.DeptMode;
import org.unitime.timetable.gwt.client.widgets.LoadingWidget;
import org.unitime.timetable.gwt.client.widgets.SimpleForm;
import org.unitime.timetable.gwt.client.widgets.UniTimeHeaderPanel;
import org.unitime.timetable.gwt.client.widgets.UniTimeTableHeader;
import org.unitime.timetable.gwt.client.widgets.FilterBox.Chip;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.MouseClickListener;
import org.unitime.timetable.gwt.client.widgets.UniTimeTable.TableEvent;
import org.unitime.timetable.gwt.command.client.GwtRpcResponse;
import org.unitime.timetable.gwt.command.client.GwtRpcResponseList;
import org.unitime.timetable.gwt.command.client.GwtRpcService;
import org.unitime.timetable.gwt.command.client.GwtRpcServiceAsync;
import org.unitime.timetable.gwt.resources.GwtConstants;
import org.unitime.timetable.gwt.resources.GwtMessages;
import org.unitime.timetable.gwt.resources.GwtResources;
import org.unitime.timetable.gwt.shared.AcademicSessionProvider;
import org.unitime.timetable.gwt.shared.AcademicSessionProvider.AcademicSessionChangeEvent;
import org.unitime.timetable.gwt.shared.AcademicSessionProvider.AcademicSessionChangeHandler;
import org.unitime.timetable.gwt.shared.EventInterface.EncodeQueryRpcRequest;
import org.unitime.timetable.gwt.shared.EventInterface.EncodeQueryRpcResponse;
import org.unitime.timetable.gwt.shared.EventInterface.FilterRpcRequest;
import org.unitime.timetable.gwt.shared.EventInterface.FilterRpcResponse;
import org.unitime.timetable.gwt.shared.EventInterface.SaveFilterDefaultRpcRequest;
import org.unitime.timetable.gwt.shared.RoomInterface.DepartmentInterface;
import org.unitime.timetable.gwt.shared.RoomInterface.ExamTypeInterface;
import org.unitime.timetable.gwt.shared.RoomInterface.FeatureInterface;
import org.unitime.timetable.gwt.shared.RoomInterface.RoomFeaturesColumn;
import org.unitime.timetable.gwt.shared.RoomInterface.RoomPropertiesInterface;
import org.unitime.timetable.gwt.shared.RoomInterface.RoomPropertiesRequest;
import org.unitime.timetable.gwt.shared.RoomInterface.RoomsPageMode;
import org.unitime.timetable.gwt.shared.RoomInterface.SearchRoomFeaturesRequest;

import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Cursor;
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.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.TakesValue;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Tomas Muller
 */
public class RoomFeaturesPage extends Composite {
    protected static final GwtMessages MESSAGES = GWT.create(GwtMessages.class);
    protected static final GwtResources RESOURCES = GWT.create(GwtResources.class);
    protected static final GwtConstants CONSTANTS = GWT.create(GwtConstants.class);
    protected static GwtRpcServiceAsync RPC = GWT.create(GwtRpcService.class);

    private AcademicSessionProvider iSession = null;
    private RoomFilterBox iFilter = null;
    private AriaButton iSearch = null;
    private AriaButton iNew = null;
    private AriaButton iMore = null;

    private SimpleForm iFeaturesPanel = null;
    private SimplePanel iRootPanel;

    private SimplePanel iPanel = null;
    private HorizontalPanel iFilterPanel = null;
    private RoomPropertiesInterface iProperties = null;
    private UniTimeHeaderPanel iGlobalFeaturesHeader = null;
    private RoomFeaturesTable iGlobalFeaturesTable = null;
    private int iGlobalFeaturesRow = -1;
    private UniTimeHeaderPanel iDepartmentalFeaturesHeader = null;
    private RoomFeaturesTable iDepartmentalFeaturesTable = null;
    private int iDepartmentalFeaturesRow = -1;
    private RoomsPageMode iMode = RoomsPageMode.COURSES;
    private UniTimeHeaderPanel iHeaderPanel = null;
    private HistoryToken iHistoryToken = null;

    private RoomFeatureEdit iRoomFeatureEdit = null;

    public RoomFeaturesPage() {
        if (Location.getParameter("mode") != null)
            iMode = RoomsPageMode.valueOf(Location.getParameter("mode").toUpperCase());
        iHistoryToken = new HistoryToken(iMode);

        iPanel = new SimplePanel();

        iFeaturesPanel = new SimpleForm();
        iFeaturesPanel.setWidth("100%");

        ClickHandler clickSearch = new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                changeUrl();
                search(null);
            }
        };

        ClickHandler clickMore = new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final PopupPanel popup = new PopupPanel(true);
                MenuBar menu = new UniTimeTableHeader.MenuBarWithAccessKeys();

                if (iProperties != null && iProperties.isCanSaveFilterDefaults()) {
                    MenuItem item = new MenuItem(MESSAGES.buttonClear(), true, new Command() {
                        @Override
                        public void execute() {
                            popup.hide();
                            iFilter.setValue(iHistoryToken.getDefaultParameter("q", ""), true);
                            hideResults();
                            changeUrl();
                        }
                    });
                    Roles.getMenuitemRole().setAriaLabelProperty(item.getElement(),
                            UniTimeHeaderPanel.stripAccessKey(MESSAGES.buttonClear()));
                    menu.addItem(item);
                    menu.addSeparator();
                }

                MenuBar sortItems = new MenuBar(true);
                for (final RoomFeaturesColumn column : RoomFeaturesColumn.values()) {
                    if (RoomFeaturesComparator.isApplicable(column)) {
                        if ((iGlobalFeaturesTable.getRowCount() <= 1
                                || iGlobalFeaturesTable.getNbrCells(column) == 0)
                                && (iDepartmentalFeaturesTable.getRowCount() <= 1
                                        || iDepartmentalFeaturesTable.getNbrCells(column) == 0))
                            continue;
                        String name = iGlobalFeaturesTable.getColumnName(column, 0).replace("<br>", " ");
                        MenuItem item = new MenuItem(name, true, new Command() {
                            @Override
                            public void execute() {
                                popup.hide();
                                int sortBy = RoomCookie.getInstance().getRoomFeaturesSortBy();
                                if (sortBy == (1 + column.ordinal()) || sortBy == (-1 - column.ordinal())) {
                                    sortBy = -sortBy;
                                } else {
                                    sortBy = 1 + column.ordinal();
                                }
                                RoomCookie.getInstance().setSortRoomFeaturesBy(sortBy);
                                iGlobalFeaturesTable.setSortBy(sortBy);
                                iDepartmentalFeaturesTable.setSortBy(sortBy);
                            }
                        });
                        Roles.getMenuitemRole().setAriaLabelProperty(item.getElement(),
                                UniTimeHeaderPanel.stripAccessKey(MESSAGES.opSortBy(name)));
                        sortItems.addItem(item);
                    }
                }
                MenuItem sortMenu = new MenuItem(MESSAGES.opSort(), sortItems);
                sortMenu.getElement().getStyle().setCursor(Cursor.POINTER);
                menu.addItem(sortMenu);

                MenuBar deptItems = new MenuBar(true);
                for (final DeptMode d : DeptMode.values()) {
                    String name = (RoomCookie.getInstance().getDeptMode() == d.ordinal()
                            ? MESSAGES.opUncheck(d.getName())
                            : MESSAGES.opCheck(d.getName()));
                    MenuItem item = new MenuItem(name, true, new Command() {
                        @Override
                        public void execute() {
                            popup.hide();
                            RoomCookie.getInstance().setDeptMode(d.ordinal());
                            iGlobalFeaturesTable.refreshTable();
                            iDepartmentalFeaturesTable.refreshTable();
                        }
                    });
                    Roles.getMenuitemRole().setAriaLabelProperty(item.getElement(), d.getName());
                    deptItems.addItem(item);
                }
                MenuItem deptMenu = new MenuItem(MESSAGES.opDepartmentFormat(), deptItems);
                deptMenu.getElement().getStyle().setCursor(Cursor.POINTER);
                menu.addItem(deptMenu);

                if (iProperties.isCanExportRoomFeatures()) {
                    menu.addSeparator();

                    MenuItem exportPdf = new MenuItem(MESSAGES.opExportPDF(), true, new Command() {
                        @Override
                        public void execute() {
                            popup.hide();
                            export("roomfeatures.pdf");
                        }
                    });
                    Roles.getMenuitemRole().setAriaLabelProperty(exportPdf.getElement(), MESSAGES.opExportPDF());
                    menu.addItem(exportPdf);

                    MenuItem exportCsv = new MenuItem(MESSAGES.opExportCSV(), true, new Command() {
                        @Override
                        public void execute() {
                            popup.hide();
                            export("roomfeatures.csv");
                        }
                    });
                    Roles.getMenuitemRole().setAriaLabelProperty(exportCsv.getElement(), MESSAGES.opExportCSV());
                    menu.addItem(exportCsv);
                }

                popup.add(menu);
                popup.showRelativeTo((UIObject) event.getSource());
                menu.focus();
            }
        };

        ClickHandler clickNew = new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                edit(null);
            }
        };

        iRoomFeatureEdit = new RoomFeatureEdit(iMode) {
            @Override
            protected void onShow() {
                RoomHint.hideHint();
                iRootPanel.setWidget(iRoomFeatureEdit);
                changeUrl();
            }

            @Override
            protected void onHide(boolean refresh, FeatureInterface feature) {
                iRootPanel.setWidget(iFeaturesPanel);
                UniTimePageLabel.getInstance().setPageName(MESSAGES.pageRoomFeatures());
                changeUrl();
                if (refresh && (iFeaturesPanel.getRowFormatter().isVisible(iGlobalFeaturesRow)
                        || iFeaturesPanel.getRowFormatter().isVisible(iDepartmentalFeaturesRow)))
                    search(feature == null ? null : feature.getId());
            }
        };

        if (iMode.hasSessionSelection()) {
            iHeaderPanel = new UniTimeHeaderPanel(MESSAGES.sectFilter());
            iFeaturesPanel.addHeaderRow(iHeaderPanel);

            iSession = new AcademicSessionSelectionBox(iHistoryToken.getParameter("term"), "RoomFeatures") {
                @Override
                protected void onInitializationSuccess(List<AcademicSession> sessions) {
                    UniTimePageHeader.getInstance().getRight().setVisible(false);
                    UniTimePageHeader.getInstance().getRight().setPreventDefault(true);
                    setup(getAcademicSessionId(), CONSTANTS.searchWhenPageIsLoaded()
                            && (iHistoryToken.hasParameter("id") || iHistoryToken.hasParameter("q")));
                }

                @Override
                protected void onInitializationFailure(Throwable caught) {
                    UniTimeNotifications.error(MESSAGES.failedLoadSessions(caught.getMessage()), caught);
                }
            };
            iSession.addAcademicSessionChangeHandler(new AcademicSessionChangeHandler() {
                @Override
                public void onAcademicSessionChange(AcademicSessionChangeEvent event) {
                    setup(event.getNewAcademicSessionId(),
                            iDepartmentalFeaturesTable.getRowCount() > 1 || iGlobalFeaturesTable.getRowCount() > 1);
                }
            });
            ;
            iFeaturesPanel.addRow(MESSAGES.propAcademicSession(), (Widget) iSession);

            iFilter = new RoomFilterBox(iSession);
            iFeaturesPanel.addRow(MESSAGES.propRoomFilter(), iFilter);

            iHeaderPanel.addButton("search", MESSAGES.buttonSearch(), clickSearch);
            iHeaderPanel.addButton("more", MESSAGES.buttonMoreOperations(), clickMore);
            iHeaderPanel.addButton("new", MESSAGES.buttonAddNewRoom(), clickNew);
            iHeaderPanel.setEnabled("more", false);
            iHeaderPanel.setEnabled("new", false);
        } else {
            iFilterPanel = new HorizontalPanel();
            iFilterPanel.setSpacing(3);

            Label filterLabel = new Label(MESSAGES.propFilter());
            iFilterPanel.add(filterLabel);
            iFilterPanel.setCellVerticalAlignment(filterLabel, HasVerticalAlignment.ALIGN_MIDDLE);

            iSession = new Session();
            iFilter = new RoomFilterBox(iSession);
            iFilterPanel.add(iFilter);

            iSearch = new AriaButton(MESSAGES.buttonSearch());
            iSearch.addStyleName("unitime-NoPrint");
            iSearch.addClickHandler(clickSearch);
            iFilterPanel.add(iSearch);

            iMore = new AriaButton(MESSAGES.buttonMoreOperations());
            iMore.setEnabled(false);
            iMore.addStyleName("unitime-NoPrint");
            iMore.addClickHandler(clickMore);
            iFilterPanel.add(iMore);

            iNew = new AriaButton(MESSAGES.buttonAddNewRoomFeature());
            iNew.setEnabled(false);
            iNew.addStyleName("unitime-NoPrint");
            iNew.addClickHandler(clickNew);
            iFilterPanel.add(iNew);

            int filterRow = iFeaturesPanel.addRow(iFilterPanel);
            iFeaturesPanel.getCellFormatter().setHorizontalAlignment(filterRow, 0,
                    HasHorizontalAlignment.ALIGN_CENTER);

            setup(null, CONSTANTS.searchWhenPageIsLoaded()
                    && (iHistoryToken.hasParameter("id") || iHistoryToken.hasParameter("q")));
        }

        iGlobalFeaturesHeader = new UniTimeHeaderPanel(MESSAGES.headerGlobalRoomFeatures());
        iGlobalFeaturesRow = iFeaturesPanel.addHeaderRow(iGlobalFeaturesHeader);
        iGlobalFeaturesTable = new RoomFeaturesTable(true) {
            protected void doSort(RoomFeaturesColumn column) {
                super.doSort(column);
                iDepartmentalFeaturesTable.setSortBy(RoomCookie.getInstance().getRoomFeaturesSortBy());
            }
        };
        iFeaturesPanel.addRow(iGlobalFeaturesTable);
        iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow, false);
        iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow + 1, false);

        iDepartmentalFeaturesHeader = new UniTimeHeaderPanel(MESSAGES.headerDepartmentalRoomFeatures());
        iDepartmentalFeaturesRow = iFeaturesPanel.addHeaderRow(iDepartmentalFeaturesHeader);
        iDepartmentalFeaturesTable = new RoomFeaturesTable(false) {
            protected void doSort(RoomFeaturesColumn column) {
                super.doSort(column);
                iGlobalFeaturesTable.setSortBy(RoomCookie.getInstance().getRoomFeaturesSortBy());
            }
        };
        iFeaturesPanel.addRow(iDepartmentalFeaturesTable);
        iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow, false);
        iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow + 1, false);

        iRootPanel = new SimplePanel(iFeaturesPanel);
        iPanel.setWidget(iRootPanel);

        iGlobalFeaturesTable.addMouseClickListener(new MouseClickListener<FeatureInterface>() {
            @Override
            public void onMouseClick(final TableEvent<FeatureInterface> event) {
                if (event.getData() != null && (event.getData().canEdit() || event.getData().canDelete()))
                    edit(event.getData());
            }
        });

        iDepartmentalFeaturesTable.addMouseClickListener(new MouseClickListener<FeatureInterface>() {
            @Override
            public void onMouseClick(final TableEvent<FeatureInterface> event) {
                if (event.getData() != null && (event.getData().canEdit() || event.getData().canDelete()))
                    edit(event.getData());
            }
        });

        initWidget(iPanel);

        History.addValueChangeHandler(new ValueChangeHandler<String>() {
            @Override
            public void onValueChange(ValueChangeEvent<String> event) {
                if (!iInitialized)
                    return;
                iHistoryToken.reset(event.getValue());
                updateFilter(iFeaturesPanel.getRowFormatter().isVisible(iGlobalFeaturesRow)
                        || iFeaturesPanel.getRowFormatter().isVisible(iDepartmentalFeaturesRow));
            }
        });
    }

    private void edit(FeatureInterface feature) {
        if (iRoomFeatureEdit == null)
            return;
        Chip dept = iFilter.getChip("department");
        iRoomFeatureEdit.setFeature(feature, dept == null ? null : dept.getValue());
        LoadingWidget.execute(iFilter.getElementsRequest(), new AsyncCallback<FilterRpcResponse>() {
            @Override
            public void onFailure(Throwable caught) {
                iFilter.setErrorHint(MESSAGES.failedToLoadRooms(caught.getMessage()));
                UniTimeNotifications.error(MESSAGES.failedToLoadRooms(caught.getMessage()), caught);
            }

            @Override
            public void onSuccess(FilterRpcResponse result) {
                iFilter.clearHint();
                if (result == null || result.getResults() == null || result.getResults().isEmpty()) {
                    iFilter.setErrorHint(MESSAGES.errorNoRoomsMatchingFilter());
                } else {
                    iRoomFeatureEdit.setRooms(result.getResults());
                    iRoomFeatureEdit.show();
                }
            }
        }, MESSAGES.waitLoadingRooms());

    }

    private boolean iInitialized = false;

    protected void setup(final Long sessionId, final boolean search) {
        LoadingWidget.getInstance().show(MESSAGES.waitLoadingPage());
        RPC.execute(new RoomPropertiesRequest(sessionId, iMode.name()),
                new AsyncCallback<RoomPropertiesInterface>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        LoadingWidget.getInstance().hide();
                        iFilter.setErrorHint(MESSAGES.failedToInitialize(caught.getMessage()));
                        UniTimeNotifications.error(MESSAGES.failedToInitialize(caught.getMessage()), caught);
                        ToolBox.checkAccess(caught);
                    }

                    @Override
                    public void onSuccess(RoomPropertiesInterface result) {
                        LoadingWidget.getInstance().hide();
                        iProperties = result;
                        iRoomFeatureEdit.setProperties(iProperties);

                        if (iProperties.isCanSaveFilterDefaults()) {
                            iHistoryToken.setDefaultParameter("q", result.getFilterDefault("filter"));
                            iFilter.setDefaultValueProvider(new TakesValue<String>() {
                                @Override
                                public void setValue(final String value) {
                                    RPC.execute(new SaveFilterDefaultRpcRequest(iMode.name() + ".filter",
                                            iFilter.getValue()), new AsyncCallback<GwtRpcResponse>() {
                                                @Override
                                                public void onFailure(Throwable caught) {
                                                    UniTimeNotifications.error(
                                                            MESSAGES.failedSaveAsDefault(caught.getMessage()),
                                                            caught);
                                                }

                                                @Override
                                                public void onSuccess(GwtRpcResponse result) {
                                                    iHistoryToken.setDefaultParameter("q", value);
                                                }
                                            });
                                }

                                @Override
                                public String getValue() {
                                    return iHistoryToken.getDefaultParameter("q", "");
                                }
                            });
                        } else {
                            if (result.hasFilterDefault("filter"))
                                iHistoryToken.setDefaultParameter("q", result.getFilterDefault("filter"));
                            iFilter.setDefaultValueProvider(null);
                        }

                        if (iSession instanceof Session)
                            ((Session) iSession).fireChange();

                        if (iNew != null)
                            iNew.setEnabled(iProperties.isCanAddDepartmentalRoomFeature()
                                    || iProperties.isCanAddGlobalRoomFeature());
                        if (iHeaderPanel != null)
                            iHeaderPanel.setEnabled("new", iProperties.isCanAddDepartmentalRoomFeature()
                                    || iProperties.isCanAddGlobalRoomFeature());

                        if (sessionId != null && iSession instanceof AcademicSessionSelectionBox) {
                            iHistoryToken.setParameter("term",
                                    ((AcademicSessionSelectionBox) iSession).getAcademicSessionAbbreviation());
                            iHistoryToken.mark();
                        }
                        updateFilter(search);
                        iInitialized = true;
                    }
                });
    }

    protected void updateFilter(boolean search) {
        iFilter.setValue(iHistoryToken.getParameter("q"), true);
        if (iSession instanceof AcademicSessionSelectionBox
                && iHistoryToken.isChanged("term",
                        ((AcademicSessionSelectionBox) iSession).getAcademicSessionAbbreviation())
                && iHistoryToken.getParameter("term") != null)
            ((AcademicSessionSelectionBox) iSession).selectSession(iHistoryToken.getParameter("term"), null);
        if (iHistoryToken.hasParameter("id")) {
            String id = iHistoryToken.getParameter("id");
            if ("add".equals(id)) {
                if (iProperties != null && (iProperties.isCanAddDepartmentalRoomFeature()
                        || iProperties.isCanAddGlobalRoomFeature()))
                    edit(null);
            } else {
                if (iGlobalFeaturesTable != null)
                    for (FeatureInterface g : iGlobalFeaturesTable.getData())
                        if (g.getId().toString().equals(id) && (g.canEdit() || g.canDelete()))
                            edit(g);
                if (iDepartmentalFeaturesTable != null)
                    for (FeatureInterface g : iDepartmentalFeaturesTable.getData())
                        if (g.getId().toString().equals(id) && (g.canEdit() || g.canDelete()))
                            edit(g);
            }
        } else if (iRoomFeatureEdit.equals(iRootPanel.getWidget()))
            iRoomFeatureEdit.hide();
        else if (search)
            search(null);
    }

    protected void changeUrl() {
        iHistoryToken.reset(null);
        if (iSession instanceof AcademicSessionSelectionBox)
            iHistoryToken.setParameter("term",
                    ((AcademicSessionSelectionBox) iSession).getAcademicSessionAbbreviation());
        if (iRoomFeatureEdit.equals(iRootPanel.getWidget()))
            iHistoryToken.setParameter("id", iRoomFeatureEdit.getFeature().getId() == null ? "add"
                    : iRoomFeatureEdit.getFeature().getId().toString());
        iHistoryToken.setParameter("q", iFilter.getValue());
        iHistoryToken.mark();
        Client.fireGwtPageChanged(new Client.GwtPageChangeEvent());
    }

    protected void hideResults() {
        if (iMore != null)
            iMore.setEnabled(false);
        if (iHeaderPanel != null)
            iHeaderPanel.setEnabled("more", false);
        iGlobalFeaturesTable.clearTable(1);
        iDepartmentalFeaturesTable.clearTable(1);
        iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow, false);
        iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow + 1, false);
        iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow, false);
        iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow + 1, false);
    }

    protected void search(final Long featureId) {
        hideResults();
        SearchRoomFeaturesRequest request = new SearchRoomFeaturesRequest(iProperties.getAcademicSessionId());
        request.setFilter(iFilter.getElementsRequest());
        LoadingWidget.execute(request, new AsyncCallback<GwtRpcResponseList<FeatureInterface>>() {
            @Override
            public void onFailure(Throwable caught) {
                iFilter.setErrorHint(MESSAGES.failedToLoadRoomFeatures(caught.getMessage()));
                UniTimeNotifications.error(MESSAGES.failedToLoadRoomFeatures(caught.getMessage()), caught);
            }

            @Override
            public void onSuccess(GwtRpcResponseList<FeatureInterface> result) {
                iFilter.clearHint();
                if (result == null || result.isEmpty()) {
                    iFilter.setErrorHint(MESSAGES.errorNoRoomFeatures());
                } else {
                    Chip dept = iFilter.getChip("department");
                    boolean skipDepartmental = false;
                    DepartmentInterface department = null;
                    if (dept != null) {
                        for (ExamTypeInterface type : iProperties.getExamTypes())
                            if (type.getReference().equals(dept.getValue())) {
                                skipDepartmental = true;
                                break;
                            }
                        for (DepartmentInterface d : iProperties.getDepartments())
                            if (dept.getValue().equals(d.getDeptCode())) {
                                department = d;
                                break;
                            }
                    }
                    for (FeatureInterface Feature : result) {
                        if (Feature.isDepartmental()) {
                            if (skipDepartmental)
                                continue;
                            if (department != null && !department.equals(Feature.getDepartment()))
                                continue;
                            if (dept == null && !Feature.hasRooms())
                                continue;
                            iDepartmentalFeaturesTable.addFeature(Feature);
                        } else {
                            iGlobalFeaturesTable.addFeature(Feature);
                        }
                    }
                    iDepartmentalFeaturesTable.sort();
                    iGlobalFeaturesTable.sort();
                }
                if (iMore != null)
                    iMore.setEnabled(
                            iDepartmentalFeaturesTable.getRowCount() > 1 || iGlobalFeaturesTable.getRowCount() > 1);
                if (iHeaderPanel != null)
                    iHeaderPanel.setEnabled("more",
                            iDepartmentalFeaturesTable.getRowCount() > 1 || iGlobalFeaturesTable.getRowCount() > 1);
                iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow,
                        iGlobalFeaturesTable.getRowCount() > 1);
                iFeaturesPanel.getRowFormatter().setVisible(iGlobalFeaturesRow + 1,
                        iGlobalFeaturesTable.getRowCount() > 1);
                iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow,
                        iDepartmentalFeaturesTable.getRowCount() > 1);
                iFeaturesPanel.getRowFormatter().setVisible(iDepartmentalFeaturesRow + 1,
                        iDepartmentalFeaturesTable.getRowCount() > 1);
                iDepartmentalFeaturesTable.scrollTo(featureId);
                iGlobalFeaturesTable.scrollTo(featureId);
            }
        }, MESSAGES.waitLoadingRoomFeatures());
    }

    protected void export(String format) {
        RPC.execute(EncodeQueryRpcRequest.encode(query(format)), new AsyncCallback<EncodeQueryRpcResponse>() {
            @Override
            public void onFailure(Throwable caught) {
            }

            @Override
            public void onSuccess(EncodeQueryRpcResponse result) {
                ToolBox.open(GWT.getHostPageBaseURL() + "export?q=" + result.getQuery());
            }
        });
    }

    protected String query(String format) {
        RoomCookie cookie = RoomCookie.getInstance();
        String query = "output=" + format + "&sort=" + cookie.getRoomsSortBy()
                + (cookie.hasMode() ? "&mode=" + cookie.getMode() : "") + "&dm=" + cookie.getDeptMode();
        if (iProperties.getAcademicSessionId() != null)
            query += "&sid=" + iProperties.getAcademicSessionId();

        FilterRpcRequest rooms = iFilter.getElementsRequest();
        if (rooms.hasOptions()) {
            for (Map.Entry<String, Set<String>> option : rooms.getOptions().entrySet()) {
                for (String value : option.getValue()) {
                    query += "&r:" + option.getKey() + "=" + URL.encodeQueryString(value);
                }
            }
        }

        if (rooms.getText() != null && !rooms.getText().isEmpty())
            query += "&r:text=" + URL.encodeQueryString(rooms.getText());

        return query;
    }

    private class Session implements AcademicSessionProvider {
        private List<AcademicSessionChangeHandler> iHandlers = new ArrayList<AcademicSessionProvider.AcademicSessionChangeHandler>();

        private Session() {
        }

        @Override
        public void selectSession(Long sessionId, AsyncCallback<Boolean> callback) {
            callback.onSuccess(false);
        }

        @Override
        public String getAcademicSessionName() {
            return iProperties == null ? null : iProperties.getAcademicSessionName();
        }

        @Override
        public Long getAcademicSessionId() {
            return iProperties == null ? null : iProperties.getAcademicSessionId();
        }

        @Override
        public void addAcademicSessionChangeHandler(AcademicSessionChangeHandler handler) {
            iHandlers.add(handler);
        }

        @Override
        public AcademicSessionInfo getAcademicSessionInfo() {
            return null;
        }

        protected void fireChange() {
            AcademicSessionProvider.AcademicSessionChangeEvent event = new AcademicSessionProvider.AcademicSessionChangeEvent() {
                @Override
                public Long getNewAcademicSessionId() {
                    return iProperties == null ? null : iProperties.getAcademicSessionId();
                }

                @Override
                public Long getOldAcademicSessionId() {
                    return null;
                }

                @Override
                public boolean isChanged() {
                    return true;
                }
            };
            for (AcademicSessionChangeHandler h : iHandlers)
                h.onAcademicSessionChange(event);
        }
    }
}