/*=============================================================================#
 # Copyright (c) 2010, 2019 Stephan Wahlbrink 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, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.ui.intable;

import static org.eclipse.statet.ecommons.waltable.coordinate.Orientation.HORIZONTAL;
import static org.eclipse.statet.ecommons.waltable.coordinate.Orientation.VERTICAL;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.statet.ecommons.waltable.config.LayoutSizeConfig;
import org.eclipse.statet.ecommons.waltable.coordinate.Orientation;
import org.eclipse.statet.ecommons.waltable.coordinate.PositionId;
import org.eclipse.statet.ecommons.waltable.coordinate.PositionOutOfBoundsException;
import org.eclipse.statet.ecommons.waltable.layer.AbstractLayer;
import org.eclipse.statet.ecommons.waltable.layer.DataDim;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.layer.ILayerDim;
import org.eclipse.statet.ecommons.waltable.layer.cell.ILayerCell;
import org.eclipse.statet.ecommons.waltable.layer.cell.LayerCell;
import org.eclipse.statet.ecommons.waltable.layer.cell.LayerCellDim;
import org.eclipse.statet.ecommons.waltable.resize.ColumnResizeEvent;

import org.eclipse.statet.internal.r.ui.dataeditor.AbstractRDataProvider;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataFormatter;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataTableContentDescription;
import org.eclipse.statet.r.ui.dataeditor.RDataTableColumn;


public class RDataLayer extends AbstractLayer {
	
	
	private static int minmax(final int value, final int min, final int max) {
		return (value <= min) ? min : ((value >= max) ? max : value);
	}
	
	
	private static class ColumnsDim extends DataDim<RDataLayer> {
		
		
		private final int defaultMinChars= 8;
		private final int defaultMaxChars= 20;
		
		private final int autoMinChars= 3;
		private final int autoMaxChars= 1000;
		
		private final int fallbackPositionSize= 10;
		
		private final Map<Long, Integer> customPositionSizes= new HashMap<>();
		
		private int charSize;
		private int spacing;
		
		
		public ColumnsDim(final RDataLayer layer, final int charSize, final int spacing) {
			super(layer, Orientation.HORIZONTAL, PositionId.BODY_CAT);
			
			this.charSize= charSize;
			this.spacing= spacing;
		}
		
		
		@Override
		public long getPositionCount() {
			return this.layer.dataProvider.getColumnCount();
		}
		
		
		public void setSize(final int charSize, final int spacing) {
			if (charSize != this.charSize || spacing != this.spacing) {
				final double factor= (double) charSize / this.charSize;
				for (final Map.Entry<Long, Integer> entry : this.customPositionSizes.entrySet()) {
					entry.setValue((int) (
							(entry.getValue() - this.spacing) * factor + spacing + 0.5 ));
				}
			}
			
			this.charSize= charSize;
			this.spacing= spacing;
		}
		
		private long aggregateSize(final long position) {
			if (position < 0) {
				return -1;
			}
			
			if (this.layer.dataProvider.getAllColumnsEqual()) {
				final Integer columnWidth= this.customPositionSizes.get(Long.valueOf(0));
				if (columnWidth != null) {
					return columnWidth * position;
				}
				else {
					return getDefaultSize(0) * position;
				}
			}
			
			long width= 0;
			for (long i= 0; i < position; i++) {
				final Integer columnWidth= this.customPositionSizes.get(Long.valueOf(i));
				if (columnWidth != null) {
					width += columnWidth.intValue();
				}
				else {
					width += getDefaultSize(i);
				}
			}
			return width;
		}
		
		@Override
		public long getSize() {
			return aggregateSize(getPositionCount());
		}
		
		@Override
		public long getPositionStart(final long position) {
			if (position < 0 || position >= getPositionCount()) {
				throw PositionOutOfBoundsException.position(position, getOrientation());
			}
			return aggregateSize(position);
		}
		
		@Override
		public int getPositionSize(final long position) {
			if (position < 0 || position >= getPositionCount()) {
				throw PositionOutOfBoundsException.position(position, getOrientation());
			}
			final Integer columnWidth= this.customPositionSizes.get(
					this.layer.dataProvider.getAllColumnsEqual() ?
							Long.valueOf(0) : Long.valueOf(position));
			if (columnWidth != null) {
					return columnWidth.intValue();
			}
			return getDefaultSize(position);
		}
		
		@Override
		public boolean isPositionResizable(final long position) {
			return true;
		}
		
		
		protected int getFormatterCharWidth(final long position) {
			RDataFormatter formatter;
			if (this.layer.dataProvider.getAllColumnsEqual()) {
				final RDataTableContentDescription description= this.layer.dataProvider.getDescription();
				if (description != null
						&& (formatter= description.getDefaultDataFormat()) != null
						&& formatter.getAutoWidth() >= 0) {
					return formatter.getAutoWidth();
				}
				return this.fallbackPositionSize;
			}
			else {
				final RDataTableContentDescription description= this.layer.dataProvider.getDescription();
				if (description != null) {
					final List<RDataTableColumn> columns= description.getDataColumns();
					if (position < columns.size()
							&& (formatter= columns.get((int) position).getDefaultFormat()) != null
							&& formatter.getAutoWidth() >= 0) {
						return formatter.getAutoWidth();
					}
					if ((formatter= description.getDefaultDataFormat()) != null
							&& formatter.getAutoWidth() >= 0) {
						return formatter.getAutoWidth();
					}
				}
				return this.fallbackPositionSize;
			}
		}
		
		protected int getDefaultSize(final long position) {
			final int charWidth= minmax(getFormatterCharWidth(position),
					this.defaultMinChars, this.defaultMaxChars );
			return charWidth * this.charSize + this.spacing;
		}
		
		protected int getAutoSize(final long position) {
			final int charWidth= minmax(getFormatterCharWidth(position),
					this.autoMinChars, this.autoMaxChars );
			return charWidth * this.charSize + this.spacing;
		}
		
		public void setCustomSize(final long position, final int size) {
			this.customPositionSizes.put(
					this.layer.dataProvider.getAllColumnsEqual() ?
							Long.valueOf(0) : Long.valueOf(position),
					size );
		}
		
		public void setAutoSize(final long position) {
			this.customPositionSizes.put(
					this.layer.dataProvider.getAllColumnsEqual() ?
							Long.valueOf(0) : Long.valueOf(position),
					getAutoSize(position) );
		}
		
	}
	
	private static class RowsDim extends DataDim<RDataLayer> {
		
		
		private int positionSize;
		
		
		public RowsDim(final RDataLayer layer, final int positionSize) {
			super(layer, Orientation.VERTICAL, PositionId.BODY_CAT);
			
			this.positionSize= positionSize;
		}
		
		
		@Override
		public long getPositionCount() {
			return this.layer.dataProvider.getRowCount();
		}
		
		public void setSize(final int rowHeight) {
			this.positionSize= rowHeight;
		}
		
		@Override
		public long getSize() {
			return getPositionCount() * this.positionSize;
		}
		
		@Override
		public long getPositionStart(final long position) {
			if (position < 0 || position >= getPositionCount()) {
				throw new IndexOutOfBoundsException("position: " + position); //$NON-NLS-1$
			}
			return position * this.positionSize;
		}
		
		@Override
		public int getPositionSize(final long position) {
			if (position < 0 || position >= getPositionCount()) {
				throw new IndexOutOfBoundsException("position: " + position); //$NON-NLS-1$
			}
			return this.positionSize;
		}
		
		@Override
		public boolean isPositionResizable(final long position) {
			return false;
		}
		
	}
	
	
	private final AbstractRDataProvider<?> dataProvider;
	
	private LayoutSizeConfig sizeConfig;
	
	
	public RDataLayer(final AbstractRDataProvider<?> dataProvider, final LayoutSizeConfig sizeConfig) {
		this.dataProvider= dataProvider;
		this.sizeConfig= sizeConfig;
		initDims();
		
		registerCommandHandlers();
	}
	
	
	@Override
	protected void initDims() {
		if (this.sizeConfig == null) {
			return;
		}
		
		setDim(new ColumnsDim(this,
				this.sizeConfig.getCharWidth(), this.sizeConfig.getDefaultSpace() * 4 ));
		setDim(new RowsDim(this,
				this.sizeConfig.getRowHeight() ));
	}
	
	private ColumnsDim getColumnDim() {
		return (ColumnsDim) getDim(HORIZONTAL);
	}
	
	private RowsDim getRowDim() {
		return (RowsDim) getDim(VERTICAL);
	}
	
	
	public void setSizeConfig(final LayoutSizeConfig sizeConfig) {
		this.sizeConfig= sizeConfig;
		
		getColumnDim().setSize(sizeConfig.getCharWidth(), this.sizeConfig.getDefaultSpace() * 4);
		getRowDim().setSize(sizeConfig.getRowHeight());
	}
	
	
	// Configuration
	
	@Override
	protected void registerCommandHandlers() {
		registerCommandHandler(new DimPositionResizeCommandHandler(this));
		registerCommandHandler(new MultiColumnResizeCommandHandler(this));
		registerCommandHandler(new MultiColumnAutoResizeCommandHandler(this));
//		registerCommandHandler(new UpdateDataCommandHandler(this));
	}
	
	
	// Columns
	
	public void setColumnWidth(final long columnPosition, final int width) {
		getColumnDim().setCustomSize(columnPosition, width);
		fireLayerEvent(new ColumnResizeEvent(this, columnPosition));
	}
	
	public void setColumnWidthToAutoWidth(final long columnPosition) {
		getColumnDim().setAutoSize(columnPosition);
		fireLayerEvent(new ColumnResizeEvent(this, columnPosition));
	}
	
	
	// Cell features
	
	@Override
	public ILayerCell getCellByPosition(final long columnPosition, final long rowPosition) {
		final ILayerDim hDim= getDim(HORIZONTAL);
		final ILayerDim vDim= getDim(VERTICAL);
		final long columnId= hDim.getPositionId(columnPosition, columnPosition);
		final long rowId= vDim.getPositionId(rowPosition, rowPosition);
		
		return new LayerCell(this,
				new LayerCellDim(HORIZONTAL, columnId, columnPosition),
				new LayerCellDim(VERTICAL, rowId, rowPosition) ) {
			
			@Override
			public Object getDataValue(final int flags, final IProgressMonitor monitor) {
				return RDataLayer.this.dataProvider.getDataValue(getColumnPosition(), getRowPosition(),
						flags, monitor );
			}
			
		};
	}
	
	@Override
	public ILayer getUnderlyingLayerByPosition(final long columnPosition, final long rowPosition) {
		return null;
	}
	
}
