package org.eclipse.nebula.widgets.nattable.core.layer.impl.viewport

import java.io.Serializable
import java.math.BigDecimal
import java.math.BigInteger
import org.eclipse.nebula.widgets.nattable.core.big.layer.axis.BigAxis
import org.eclipse.nebula.widgets.nattable.core.layer.axis.impl.AbstractAxis

import static extension org.eclipse.nebula.widgets.nattable.core.big.layer.axis.BigAxisInvariants.*
import static extension org.eclipse.nebula.widgets.nattable.core.big.math.BigIntegerExtensions.*

class ViewportAxis extends AbstractAxis {
	
	val BigAxis underlyingAxis
	val ViewportAxisListener viewportAxisListener
	
	BigDecimal minPixelOrigin = BigDecimal::ZERO
	BigDecimal maxPixelSize
	
	/**
	 * Indicates the visible size of the axis. Note that the pixel locations returned by this ClientDimensionProvider
	 * must be in terms of underlying axis pixel coordinates.
	 */
	BigDecimal visiblePixelSize = -BigDecimal::ONE
	
	BigDecimal pixelOrigin = BigDecimal::ZERO
	
	new(BigAxis underlyingAxis, ViewportAxisListener viewportAxisListener) {
		this.underlyingAxis = underlyingAxis
		this.viewportAxisListener = viewportAxisListener
	}
	
	def getUnderlyingAxis() { underlyingAxis }
	
	def setMinPixelOrigin(double minPixelOrigin) { setMinPixelOrigin(new BigDecimal(minPixelOrigin)) }
	def setMinPixelOrigin(BigDecimal minPixelOrigin) { this.minPixelOrigin = minPixelOrigin }
	def setMaxPixelSize(double maxPixelSize) { setMaxPixelSize(new BigDecimal(maxPixelSize)) }
	def setMaxPixelSize(BigDecimal maxPixelSize) { this.maxPixelSize = maxPixelSize }
	
	override getMinPixelLocation() {
		if (minPixelOrigin != null)
			minPixelOrigin.doubleValue
		else
			super.minPixelLocation
	}
	
	override getPixelSize() {
		if (maxPixelSize != null)
			maxPixelSize.doubleValue
		else
			super.pixelSize
	}
	
	def getVisiblePixelSize() {
		val pixelSize =
			if (visiblePixelSize >= BigDecimal::ZERO) visiblePixelSize
			else underlyingAxis.pixelSize
		if (maxPixelSize != null)
			pixelSize.min(maxPixelSize)
		else
			pixelSize
	}
	
	def setVisiblePixelSize(double visiblePixelSize) {
		setVisiblePixelSize(new BigDecimal(visiblePixelSize))
	}
	
	def setVisiblePixelSize(BigDecimal visiblePixelSize) {
		this.visiblePixelSize = visiblePixelSize
	}
	
	def getPixelOrigin() { pixelOrigin }
	
	def void setPixelOrigin(double pixelOrigin) {
		setPixelOrigin(new BigDecimal(pixelOrigin))
	}
	
	def void setPixelOrigin(BigDecimal pixelOrigin) {
		this.pixelOrigin = pixelOrigin
		viewportAxisListener?.viewportAxisChanged
	}
	
	def getOriginSegmentPosition() {
		underlyingAxis.getSegmentPositionOfPixelLocation(pixelOrigin)
	}
	
	def void handleResize() {
		// If the visible pixel size is greater than the content size, move origin to fill as much content as possible.
		val additionalSize = pixelOrigin + getVisiblePixelSize - underlyingAxis.pixelSize
		if (additionalSize > BigDecimal::ZERO)
			pixelOrigin = BigDecimal::ZERO.max(pixelOrigin - additionalSize)
	}
	
	// Layer interface
	
	override getSegmentCount() {
		val endPixel = pixelOrigin + getVisiblePixelSize
		val endSegmentPosition = underlyingAxis.getSegmentPositionOfPixelLocation(endPixel)
		val isEndPixelInsideEndSegment = endPixel > underlyingAxis.getStartPixelOfSegmentPosition(endSegmentPosition) && endPixel < underlyingAxis.getStartPixelOfSegmentPosition(underlyingAxis.segmentCount)
		val segmentCount = endSegmentPosition - originSegmentPosition
		segmentCount.intValue + if (isEndPixelInsideEndSegment) 1 else 0
	}
	
	override getStartPixelOfSegmentPosition(int segmentPosition) {
		(underlyingAxis.getStartPixelOfSegmentPosition(originSegmentPosition + BigInteger::valueOf(segmentPosition)) - pixelOrigin).doubleValue
	}
	
	override getSegmentPositionOfPixelLocation(double pixelLocation) {
		val underlyingPixelLocation = pixelOrigin + BigDecimal::valueOf(pixelLocation)
		if (underlyingPixelLocation < BigDecimal::ZERO) return -1
		if (underlyingPixelLocation >= underlyingAxis.pixelSize) return getSegmentCount()
		(underlyingAxis.getSegmentPositionOfPixelLocation(underlyingPixelLocation) - originSegmentPosition).intValueExact
	}
	
	override getIdOfSegmentPosition(int segmentPosition) {
		underlyingAxis.getIdOfSegmentPosition(originSegmentPosition + BigInteger::valueOf(segmentPosition))
	}
	
	override getSegmentPositionOfId(Serializable segmentId) {
		(underlyingAxis.getSegmentPositionOfId(segmentId) - originSegmentPosition).intValueExact
	}
	
}