/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.layout.model.table;
import java.util.HashMap;
import org.pentaho.reporting.engine.classic.core.ReportAttributeMap;
import org.pentaho.reporting.engine.classic.core.filter.types.AutoLayoutBoxType;
import org.pentaho.reporting.engine.classic.core.layout.model.AutoRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.BlockRenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.LayoutNodeTypes;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderBox;
import org.pentaho.reporting.engine.classic.core.layout.model.RenderNode;
import org.pentaho.reporting.engine.classic.core.layout.model.context.BoxDefinition;
import org.pentaho.reporting.engine.classic.core.layout.model.table.columns.TableColumnModel;
import org.pentaho.reporting.engine.classic.core.layout.model.table.rows.SeparateRowModel;
import org.pentaho.reporting.engine.classic.core.layout.model.table.rows.TableRowModel;
import org.pentaho.reporting.engine.classic.core.layout.style.SimpleStyleSheet;
import org.pentaho.reporting.engine.classic.core.metadata.ElementType;
import org.pentaho.reporting.engine.classic.core.states.ReportStateKey;
import org.pentaho.reporting.engine.classic.core.style.BandStyleKeys;
import org.pentaho.reporting.engine.classic.core.style.StyleSheet;
import org.pentaho.reporting.engine.classic.core.util.InstanceID;
/**
* A table section box does not much rendering or layouting at all. It
* represents one of the three possible sections and behaves like any other
* block box. But (here it comes!) it refuses to be added to anything else than
* a TableRenderBox (a small check to save me a lot of insanity ..).
*
* @author Thomas Morgner
*/
public class TableSectionRenderBox extends BlockRenderBox
{
private static final int FLAG_TABLE_SECTION_STRUCTURE_VALIDATED = FLAG_BOX_TABLE_SECTION_RESERVED;
private static final int FLAG_TABLE_SECTION_ACTIVE = FLAG_BOX_TABLE_SECTION_RESERVED4;
private static final int FLAG_TABLE_SECTION_MARKED_ACTIVE = FLAG_BOX_TABLE_SECTION_RESERVED2;
private static final int FLAG_TABLE_SECTION_APPLIED_ACTIVE = FLAG_BOX_TABLE_SECTION_RESERVED3;
private Role displayRole;
private TableRowModel rowModel;
private HashMap<Long,Long> headerShift;
private HashMap<Long,Long> markedHeaderShift;
private HashMap<Long,Long> appliedHeaderShift;
private long rowModelAge;
public static enum Role
{
BODY, HEADER, FOOTER
}
public TableSectionRenderBox()
{
this(SimpleStyleSheet.EMPTY_STYLE, new InstanceID(), BoxDefinition.EMPTY,
AutoLayoutBoxType.INSTANCE, ReportAttributeMap.EMPTY_MAP, null);
}
public TableSectionRenderBox(final StyleSheet styleSheet,
final InstanceID instanceID,
final BoxDefinition boxDefinition,
final ElementType elementType,
final ReportAttributeMap attributes,
final ReportStateKey stateKey)
{
super(styleSheet, instanceID, boxDefinition, elementType, attributes, stateKey);
this.rowModel = new SeparateRowModel();
this.rowModel.setDebugInformation(elementType, instanceID);
this.appliedHeaderShift = new HashMap<Long, Long>();
this.markedHeaderShift = new HashMap<Long, Long>();
this.headerShift = new HashMap<Long, Long>();
final Object layoutMode = styleSheet.getStyleProperty(BandStyleKeys.LAYOUT);
if (BandStyleKeys.LAYOUT_TABLE_FOOTER.equals(layoutMode))
{
this.displayRole = Role.FOOTER;
}
else if (BandStyleKeys.LAYOUT_TABLE_HEADER.equals(layoutMode))
{
this.displayRole = Role.HEADER;
}
else
{
this.displayRole = Role.BODY;
}
}
public long getRowModelAge()
{
return rowModelAge;
}
public void setRowModelAge(final long rowModelAge)
{
this.rowModelAge = rowModelAge;
}
public boolean useMinimumChunkWidth()
{
return true;
}
public long getHeaderShift(final long pageOffset)
{
final Long retval = headerShift.get(pageOffset);
if (retval == null)
return 0;
return retval;
}
public void setHeaderShift(final long pageOffset, final long headerShift)
{
this.headerShift.put(pageOffset, headerShift);
}
public Object clone()
{
final TableSectionRenderBox clone = (TableSectionRenderBox) super.clone();
clone.headerShift = (HashMap<Long, Long>) headerShift.clone();
return clone;
}
public boolean isBody()
{
return Role.BODY.equals(displayRole);
}
public Role getDisplayRole()
{
return displayRole;
}
public int getNodeType()
{
return LayoutNodeTypes.TYPE_BOX_TABLE_SECTION;
}
public TableColumnModel getColumnModel()
{
final TableRenderBox table = TableHelper.lookupTable(this);
if (table == null)
{
return null;
}
return table.getColumnModel();
}
public TableRowModel getRowModel()
{
return rowModel;
}
public boolean isStructureValidated()
{
return isFlag(FLAG_TABLE_SECTION_STRUCTURE_VALIDATED);
}
public void setStructureValidated(final boolean structureValidated)
{
setFlag(FLAG_TABLE_SECTION_STRUCTURE_VALIDATED, structureValidated);
}
public boolean isActive()
{
return isFlag(FLAG_TABLE_SECTION_ACTIVE);
}
protected void setActive(final boolean active)
{
setFlag(FLAG_TABLE_SECTION_ACTIVE, active);
}
public boolean isMarkedActive()
{
return isFlag(FLAG_TABLE_SECTION_MARKED_ACTIVE);
}
protected void setMarkedActive(final boolean active)
{
setFlag(FLAG_TABLE_SECTION_MARKED_ACTIVE, active);
}
public boolean isAppliedActive()
{
return isFlag(FLAG_TABLE_SECTION_APPLIED_ACTIVE);
}
protected void setAppliedActive(final boolean active)
{
setFlag(FLAG_TABLE_SECTION_APPLIED_ACTIVE, active);
}
public void markBoxSeen()
{
super.markBoxSeen();
setMarkedActive(isActive());
markedHeaderShift = (HashMap<Long, Long>) headerShift.clone();
}
public void commit()
{
super.commit();
appliedHeaderShift = (HashMap<Long, Long>) markedHeaderShift.clone();
setAppliedActive(isMarkedActive());
}
public void rollback(final boolean deepDirty)
{
super.rollback(deepDirty);
setActive(isAppliedActive());
this.headerShift = (HashMap<Long, Long>) appliedHeaderShift.clone();
}
public void addChild(final RenderNode child)
{
if (isValid(child) == false)
{
TableRowRenderBox tsrb = new TableRowRenderBox();
tsrb.addChild(child);
addChild(tsrb);
tsrb.close();
return;
}
super.addChild(child);
}
private boolean isValid(final RenderNode child)
{
if ((child.getNodeType() & LayoutNodeTypes.MASK_BOX) != LayoutNodeTypes.MASK_BOX)
{
return true;
}
if (child.getNodeType() == LayoutNodeTypes.TYPE_BOX_AUTOLAYOUT)
{
return true;
}
if (child.getNodeType() == LayoutNodeTypes.TYPE_BOX_BREAKMARK)
{
return true;
}
if (child.getNodeType() == LayoutNodeTypes.TYPE_BOX_PROGRESS_MARKER)
{
return true;
}
if (child.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_ROW)
{
return true;
}
return false;
}
public RenderBox create(final StyleSheet styleSheet)
{
return new AutoRenderBox(styleSheet);
}
}