/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed 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.onebusaway.webapp.gwt.viewkit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.onebusaway.webapp.gwt.viewkit.resources.ViewKitCssResource;
import org.onebusaway.webapp.gwt.viewkit.resources.ViewKitResources;
import com.google.gwt.user.client.ui.Grid;
public class NavigationController extends ViewController {
private static final ViewKitCssResource _css = ViewKitResources.INSTANCE.getCSS();
private List<ViewController> _viewControllers = new ArrayList<ViewController>();
private Grid _panel = new Grid(2, 1);
private NavigationBar _navigationBar = new NavigationBar(this);
private boolean _visible = false;
public int getViewControllerCount() {
return _viewControllers.size();
}
public void pushViewController(ViewController viewController) {
// Force a view load, just in case
viewController.getView();
ViewController existingController = hasTop() ? peek() : null;
viewController.setNavigationController(this);
_viewControllers.add(viewController);
_navigationBar.pushNavigationItem(viewController.getNavigationItem());
swapView(existingController, viewController);
}
public void popToRootViewController() {
if (_viewControllers.size() < 2)
return;
ViewController oldViewContoller = pop();
while (_viewControllers.size() > 1)
pop();
ViewController newViewController = peek();
_navigationBar.popToRootNavigationItem();
swapView(oldViewContoller, newViewController);
}
public void popToViewController(ViewController controller) {
ViewController existingController = hasTop() ? peek() : null;
int index = _viewControllers.indexOf(controller);
if( index == -1) {
_viewControllers.clear();
_viewControllers.add(controller);
}
else {
while( index + 1 < _viewControllers.size())
pop();
}
swapView(existingController, controller);
}
public void popViewController() {
if (!hasTop())
return;
ViewController oldViewContoller = hasTop() ? pop() : null;
ViewController newViewController = hasTop() ? peek() : null;
_navigationBar.popNavigationItem();
swapView(oldViewContoller, newViewController);
}
public ViewController getPreviousController(ViewController controller) {
return getRelativeController(controller, 1);
}
public ViewController getNextController(ViewController controller) {
return getRelativeController(controller, 1);
}
/****
* {@link ViewController} Methods
****/
@Override
public void viewWillAppear() {
super.viewWillAppear();
if (hasTop())
peek().viewWillAppear();
}
@Override
public void viewDidAppear() {
super.viewDidAppear();
_visible = true;
if (hasTop())
peek().viewDidAppear();
}
@Override
public void viewWillDisappear() {
super.viewWillDisappear();
if (hasTop())
peek().viewWillDisappear();
}
@Override
public void viewDidDisappear() {
super.viewDidDisappear();
_visible = false;
if (hasTop())
peek().viewDidDisappear();
}
@Override
protected void loadView() {
super.loadView();
_panel.addStyleName(_css.NavigationController());
_panel.setWidget(0, 0, _navigationBar.getView());
_panel.getCellFormatter().addStyleName(0, 0,
_css.NavigationControllerNavigationBar());
_view = _panel;
}
@Override
protected void fireContextChangedEvent() {
NavigationController parent = getNavigationController();
if (parent != null)
parent.fireContextChangedEvent();
}
@Override
public void handleContext(List<String> path, Map<String, String> context) {
if( _viewControllers.isEmpty() )
return;
ViewController root = _viewControllers.get(0);
root.handleContext(path, context);
}
@Override
public void retrieveContext(List<String> path, Map<String, String> context) {
if( _viewControllers.isEmpty() )
return;
ViewController root = _viewControllers.get(0);
root.retrieveContext(path, context);
}
/****
* Private Methods
****/
private ViewController getRelativeController(ViewController controller, int offset) {
int index = _viewControllers.indexOf(controller);
if( index == -1)
return null;
index += offset;
if( index < 0 || _viewControllers.size() <= index)
return null;
return _viewControllers.get(index);
}
private void swapView(ViewController from, ViewController to) {
if( from != null && from.equals(to))
return;
if (_visible) {
if (from != null)
from.viewWillDisappear();
if (to != null)
to.viewWillAppear();
}
if (to != null) {
_panel.setWidget(1, 0, to.getView());
} else {
_panel.setText(1, 0, "");
}
if (_visible) {
if (from != null)
from.viewDidDisappear();
if (to != null)
to.viewDidAppear();
}
fireContextChangedEvent();
}
private boolean hasTop() {
return !_viewControllers.isEmpty();
}
private ViewController peek() {
return _viewControllers.get(_viewControllers.size() - 1);
}
private ViewController pop() {
return _viewControllers.remove(_viewControllers.size() - 1);
}
}