/*=============================================================================#
 # Copyright (c) 2012, 2021 Original NatTable authors and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     Original NatTable authors and others - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.waltable.grid.layer;

import org.eclipse.statet.ecommons.waltable.command.ILayerCommand;
import org.eclipse.statet.ecommons.waltable.coordinate.LRectangle;
import org.eclipse.statet.ecommons.waltable.export.ExportCommandHandler;
import org.eclipse.statet.ecommons.waltable.grid.ClientAreaResizeCommand;
import org.eclipse.statet.ecommons.waltable.grid.GridRegion;
import org.eclipse.statet.ecommons.waltable.grid.layer.config.DefaultGridLayerConfiguration;
import org.eclipse.statet.ecommons.waltable.layer.CompositeLayer;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.print.PrintCommandHandler;
import org.eclipse.statet.ecommons.waltable.selection.SelectCellCommand;
import org.eclipse.statet.ecommons.waltable.swt.SWTUtil;


/**
 * Top level layer. It is composed of the smaller child layers: RowHeader,
 * ColumnHeader, Corner and Body It does not have its own coordinate system
 * unlike the other layers. It simply delegates most functions to its child
 * layers.
 */
public class GridLayer extends CompositeLayer {

	public GridLayer(final ILayer bodyLayer, final ILayer columnHeaderLayer, final ILayer rowHeaderLayer, final ILayer cornerLayer) {
		this(bodyLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer, true);
	}
	
	public GridLayer(final ILayer bodyLayer, final ILayer columnHeaderLayer, final ILayer rowHeaderLayer, final ILayer cornerLayer, final boolean useDefaultConfiguration) {
		super(2, 2);
		
		setBodyLayer(bodyLayer);
		setColumnHeaderLayer(columnHeaderLayer);
		setRowHeaderLayer(rowHeaderLayer);
		setCornerLayer(cornerLayer);
		
		init(useDefaultConfiguration);
	}

	protected GridLayer(final boolean useDefaultConfiguration) {
		super(2, 2);
		init(useDefaultConfiguration);
	}

	protected void init(final boolean useDefaultConfiguration) {
		registerCommandHandlers();
		
		if (useDefaultConfiguration) {
			addConfiguration(new DefaultGridLayerConfiguration(this));
		}
	}

	@Override
	protected void registerCommandHandlers() {
		registerCommandHandler(new PrintCommandHandler(this));
		registerCommandHandler(new ExportCommandHandler(this));
//		registerCommandHandler(new AutoResizeColumnCommandHandler(this));
//		registerCommandHandler(new AutoResizeRowCommandHandler(this));
	}
	
	/**
	 * How the GridLayer processes commands is very important. <strong>Do not
	 * change this unless you know what you are doing and understand the full
	 * ramifications of your change. Otherwise your grid will not behave
	 * correctly!</strong>
	 * 
	 * The Body is always given the first chance to process a command. There are
	 * two reasons for this: (1) most commands (80%) are destined for the body
	 * anyways so it's faster to check there first (2) the other layers all
	 * transitively depend on the body so it's not wise to ask them to do stuff
	 * until after the body has done it. This is especially true of grid
	 * initialization where the body must be initialized before any of its
	 * dependent layers.
	 * 
	 * Because of this, if you want to intercept well-known commands to
	 * implement custom behavior (for example, you want to intercept the
	 * {@link SelectCellCommand}) then <strong>you must inject your special
	 * layer into the body. </strong> An injected column or row header will
	 * never see the command because it will be consumed first by the body. In
	 * practice, it's a good idea to implement all your command-handling logic
	 * in the body.
	 **/
	@Override
	protected boolean doCommandOnChildLayers(final ILayerCommand command) {
		if (getBodyLayer().doCommand(command)) {
			return true;
		}
		else if (getColumnHeaderLayer().doCommand(command)) {
			return true;
		}
		else if (getRowHeaderLayer().doCommand(command)) {
			return true;
		}
		else {
			return getCornerLayer().doCommand(command);
		}
	}
	
	// Sub-layer accessors
	
	public ILayer getCornerLayer() {
		return getChildLayerByLayoutCoordinate(0, 0);
	}
	
	public void setCornerLayer(final ILayer cornerLayer) {
		setChildLayer(GridRegion.CORNER, cornerLayer, 0, 0);
	}

	public ILayer getColumnHeaderLayer() {
		return getChildLayerByLayoutCoordinate(1, 0);
	}
	
	public void setColumnHeaderLayer(final ILayer columnHeaderLayer) {
		setChildLayer(GridRegion.COLUMN_HEADER, columnHeaderLayer, 1, 0);
	}
	
	public ILayer getRowHeaderLayer() {
		return getChildLayerByLayoutCoordinate(0, 1);
	}
	
	public void setRowHeaderLayer(final ILayer rowHeaderLayer) {
		setChildLayer(GridRegion.ROW_HEADER, rowHeaderLayer, 0, 1);
	}
	
	public ILayer getBodyLayer() {
		return getChildLayerByLayoutCoordinate(1, 1);
	}
	
	public void setBodyLayer(final ILayer bodyLayer) {
		setChildLayer(GridRegion.BODY, bodyLayer, 1, 1);
		
		//update the command handlers for auto resize because of the connection to the body layer stack
//		unregisterCommandHandler(AutoResizePositionsCommand.class);
//		unregisterCommandHandler(AutoResizeRowsCommand.class);
		
//		registerCommandHandler(new AutoResizeColumnCommandHandler(this));
//		registerCommandHandler(new AutoResizeRowCommandHandler(this));		
	}
	
	@Override
	public String toString() {
		return getClass().getSimpleName()
				+ "[corner=" + getCornerLayer() //$NON-NLS-1$
				+ " columnHeader=" + getColumnHeaderLayer() //$NON-NLS-1$
				+ " rowHeader=" + getRowHeaderLayer() //$NON-NLS-1$
				+ " bodyLayer=" + getBodyLayer() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
	}
	
	
	@Override
	public boolean doCommand(final ILayerCommand command) {
		if (command instanceof ClientAreaResizeCommand && command.convertToTargetLayer(this)) {
			final ClientAreaResizeCommand clientAreaResizeCommand= (ClientAreaResizeCommand) command;
			final LRectangle possibleArea= SWTUtil.toNatTable(clientAreaResizeCommand.getScrollable().getClientArea());
			
			//remove the column header height and the row header width from the client area to 
			//ensure that only the body region is used for percentage calculation
			final LRectangle rowLayerArea= getRowHeaderLayer().getClientAreaProvider().getClientArea();
			final LRectangle columnLayerArea= getColumnHeaderLayer().getClientAreaProvider().getClientArea();
			possibleArea.width= possibleArea.width - rowLayerArea.width;
			possibleArea.height= possibleArea.height - columnLayerArea.height;
			
			clientAreaResizeCommand.setCalcArea(possibleArea);
		}
		return super.doCommand(command);
	}

}