/**
* Copyright 2010 Google Inc.
*
* 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.waveprotocol.wave.client.wavepanel.block;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import org.waveprotocol.wave.client.common.util.MeasurerInstance;
import org.waveprotocol.wave.client.paging.Block;
import org.waveprotocol.wave.client.wavepanel.block.BlockStructure.Node;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.StringMap;
/**
* Exposes a view structure as pageable blocks.
*
*/
public final class PageableBlockStructure {
/**
* Wraps a structural node in order to provide behaviour.
* This is temporary until the pager is flyweighted.
*/
private class NodeImpl implements Block {
private final Node source;
private Element dom;
public NodeImpl(Node source) {
this.source = source;
}
@Override
public NodeImpl getParent() {
return adapt(source.getParent());
}
@Override
public NodeImpl getFirstChild() {
return adapt(source.getFirstChild());
}
@Override
public NodeImpl getLastChild() {
return adapt(source.getLastChild());
}
@Override
public NodeImpl getNextSibling() {
return adapt(source.getNextSibling());
}
@Override
public NodeImpl getPreviousSibling() {
return adapt(source.getPreviousSibling());
}
//
// Paging nature.
//
private Element getElement() {
if (dom == null) {
String domId = source.getId();
dom = Document.get().getElementById(domId);
if (dom == null) {
throw new RuntimeException("Block is missing: " + domId);
}
}
return dom;
}
@Override
public double getStart() {
return MeasurerInstance.get().top(getRoot().getElement(), getElement());
}
@Override
public double getEnd() {
return MeasurerInstance.get().bottom(getRoot().getElement(), getElement());
}
@Override
public void pageIn() {
handler.pageIn(source);
}
@Override
public void pageOut() {
handler.pageOut(source);
}
@Override
public double getChildrenOrigin() {
return 0;
}
}
public interface PageHandler {
void pageIn(Node block);
void pageOut(Node block);
}
private final StringMap<NodeImpl> nodes = CollectionUtils.createStringMap();
private final BlockStructure view;
private final PageHandler handler;
private PageableBlockStructure(PageHandler handler, BlockStructure view) {
this.handler = handler;
this.view = view;
}
public static PageableBlockStructure create(PageHandler handler, BlockStructure view) {
return new PageableBlockStructure(handler, view);
}
private NodeImpl adapt(Node source) {
if (source == null) {
return null;
}
String id = source.getId();
NodeImpl block = nodes.get(id);
if (block == null) {
block = new NodeImpl(source);
nodes.put(id, block);
}
return block;
}
public NodeImpl getRoot() {
return adapt(view.getRoot());
}
public NodeImpl getNode(String id) {
return adapt(view.getNode(id));
}
}