/*******************************************************************************
 * Copyright (c) 2012 Original authors and others.
 * 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:
 *     Original authors and others - initial API and implementation
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.core;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.nebula.widgets.nattable.core.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.core.layer.ILayerListener;
import org.eclipse.nebula.widgets.nattable.core.layer.event.ILayerEvent;
import org.eclipse.nebula.widgets.nattable.core.painter.IGraphicsContext;
import org.eclipse.nebula.widgets.nattable.core.painter.Rectangle;

/**
 * Presentation model of the NatTable.
 * 
 * @author Dirk Fauth
 *
 */
public class NatTable implements ILayer //TODO extend AbstractLayer
//	, IClientAreaProvider, ILayerListener, IPersistable
	{

	
//	private UiBindingRegistry uiBindingRegistry;
//
//	private ModeSupport modeSupport;
//
//	private final EventConflaterChain conflaterChain = new EventConflaterChain();
//
//	private final List<IOverlayPainter> overlayPainters = new ArrayList<IOverlayPainter>();
//
//	private final List<IPersistable> persistables = new LinkedList<IPersistable>();
//
//	private ILayer underlyingLayer;
//
//	private IConfigRegistry configRegistry;
//
//	protected final Collection<IConfiguration> configurations = new LinkedList<IConfiguration>();
//
//	protected String id = GUIHelper.getSequenceNumber();
//
//	private ILayerPainter layerPainter = new NatLayerPainter(this);
//
//	private final boolean autoconfigure;



	public NatTable(INatTableConfiguration natConfig) {
		if (natConfig != null) {
			//if a NatTableConfiguration is given, start configuring it by this
			//e.g. if using the E4 extension, the layers and other configurations will
			//be added by using dependency injection
			natConfig.startConstruction();
		}
		
//		initInternalListener();
//
//		internalSetLayer(layer);
//
//		this.autoconfigure = autoconfigure;
//		if (autoconfigure) {
//			configurations.add(new DefaultNatTableStyleConfiguration());
//			configure();
//		}
//
//		conflaterChain.add(getVisualChangeEventConflater());
//		conflaterChain.start();
//
//		addDisposeListener(new DisposeListener() {
//
//			public void widgetDisposed(DisposeEvent e) {
//				doCommand(new DisposeResourcesCommand());
//				conflaterChain.stop();
//				InlineCellEditController.dispose();
//				ActiveCellEditor.close();
//				
//				layer.dispose();
//			}
//
//		});
	}
	
//	protected IEventConflater getVisualChangeEventConflater() {
//		return new VisualChangeEventConflater(this);
//	}


//	public ILayer getLayer() {
//		return underlyingLayer;
//	}
//
//	public void setLayer(ILayer layer) {
//		if (autoconfigure) {
//			throw new IllegalStateException("May only set layer post construction if autoconfigure is turned off"); //$NON-NLS-1$
//		}
//
//		internalSetLayer(layer);
//	}
//
//	private void internalSetLayer(ILayer layer) {
//		if (layer != null) {
//			this.underlyingLayer = layer;
//			underlyingLayer.setClientAreaProvider(new IClientAreaProvider() {
//
//				public Rectangle getClientArea() {
//					final Rectangle clientArea = new Rectangle(0, 0, 0, 0);
//					if (!isDisposed()) {
//						getDisplay().syncExec(new Runnable() {
//							public void run() {
//								Rectangle natClientArea = NatTable.this.getClientArea();
//								clientArea.x = natClientArea.x;
//								clientArea.y = natClientArea.y;
//								clientArea.width = natClientArea.width;
//								clientArea.height = natClientArea.height;
//							}
//						});
//					}
//					return clientArea;
//				}
//
//			});
//			underlyingLayer.addLayerListener(this);
//		}
//	}
//
//	/**
//	 * Adds a configuration to the table.<br/>
//	 *
//	 * Configurations are processed when the {@link #configure()} method is invoked.<br/>
//	 * Each configuration object then has a chance to configure the<br/>
//	 * 	<ol>
//	 * 		<li>ILayer</li>
//	 * 		<li>ConfigRegistry</li>
//	 * 		<li>UiBindingRegistry</li>
//	 *  </ol>
//	 */
//	public void addConfiguration(IConfiguration configuration) {
//		if (autoconfigure) {
//			throw new IllegalStateException("May only add configurations post construction if autoconfigure is turned off"); //$NON-NLS-1$
//		}
//
//		configurations.add(configuration);
//	}
//
//	/**
//	 * @return {@link IConfigRegistry} used to hold the configuration bindings<br/>
//	 * 	by Layer, DisplayMode and Config labels.
//	 */
//	public IConfigRegistry getConfigRegistry() {
//		if (configRegistry == null) {
//			configRegistry = new ConfigRegistry();
//		}
//		return configRegistry;
//	}
//
//	public void setConfigRegistry(IConfigRegistry configRegistry) {
//		if (autoconfigure) {
//			throw new IllegalStateException("May only set config registry post construction if autoconfigure is turned off"); //$NON-NLS-1$
//		}
//
//		this.configRegistry = configRegistry;
//	}
//
//	/**
//	 * @return Registry holding all the UIBindings contributed by the underlying layers
//	 */
//	public UiBindingRegistry getUiBindingRegistry() {
//		if (uiBindingRegistry == null) {
//			uiBindingRegistry = new UiBindingRegistry(this);
//		}
//		return uiBindingRegistry;
//	}
//
//	public void setUiBindingRegistry(UiBindingRegistry uiBindingRegistry) {
//		if (autoconfigure) {
//			throw new IllegalStateException("May only set UI binding registry post construction if autoconfigure is turned off"); //$NON-NLS-1$
//		}
//
//		this.uiBindingRegistry = uiBindingRegistry;
//	}
//
//	public String getID() {
//		return id;
//	}

//	protected void initInternalListener() {
//		modeSupport = new ModeSupport(this);
//		modeSupport.registerModeEventHandler(Mode.NORMAL_MODE, new ConfigurableModeEventHandler(modeSupport, this));
//		modeSupport.switchMode(Mode.NORMAL_MODE);
//
//		addPaintListener(this);
//
//		addFocusListener(new FocusListener() {
//
//			public void focusLost(final FocusEvent arg0) {
//				redraw();
//			}
//
//			public void focusGained(final FocusEvent arg0) {
//				redraw();
//			}
//
//		});
//
//		addListener(SWT.Resize, new Listener() {
//			public void handleEvent(final Event e) {
//				doCommand(new ClientAreaResizeCommand(NatTable.this));
//			}
//		});
//	}

	// Painting ///////////////////////////////////////////////////////////////

//	public List<IOverlayPainter> getOverlayPainters() {
//		return overlayPainters;
//	}
//	
//	public void addOverlayPainter(IOverlayPainter overlayPainter) {
//		overlayPainters.add(overlayPainter);
//	}
//
//	public void removeOverlayPainter(IOverlayPainter overlayPainter) {
//		overlayPainters.remove(overlayPainter);
//	}


	public void paintNatTable(final IGraphicsContext gc, final Rectangle rectangle) {
//		getLayerPainter().paintLayer(this, event.gc, 0, 0, new Rectangle(event.x, event.y, event.width, event.height), getConfigRegistry());
	}

//	public ILayerPainter getLayerPainter() {
//		return layerPainter;
//	}
//
//	public void setLayerPainter(ILayerPainter layerPainter) {
//		this.layerPainter = layerPainter;
//	}
//
//	/**
//	 * Repaint only a specific column in the grid. This method is optimized so that only the specific column is
//	 * repainted and nothing else.
//	 *
//	 * @param gridColumnPosition column of the grid to repaint
//	 */
//	public void repaintColumn(int columnPosition) {
//		int xOffset = getStartXOfColumnPosition(columnPosition);
//		if (xOffset < 0) {
//			return;
//		}
//		redraw(xOffset, 0, getColumnWidthByPosition(columnPosition), getHeight(), true);
//	}
//
//	/**
//	 * Repaint only a specific row in the grid. This method is optimized so that only the specific row is repainted and
//	 * nothing else.
//	 *
//	 * @param gridRowPosition row of the grid to repaint
//	 */
//	public void repaintRow(int rowPosition) {
//		int yOffset = getStartYOfRowPosition(rowPosition);
//		if (yOffset < 0) {
//			return;
//		}
//		redraw(0, yOffset, getWidth(), getRowHeightByPosition(rowPosition), true);
//	}


//	/**
//	 * Refreshes the entire NatTable as every layer will be refreshed.
//	 */
//	public void refresh() {
//		doCommand(new StructuralRefreshCommand());
//	}
//	
//	public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
//		throw new UnsupportedOperationException("Cannot use this method to configure NatTable. Use no-argument configure() instead."); //$NON-NLS-1$
//	}
//
//	/**
//	 * Processes all the registered {@link IConfiguration} (s).
//	 * All the underlying layers are walked and given a chance to configure.
//	 * Note: all desired configuration tweaks must be done <i>before</i> this method is invoked.
//	 */
//	public void configure() {
//		if (underlyingLayer == null) {
//			throw new IllegalStateException("Layer must be set before configure is called"); //$NON-NLS-1$
//		}
//
//		if (underlyingLayer != null) {
//			underlyingLayer.configure((ConfigRegistry) getConfigRegistry(), getUiBindingRegistry());
//		}
//
//		for (IConfiguration configuration : configurations) {
//			configuration.configureLayer(this);
//			configuration.configureRegistry(getConfigRegistry());
//			configuration.configureUiBindings(getUiBindingRegistry());
//		}
//
//		// Once everything is initialized and properly configured we will
//		// now formally initialize the grid
//		doCommand(new InitializeGridCommand(this));
//	}
//
	// Events /////////////////////////////////////////////////////////////////

	private final List<ILayerListener> listeners = new ArrayList<ILayerListener>();

	public void fireLayerEvent(ILayerEvent event) {
		for (ILayerListener layerListener : listeners) {
			layerListener.handleLayerEvent(event);
		}
	}

	public void addLayerListener(ILayerListener listener) {
		listeners.add(listener);
	}

	public void removeLayerListener(ILayerListener listener) {
		listeners.remove(listener);
	}

	public void handleLayerEvent(ILayerEvent event) {
		for (ILayerListener layerListener : listeners) {
			layerListener.handleLayerEvent(event);
		}

//	    if (event instanceof IVisualChangeEvent) {
//	    	conflaterChain.addEvent(event);
//	    }
//
//		if (event instanceof CellSelectionEvent) {
//			Event e = new Event();
//			e.widget = this;
//			try {
//				notifyListeners(SWT.Selection, e);
//			} catch (RuntimeException re) {
//				re.printStackTrace();
//			}
//		}
	}
	
	@Override
	public void dispose() {
		//TODO tell the presentation to dispose
	}
	
//
//
//	// ILayer /////////////////////////////////////////////////////////////////
//
//	// Persistence
//
//	/**
//	 * Save the state of the table to the properties object.
//	 * {@link ILayer#saveState(String, Properties)} is invoked on all the underlying layers.
//	 * This properties object will be populated with the settings of all underlying layers
//	 * and any {@link IPersistable} registered with those layers.
//	 */
//	public void saveState(String prefix, Properties properties) {
//		underlyingLayer.saveState(prefix, properties);
//	}
//
//	/**
//	 * Restore the state of the underlying layers from the values in the properties object.
//	 * @see #saveState(String, Properties)
//	 */
//	public void loadState(String prefix, Properties properties) {
//		underlyingLayer.loadState(prefix, properties);
//	}
//
//	/**
//	 * @see ILayer#registerPersistable(IPersistable)
//	 */
//	public void registerPersistable(IPersistable persistable) {
//		persistables.add(persistable);
//	}
//
//	public void unregisterPersistable(IPersistable persistable) {
//		persistables.remove(persistable);
//	}
//
//	// Command
//
//	public boolean doCommand(ILayerCommand command) {
//		return underlyingLayer.doCommand(command);
//	}
//
//
//	// Columns
//
//	public int getColumnCount() {
//		return underlyingLayer.getColumnCount();
//	}
//
//	public int getPreferredColumnCount() {
//		return underlyingLayer.getPreferredColumnCount();
//	}
//
//	public int getColumnIndexByPosition(int columnPosition) {
//		return underlyingLayer.getColumnIndexByPosition(columnPosition);
//	}
//
//	public int localToUnderlyingColumnPosition(int localColumnPosition) {
//		return localColumnPosition;
//	}
//
//	public int underlyingToLocalColumnPosition(ILayer sourceUnderlyingLayer, int underlyingColumnPosition) {
//		if (sourceUnderlyingLayer != underlyingLayer) {
//			return -1;
//		}
//
//		return underlyingColumnPosition;
//	}
//
//	public Collection<Range> underlyingToLocalColumnPositions(ILayer sourceUnderlyingLayer, Collection<Range> underlyingColumnPositionRanges) {
//		if (sourceUnderlyingLayer != underlyingLayer) {
//			return null;
//		}
//
//		return underlyingColumnPositionRanges;
//	}
//
//	// Width
//
//	public int getWidth() {
//		return underlyingLayer.getWidth();
//	}
//
//	public int getPreferredWidth() {
//		return underlyingLayer.getPreferredWidth();
//	}
//
//	public int getColumnWidthByPosition(int columnPosition) {
//		return underlyingLayer.getColumnWidthByPosition(columnPosition);
//	}
//
//	// Column resize
//
//	public boolean isColumnPositionResizable(int columnPosition) {
//		return underlyingLayer.isColumnPositionResizable(columnPosition);
//	}
//
//	// X
//
//	public int getColumnPositionByX(int x) {
//		return underlyingLayer.getColumnPositionByX(x);
//	}
//
//	public int getStartXOfColumnPosition(int columnPosition) {
//		return underlyingLayer.getStartXOfColumnPosition(columnPosition);
//	}
//
//	// Underlying
//
//	public Collection<ILayer> getUnderlyingLayersByColumnPosition(int columnPosition) {
//		Collection<ILayer> underlyingLayers = new HashSet<ILayer>();
//		underlyingLayers.add(underlyingLayer);
//		return underlyingLayers;
//	}
//
//	// Rows
//
//	public int getRowCount() {
//		return underlyingLayer.getRowCount();
//	}
//
//	public int getPreferredRowCount() {
//		return underlyingLayer.getPreferredRowCount();
//	}
//
//	public int getRowIndexByPosition(int rowPosition) {
//		return underlyingLayer.getRowIndexByPosition(rowPosition);
//	}
//
//	public int localToUnderlyingRowPosition(int localRowPosition) {
//		return localRowPosition;
//	}
//
//	public int underlyingToLocalRowPosition(ILayer sourceUnderlyingLayer, int underlyingRowPosition) {
//		if (sourceUnderlyingLayer != underlyingLayer) {
//			return -1;
//		}
//
//		return underlyingRowPosition;
//	}
//
//	public Collection<Range> underlyingToLocalRowPositions(ILayer sourceUnderlyingLayer, Collection<Range> underlyingRowPositionRanges) {
//		if (sourceUnderlyingLayer != underlyingLayer) {
//			return null;
//		}
//
//		return underlyingRowPositionRanges;
//	}
//
//	// Height
//
//	public int getHeight() {
//		return underlyingLayer.getHeight();
//	}
//
//	public int getPreferredHeight() {
//		return underlyingLayer.getPreferredHeight();
//	}
//
//	public int getRowHeightByPosition(int rowPosition) {
//		return underlyingLayer.getRowHeightByPosition(rowPosition);
//	}
//
//	// Row resize
//
//	public boolean isRowPositionResizable(int rowPosition) {
//		return underlyingLayer.isRowPositionResizable(rowPosition);
//	}
//
//	// Y
//
//	public int getRowPositionByY(int y) {
//		return underlyingLayer.getRowPositionByY(y);
//	}
//
//	public int getStartYOfRowPosition(int rowPosition) {
//		return underlyingLayer.getStartYOfRowPosition(rowPosition);
//	}
//
//	// Underlying
//
//	public Collection<ILayer> getUnderlyingLayersByRowPosition(int rowPosition) {
//		Collection<ILayer> underlyingLayers = new HashSet<ILayer>();
//		underlyingLayers.add(underlyingLayer);
//		return underlyingLayers;
//	}
//
//	// Cell features
//
//	public ILayerCell getCellByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer.getCellByPosition(columnPosition, rowPosition);
//	}
//
//	public Rectangle getBoundsByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer.getBoundsByPosition(columnPosition, rowPosition);
//	}
//
//	public String getDisplayModeByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer.getDisplayModeByPosition(columnPosition, rowPosition);
//	}
//
//	public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer.getConfigLabelsByPosition(columnPosition, rowPosition);
//	}
//
//	public Object getDataValueByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer.getDataValueByPosition(columnPosition, rowPosition);
//	}
//	
//	public ICellPainter getCellPainter(int columnPosition, int rowPosition, ILayerCell cell, IConfigRegistry configRegistry) {
//		return underlyingLayer.getCellPainter(columnPosition, rowPosition, cell, configRegistry);
//	}
//
//	// IRegionResolver
//
//	public LabelStack getRegionLabelsByXY(int x, int y) {
//		return underlyingLayer.getRegionLabelsByXY(x, y);
//	}
//
//	public ILayer getUnderlyingLayerByPosition(int columnPosition, int rowPosition) {
//		return underlyingLayer;
//	}
//
//	public IClientAreaProvider getClientAreaProvider() {
//		return this;
//	}
//
//	public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
//		throw new UnsupportedOperationException("Cannot set an area provider."); //$NON-NLS-1$
//	}
//	
//	
//	// DND /////////////////////////////////////////////////////////////////
//	
//	/**
//	 * Adds support for dragging items out of this control via a user
//	 * drag-and-drop operation.
//	 *
//	 * @param operations
//	 *            a bitwise OR of the supported drag and drop operation types (
//	 *            <code>DROP_COPY</code>,<code>DROP_LINK</code>, and
//	 *            <code>DROP_MOVE</code>)
//	 * @param transferTypes
//	 *            the transfer types that are supported by the drag operation
//	 * @param listener
//	 *            the callback that will be invoked to set the drag data and to
//	 *            cleanup after the drag and drop operation finishes
//	 * @see org.eclipse.swt.dnd.DND
//	 */
//	public void addDragSupport(final int operations, final Transfer[] transferTypes, final DragSourceListener listener) {
//		final DragSource dragSource = new DragSource(this, operations);
//		dragSource.setTransfer(transferTypes);
//		dragSource.addDragListener(listener);
//	}
//
//	/**
//	 * Adds support for dropping items into this control via a user drag-and-drop
//	 * operation.
//	 *
//	 * @param operations
//	 *            a bitwise OR of the supported drag and drop operation types (
//	 *            <code>DROP_COPY</code>,<code>DROP_LINK</code>, and
//	 *            <code>DROP_MOVE</code>)
//	 * @param transferTypes
//	 *            the transfer types that are supported by the drop operation
//	 * @param listener
//	 *            the callback that will be invoked after the drag and drop
//	 *            operation finishes
//	 * @see org.eclipse.swt.dnd.DND
//	 */
//	public void addDropSupport(final int operations, final Transfer[] transferTypes, final DropTargetListener listener) {
//		final DropTarget dropTarget = new DropTarget(this, operations);
//		dropTarget.setTransfer(transferTypes);
//		dropTarget.addDropListener(listener);
//	}
}
