package xcanvas

import "image"
import "github.com/jezek/xgbutil/xgraphics"

func (this *pen) line  (
	c      xgraphics.BGRA,
	min    image.Point,
	max    image.Point,
) {
	context := linePlottingContext {
		plottingContext: plottingContext {
			image:  this.image,
			color:  c,
			weight: this.weight,
		},
		min: min,
		max: max,
	}
	
	if abs(max.Y - min.Y) < abs(max.X - min.X) {
		if max.X < min.X { context.swap() }
		context.lineLow()
		
	} else {
		if max.Y < min.Y { context.swap() }
		context.lineHigh()
	}
}

type linePlottingContext struct {
	plottingContext
	min image.Point
	max image.Point
}

func (context *linePlottingContext) swap () {
	temp := context.max
	context.max = context.min
	context.min = temp
}

func (context linePlottingContext) lineLow () {
	deltaX := context.max.X - context.min.X
	deltaY := context.max.Y - context.min.Y
	yi     := 1

	if deltaY < 0 {
		yi      = -1
		deltaY *= -1
	}

	D := (2 * deltaY) - deltaX
	point := context.min

	for ; point.X < context.max.X; point.X ++ {
		context.plot(point)
		if D > 0 {
			D += 2 * (deltaY - deltaX)
			point.Y += yi
		} else {
			D += 2 * deltaY
		}
	}
}

func (context linePlottingContext) lineHigh () {
	deltaX := context.max.X - context.min.X
	deltaY := context.max.Y - context.min.Y
	xi     := 1

	if deltaX < 0 {
		xi      = -1
		deltaX *= -1
	}

	D := (2 * deltaX) - deltaY
	point := context.min

	for ; point.Y < context.max.Y; point.Y ++ {
		context.plot(point)
		if D > 0 {
			point.X += xi
			D += 2 * (deltaX - deltaY)
		} else {
			D += 2 * deltaX
		}
	}
}

func abs (n int) int {
	if n < 0 { n *= -1}
	return n
}