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 {
	
	int segmentCount
	double defaultSegmentSize
	val segmentSizeMap = new TreeMap<Integer, Double>  // segment Position -> pixel size
	
	new() {}
	
	new(int segmentCount, double defaultSegmentSize) {
		setSegmentCount(segmentCount)
		setDefaultSegmentSize(defaultSegmentSize)
	}
	
	def void setSegmentCount(int segmentCount) {
		this.segmentCount = segmentCount
	}
	
	def void setDefaultSegmentSize(double defaultSegmentSize) {
		this.defaultSegmentSize = defaultSegmentSize
	}
	
	// Axis interface
	
	override getSegmentCount() {
		segmentCount
	}

	override getStartPixelOfSegmentPosition(int 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(0, 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 int
		else return findSegmentPositionOfPixelLocation(pixelLocation, 0, pixelSize, 0, segmentCount)
	}
	
	def private int findSegmentPositionOfPixelLocation(double pixelLocation, double fromPixel, double toPixel, int fromSegmentPosition, int toSegmentPosition) {
		// guess segment position = pixelLocation / size of guess region
		val guessSegmentSize = (toPixel - fromPixel) / (toSegmentPosition - fromSegmentPosition)
		val guessSegmentPosition = fromSegmentPosition + ((pixelLocation - fromPixel) / guessSegmentSize) as int
		
		// 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(int segmentPosition) {
		segmentPosition
	}
	
	override getSegmentPositionOfId(Serializable segmentId) {
		if (segmentId != null)
			return (segmentId as Number).intValue
		else
			return -1
	}
	
	//

	def void setPixelSizeOfSegmentPosition(double size, int 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)
	}
	
}