/*******************************************************************************
 * Copyright (c) 2004, 2005 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.report.engine.layout.html;

import org.eclipse.birt.report.engine.content.IBandContent;
import org.eclipse.birt.report.engine.content.ICellContent;
import org.eclipse.birt.report.engine.content.IRowContent;
import org.eclipse.birt.report.engine.content.ITableBandContent;
import org.eclipse.birt.report.engine.content.ITableContent;
import org.eclipse.birt.report.engine.content.ITableGroupContent;
import org.eclipse.birt.report.engine.emitter.BufferedReportEmitter;
import org.eclipse.birt.report.engine.emitter.IContentEmitter;
import org.eclipse.birt.report.engine.ir.CellDesign;

/**
 * 
 */

public class HTMLTableLayoutNoNestEmitter extends HTMLTableLayoutEmitter
{

	public HTMLTableLayoutNoNestEmitter( IContentEmitter emitter )
	{
		super( emitter );
	}

	int nestTableCount = 0;

	private boolean isNestTable( )
	{
		return nestTableCount > 1;
	}

	public void startTable( ITableContent table )
	{
		nestTableCount++;
		if ( cellEmitter != null )
		{
			cellEmitter.startTable( table );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				initLayout( table );
			}
			emitter.startTable( table );
		}
	}

	public void endTable( ITableContent table )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.endTable( table );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				resolveAll( );
				flush( );
			}
			emitter.endTable( table );
		}
		nestTableCount--;
	}

	public void startTableGroup( ITableGroupContent group )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.startTableGroup( group );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				int groupLevel = group.getGroupLevel( );
				groupStack.push( new Integer( groupLevel ) );
				if ( hasDropCell( ) )
				{
					layoutEvents.push( new LayoutEvent(
							LayoutEvent.START_GROUP, group ) );
					return;
				}
			}
			emitter.startTableGroup( group );
		}
	}

	public void endTableGroup( ITableGroupContent group )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.endTableGroup( group );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				// if there is no group footer, we still need to do with the
				// drop.
				int groupLevel = getGroupLevel( );
				resolveCellsOfDrop( groupLevel, false );
				resolveCellsOfDrop( groupLevel, true );
				assert !groupStack.isEmpty( );
				groupStack.pop( );
				if ( hasDropCell( ) )
				{
					layoutEvents.push( new LayoutEvent( LayoutEvent.END_GROUP,
							group ) );
					return;
				}
				flush( );
			}
			emitter.endTableGroup( group );
		}
	}

	public void startTableBand( ITableBandContent band )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.startTableBand( band );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				if ( band.getBandType( ) == IBandContent.BAND_GROUP_FOOTER )
				{
					int groupLevel = getGroupLevel( );
					resolveCellsOfDrop( groupLevel, false );
				}
				if ( hasDropCell( ) )
				{
					layoutEvents.push( new LayoutEvent( LayoutEvent.START_BAND,
							band ) );
					return;
				}
				flush( );
			}
			emitter.startTableBand( band );
		}
	}

	public void endTableBand( ITableBandContent band )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.endTableBand( band );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				if ( band.getBandType( ) == IBandContent.BAND_GROUP_FOOTER )
				{
					int groupLevel = getGroupLevel( );
					resolveCellsOfDrop( groupLevel, true );
				}
				if ( hasDropCell( ) )
				{
					layoutEvents.push( new LayoutEvent( LayoutEvent.END_BAND,
							band ) );
					return;
				}
				flush( );
			}
			emitter.endTableBand( band );
		}
	}

	public void startRow( IRowContent row )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.startRow( row );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				layout.createRow( row );
				if ( hasDropCell( ) )
				{
					layoutEvents.push( new LayoutEvent( LayoutEvent.ON_ROW,
							new Integer( layout.getRowCount( ) - 1 ) ) );
					return;
				}
				// TODO: here we need handle the hidden row and change the row
				// id.
			}
			emitter.startRow( row );
		}
	}

	public void endRow( IRowContent row )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.endRow( row );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				if ( hasDropCell( ) )
				{
					return;
				}
				flush( );
			}
			emitter.endRow( row );
		}
	}

	public void startCell( ICellContent cell )
	{
		if ( cellEmitter != null )
		{
			cellEmitter.startCell( cell );
		}
		else
		{
			if ( !isNestTable( ) )
			{
				BufferedReportEmitter buffer = null;
				int colId = cell.getColumn( );
				int colSpan = cell.getColSpan( );
				int rowSpan = cell.getRowSpan( );

				// the current executed cell is rowIndex, columnIndex
				// get the span value of that cell.
				CellDesign cellDesign = (CellDesign) cell.getGenerateBy( );
				if ( cellDesign != null )
				{
					String dropType = cellDesign.getDrop( );
					if ( dropType != null && !"none".equals( dropType ) )
					{
						rowSpan = createDropID( getGroupLevel( ), dropType );
					}
				}

				// the table has no cache, the cell is the first drop cell
				if ( !hasDropCell( ) && rowSpan < 0 )
				{
					layoutEvents.push( new LayoutEvent(
							LayoutEvent.ON_FIRST_DROP_CELL, new Integer( layout
									.getRowCount( ) - 1 ) ) );
				}
				if ( hasDropCell( ) || rowSpan < 0 )
				{
					buffer = new BufferedReportEmitter( emitter );
					cellEmitter = buffer;
				}
				// we need cache the cell
				createCell( colId, rowSpan, colSpan, new CellContent( cell,
						buffer ) );
				if ( hasDropCell( ) )
				{
					return;
				}
				// TODO: changes the column id and output it.
			}
			emitter.startCell( cell );
		}
	}

	public void endCell( ICellContent cell )
	{
		if ( !isNestTable( ) )
		{
			if ( cellEmitter != null )
			{
				cellEmitter = null;
				return;
			}
			else
			{
				emitter.endCell( cell );
			}
		}
		else
		{
			if ( cellEmitter != null )
			{
				cellEmitter.endCell( cell );
			}
			else
			{
				emitter.endCell( cell );
			}
		}
	}

}
