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

import java.io.Serializable
import java.util.TreeMap

import static extension org.eclipse.nebula.widgets.nattable.core.layer.axis.AxisInvariants.*

/**
 * A simple Axis implementation.
 */
class AxisImpl extends AbstractAxis {
	
	long segmentCount
	double defaultSegmentSize
	val segmentSizeMap = new TreeMap<Long, Double>  // segment Position -> pixel size
	
	new() {}
	
	new(long segmentCount, double defaultSegmentSize) {
		setSegmentCount(segmentCount)
		setDefaultSegmentSize(defaultSegmentSize)
	}
	
	def void setSegmentCount(long segmentCount) {
		this.segmentCount = segmentCount
	}
	
	def void setDefaultSegmentSize(double defaultSegmentSize) {
		this.defaultSegmentSize = defaultSegmentSize
	}
	
	// Axis interface
	
	override getSegmentCount() {
		segmentCount
	}

	override getStartPixelOfSegmentPosition(long segmentPosition) {
		if (segmentPosition < 0) return -1
		else if (segmentPosition == 0) return 0
		else if (segmentSizeMap.empty) return segmentPosition * defaultSegmentSize
		else {
			var numResizedSegments = 0
			var resizeAggregate = 0.0
			
			for (resizedSegmentPosition : segmentSizeMap.subMap(0L, segmentPosition).keySet) {
				numResizedSegments = numResizedSegments + 1
				resizeAggregate = resizeAggregate + segmentSizeMap.get(resizedSegmentPosition)
			}

			return ((segmentPosition - numResizedSegments) * defaultSegmentSize) + resizeAggregate
		}
	}
	
	override getSegmentPositionOfPixelLocation(double pixelLocation) {
		if (pixelLocation < 0) return -1
		else if (pixelLocation == 0) return 0
		else if (pixelLocation >= pixelSize) return segmentCount
		else if (segmentSizeMap.empty) return (pixelLocation / defaultSegmentSize) as long
		else return findSegmentPositionOfPixelLocation(pixelLocation, 0, pixelSize, 0, segmentCount)
	}
	
	def private long findSegmentPositionOfPixelLocation(double pixelLocation, double fromPixel, double toPixel, long fromSegmentPosition, long toSegmentPosition) {
		// guess segment position = pixelLocation / size of guess region
		val guessSegmentSize = (toPixel - fromPixel) / (toSegmentPosition - fromSegmentPosition)
		val guessSegmentPosition = fromSegmentPosition + ((pixelLocation - fromPixel) / guessSegmentSize) as long
		
		// find start/end pixel of guessed segment position
		val startPixel = getStartPixelOfSegmentPosition(guessSegmentPosition)
		val endPixel = startPixel + getPixelSizeOfSegmentPosition(guessSegmentPosition)
		
		if (pixelLocation < startPixel)
			return findSegmentPositionOfPixelLocation(pixelLocation, fromPixel, startPixel, fromSegmentPosition, guessSegmentPosition)
		else if (pixelLocation >= endPixel)
			return findSegmentPositionOfPixelLocation(pixelLocation, endPixel, toPixel, guessSegmentPosition + 1, toSegmentPosition)
		else
			return guessSegmentPosition
	}
	
	override getIdOfSegmentPosition(long segmentPosition) {
		segmentPosition
	}
	
	override getSegmentPositionOfId(Serializable segmentId) {
		if (segmentId != null)
			return segmentId as Long
		else
			return -1
	}
	
	//

	def void setPixelSizeOfSegmentPosition(double size, long segmentPosition) {
		if (!containsSegmentPosition(segmentPosition)) throw new IllegalArgumentException('''segment position «segmentPosition» is not contained in this axis''')
		if (size < 0) throw new IllegalArgumentException("size must be >= 0")
		
		segmentSizeMap.put(segmentPosition, size)
	}
	
}