/*******************************************************************************
 * Copyright (c) 2012, 2016 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
 *     Dirk Fauth <dirk.fauth@googlemail.com> - made commandHandlers and eventHandlers
 *                                              visible to subclasses for testing
 *     Dirk Fauth <dirk.fauth@googlemail.com> - Bug 447145
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.layer;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfiguration;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelProvider;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.layer.cell.LayerCell;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEvent;
import org.eclipse.nebula.widgets.nattable.layer.event.ILayerEventHandler;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.layer.GridLineCellLayerPainter;
import org.eclipse.nebula.widgets.nattable.painter.layer.ILayerPainter;
import org.eclipse.nebula.widgets.nattable.persistence.IPersistable;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.swt.graphics.Rectangle;

/**
 * Base layer implementation with common methods for managing listeners and
 * caching, etc.
 */
public abstract class AbstractLayer implements ILayer {

    private String regionName;
    protected ILayerPainter layerPainter;
    private IClientAreaProvider clientAreaProvider = IClientAreaProvider.DEFAULT;
    private IConfigLabelAccumulator configLabelAccumulator;

    protected final Map<Class<? extends ILayerCommand>, ILayerCommandHandler<? extends ILayerCommand>> commandHandlers =
            new LinkedHashMap<Class<? extends ILayerCommand>, ILayerCommandHandler<? extends ILayerCommand>>();
    protected final Map<Class<? extends ILayerEvent>, ILayerEventHandler<? extends ILayerEvent>> eventHandlers =
            new HashMap<Class<? extends ILayerEvent>, ILayerEventHandler<? extends ILayerEvent>>();

    private final List<IPersistable> persistables = new LinkedList<IPersistable>();
    private final Set<ILayerListener> listeners = new LinkedHashSet<ILayerListener>();
    private final Collection<IConfiguration> configurations = new LinkedList<IConfiguration>();

    private boolean configurationApplied = false;

    /**
     * {@link ReadWriteLock} that is used to ensure that no concurrent
     * modifications happen on event handling
     * 
     * @since 1.4
     */
    protected ReadWriteLock eventHelperLock = new ReentrantReadWriteLock();

    // Dispose

    @Override
    public void dispose() {}

    // Regions

    @Override
    public LabelStack getRegionLabelsByXY(int x, int y) {
        LabelStack regionLabels = new LabelStack();
        if (this.regionName != null) {
            regionLabels.addLabel(this.regionName);
        }
        return regionLabels;
    }

    public String getRegionName() {
        return this.regionName;
    }

    public void setRegionName(String regionName) {
        this.regionName = regionName;
    }

    // Config lables

    @Override
    public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
        LabelStack configLabels = new LabelStack();
        if (this.configLabelAccumulator != null) {
            this.configLabelAccumulator.accumulateConfigLabels(configLabels, columnPosition, rowPosition);
        }
        if (this.regionName != null) {
            configLabels.addLabel(this.regionName);
        }
        return configLabels;
    }

    public IConfigLabelAccumulator getConfigLabelAccumulator() {
        return this.configLabelAccumulator;
    }

    public void setConfigLabelAccumulator(IConfigLabelAccumulator cellLabelAccumulator) {
        this.configLabelAccumulator = cellLabelAccumulator;
    }

    // Persistence

    @Override
    public void saveState(String prefix, Properties properties) {
        for (IPersistable persistable : this.persistables) {
            persistable.saveState(prefix, properties);
        }
    }

    @Override
    public void loadState(String prefix, Properties properties) {
        for (IPersistable persistable : this.persistables) {
            persistable.loadState(prefix, properties);
        }
    }

    @Override
    public void registerPersistable(IPersistable persistable) {
        this.persistables.add(persistable);
    }

    @Override
    public void unregisterPersistable(IPersistable persistable) {
        this.persistables.remove(persistable);
    }

    // Configuration

    public void addConfiguration(IConfiguration configuration) {
        this.configurations.add(configuration);
    }

    public void clearConfiguration() {
        this.configurations.clear();
    }

    @Override
    public void configure(ConfigRegistry configRegistry, UiBindingRegistry uiBindingRegistry) {
        if (!this.configurationApplied) {
            for (IConfiguration configuration : this.configurations) {
                configuration.configureLayer(this);
                configuration.configureRegistry(configRegistry);
                configuration.configureUiBindings(uiBindingRegistry);
            }

            // Bug 447145
            // to avoid registering configuration values multiple times, we
            // remember that this layer has already been configured
            this.configurationApplied = true;
        }
    }

    // Commands

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public boolean doCommand(ILayerCommand command) {
        for (Class<? extends ILayerCommand> commandClass : this.commandHandlers.keySet()) {
            if (commandClass.isInstance(command)) {
                ILayerCommandHandler commandHandler = this.commandHandlers.get(commandClass);
                if (commandHandler.doCommand(this, command)) {
                    return true;
                }
            }
        }

        return false;
    }

    // Command handlers

    /**
     * Layers should use this method to register their command handlers and call
     * it from their constructor. This allows easy overriding if required of
     * command handlers
     */
    protected void registerCommandHandlers() {
        // No op
    }

    @Override
    public void registerCommandHandler(ILayerCommandHandler<?> commandHandler) {
        this.commandHandlers.put(commandHandler.getCommandClass(), commandHandler);
    }

    @Override
    public void unregisterCommandHandler(Class<? extends ILayerCommand> commandClass) {
        this.commandHandlers.remove(commandClass);
    }

    // Events

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

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

    @Override
    public boolean hasLayerListener(Class<? extends ILayerListener> layerListenerClass) {
        for (ILayerListener listener : this.listeners) {
            if (listener.getClass().equals(layerListenerClass)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Handle layer event notification. Convert it to your context and propagate
     * <i>UP</i>.
     *
     * If you override this method you <strong>MUST NOT FORGET</strong> to raise
     * the event up the layer stack by calling
     * <code>super.fireLayerEvent(event)</code> - unless you plan to eat the
     * event yourself.
     **/
    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void handleLayerEvent(ILayerEvent event) {
        this.eventHelperLock.readLock().lock();
        try {
            for (Class<? extends ILayerEvent> eventClass : this.eventHandlers.keySet()) {
                if (eventClass.isInstance(event)) {
                    ILayerEventHandler eventHandler = this.eventHandlers.get(eventClass);
                    eventHandler.handleLayerEvent(event);
                }
            }

            // Pass on the event to our parent
            if (event.convertToLocal(this)) {
                fireLayerEvent(event);
            }
        } finally {
            this.eventHelperLock.readLock().unlock();
        }
    }

    public void registerEventHandler(ILayerEventHandler<?> eventHandler) {
        this.eventHelperLock.writeLock().lock();
        try {
            this.eventHandlers.put(eventHandler.getLayerEventClass(), eventHandler);
        } finally {
            this.eventHelperLock.writeLock().unlock();
        }
    }

    public void unregisterEventHandler(ILayerEventHandler<?> eventHandler) {
        this.eventHelperLock.writeLock().lock();
        try {
            this.eventHandlers.remove(eventHandler.getLayerEventClass());
        } finally {
            this.eventHelperLock.writeLock().unlock();
        }
    }

    /**
     * Pass the event to all the {@link ILayerListener} registered on this
     * layer. A cloned copy is passed to each listener.
     */
    @Override
    public void fireLayerEvent(ILayerEvent event) {
        if (this.listeners.size() > 0) {
            Iterator<ILayerListener> it = this.listeners.iterator();
            boolean isLastListener = false;
            do {
                ILayerListener l = it.next();
                isLastListener = !it.hasNext(); // Lookahead

                // Fire cloned event to first n-1 listeners; fire original event
                // to last listener
                ILayerEvent eventToFire = isLastListener ? event : event.cloneEvent();
                l.handleLayerEvent(eventToFire);
            } while (!isLastListener);
        }
    }

    /**
     * @return {@link ILayerPainter}. Defaults to
     *         {@link GridLineCellLayerPainter}
     */
    @Override
    public ILayerPainter getLayerPainter() {
        if (this.layerPainter == null) {
            this.layerPainter = new GridLineCellLayerPainter();
        }
        return this.layerPainter;
    }

    public void setLayerPainter(ILayerPainter layerPainter) {
        this.layerPainter = layerPainter;
    }

    // Client area

    @Override
    public IClientAreaProvider getClientAreaProvider() {
        return this.clientAreaProvider;
    }

    @Override
    public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
        this.clientAreaProvider = clientAreaProvider;
    }

    @Override
    public String toString() {
        return getClass().getSimpleName();
    }

    @Override
    public ILayerCell getCellByPosition(int columnPosition, int rowPosition) {
        if (columnPosition < 0 || columnPosition >= getColumnCount()
                || rowPosition < 0 || rowPosition >= getRowCount()) {
            return null;
        }

        return new LayerCell(this, columnPosition, rowPosition);
    }

    @Override
    public Rectangle getBoundsByPosition(int columnPosition, int rowPosition) {
        ILayerCell cell = getCellByPosition(columnPosition, rowPosition);
        ILayer cellLayer = cell.getLayer();

        int xOffset = -1;
        int yOffset = -1;
        int width = 0;
        int height = 0;
        {
            int column = cell.getOriginColumnPosition();
            int end = column + cell.getColumnSpan();
            for (; column < end; column++) {
                int columnOffset = cellLayer.getStartXOfColumnPosition(column);
                if (column < cellLayer.getColumnCount()) {
                    xOffset = columnOffset;
                    break;
                }
            }
            for (; column < end; column++) {
                width += cellLayer.getColumnWidthByPosition(column);
            }
        }
        {
            int row = cell.getOriginRowPosition();
            int end = row + cell.getRowSpan();
            for (; row < end; row++) {
                int rowOffset = cellLayer.getStartYOfRowPosition(row);
                if (row < cellLayer.getRowCount()) {
                    yOffset = rowOffset;
                    break;
                }
            }
            for (; row < end; row++) {
                height += cellLayer.getRowHeightByPosition(row);
            }
        }

        return new Rectangle(xOffset, yOffset, width, height);
    }

    @Override
    public String getDisplayModeByPosition(int columnPosition, int rowPosition) {
        return DisplayMode.NORMAL;
    }

    @Override
    public ICellPainter getCellPainter(
            int columnPosition, int rowPosition,
            ILayerCell cell, IConfigRegistry configRegistry) {
        return configRegistry.getConfigAttribute(
                CellConfigAttributes.CELL_PAINTER,
                cell.getDisplayMode(),
                cell.getConfigLabels().getLabels());
    }

    /**
     * @return <code>true</code> if the layer has a dynamic size (e.g. viewport)
     *         or a fixed size.
     * @since 1.4
     */
    public boolean isDynamicSizeLayer() {
        return false;
    }

    /**
     * @return The collection of labels that are provided by this layer.
     * @since 1.4
     */
    public Collection<String> getProvidedLabels() {
        Collection<String> labels = null;

        if (getUnderlyingLayerByPosition(0, 0) instanceof AbstractLayer) {
            labels = ((AbstractLayer) getUnderlyingLayerByPosition(0, 0)).getProvidedLabels();
        } else {
            labels = new LinkedHashSet<String>();
        }

        // add the region
        if (this.regionName != null) {
            labels.add(this.regionName);
        }

        // add the labels configured via IConfigLabelAccumulator
        if (this.configLabelAccumulator != null
                && this.configLabelAccumulator instanceof IConfigLabelProvider) {
            labels.addAll(((IConfigLabelProvider) this.configLabelAccumulator).getProvidedLabels());
        }

        return labels;
    }
}
