// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package draw provides basic graphics and drawing primitives,
// in the style of the Plan 9 graphics library
// (see http://plan9.bell-labs.com/magic/man2html/2/draw)
// and the X Render extension.
package draw

// BUG(rsc): This is a toy library and not ready for production use.

import "image"

// A draw.Image is an image.Image with a Set method to change a single pixel.
type Image interface {
	image.Image
	Set(x, y int, c image.Color)
}

// Draw aligns r.Min in dst with pt in src and mask
// and then replaces the rectangle r in dst with the
// result of the Porter-Duff compositing operation
// ``(src in mask) over dst.''  If mask is nil, the operation
// simplifies to ``src over dst.''
// The implementation is simple and slow.
func Draw(dst Image, r Rectangle, src, mask image.Image, pt Point) {
	// Plenty of room for optimizations here.

	dx, dy := src.Width(), src.Height()
	if mask != nil {
		if dx > mask.Width() {
			dx = mask.Width()
		}
		if dy > mask.Width() {
			dy = mask.Width()
		}
	}
	dx -= pt.X
	dy -= pt.Y
	if r.Dx() > dx {
		r.Max.X = r.Min.X + dx
	}
	if r.Dy() > dy {
		r.Max.Y = r.Min.Y + dy
	}

	x0, x1, dx := r.Min.X, r.Max.X, 1
	y0, y1, dy := r.Min.Y, r.Max.Y, 1
	if image.Image(dst) == src && r.Overlaps(r.Add(pt.Sub(r.Min))) {
		// Rectangles overlap: process backward?
		if pt.Y < r.Min.Y || pt.Y == r.Min.Y && pt.X < r.Min.X {
			x0, x1, dx = x1-1, x0-1, -1
			y0, y1, dy = y1-1, y0-1, -1
		}
	}

	var out *image.RGBA64Color
	for y := y0; y != y1; y += dy {
		for x := x0; x != x1; x += dx {
			sx := pt.X + x - r.Min.X
			sy := pt.Y + y - r.Min.Y
			if mask == nil {
				dst.Set(x, y, src.At(sx, sy))
				continue
			}
			_, _, _, ma := mask.At(sx, sy).RGBA()
			switch ma {
			case 0:
				continue
			case 0xFFFFFFFF:
				dst.Set(x, y, src.At(sx, sy))
			default:
				dr, dg, db, da := dst.At(x, y).RGBA()
				dr >>= 16
				dg >>= 16
				db >>= 16
				da >>= 16
				sr, sg, sb, sa := src.At(sx, sy).RGBA()
				sr >>= 16
				sg >>= 16
				sb >>= 16
				sa >>= 16
				ma >>= 16
				const M = 1<<16 - 1
				a := sa * ma / M
				dr = (dr*(M-a) + sr*ma) / M
				dg = (dg*(M-a) + sg*ma) / M
				db = (db*(M-a) + sb*ma) / M
				da = (da*(M-a) + sa*ma) / M
				if out == nil {
					out = new(image.RGBA64Color)
				}
				out.R = uint16(dr)
				out.G = uint16(dg)
				out.B = uint16(db)
				out.A = uint16(da)
				dst.Set(x, y, out)
			}
		}
	}
}

// Border aligns r.Min in dst with sp in src and then replaces pixels
// in a w-pixel border around r in dst with the result of the Porter-Duff compositing
// operation ``src over dst.''  If w is positive, the border extends w pixels inside r.
// If w is negative, the border extends w pixels outside r.
func Border(dst Image, r Rectangle, w int, src image.Image, sp Point) {
	i := w
	if i > 0 {
		// inside r
		Draw(dst, Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+i), src, nil, sp)                          // top
		Draw(dst, Rect(r.Min.X, r.Min.Y+i, r.Min.X+i, r.Max.Y-i), src, nil, sp.Add(Pt(0, i)))        // left
		Draw(dst, Rect(r.Max.X-i, r.Min.Y+i, r.Max.X, r.Max.Y-i), src, nil, sp.Add(Pt(r.Dx()-i, i))) // right
		Draw(dst, Rect(r.Min.X, r.Max.Y-i, r.Max.X, r.Max.Y), src, nil, sp.Add(Pt(0, r.Dy()-i)))     // bottom
		return
	}

	// outside r;
	i = -i
	Draw(dst, Rect(r.Min.X-i, r.Min.Y-i, r.Max.X+i, r.Min.Y), src, nil, sp.Add(Pt(-i, -i))) // top
	Draw(dst, Rect(r.Min.X-i, r.Min.Y, r.Min.X, r.Max.Y), src, nil, sp.Add(Pt(-i, 0)))      // left
	Draw(dst, Rect(r.Max.X, r.Min.Y, r.Max.X+i, r.Max.Y), src, nil, sp.Add(Pt(r.Dx(), 0)))  // right
	Draw(dst, Rect(r.Min.X-i, r.Max.Y, r.Max.X+i, r.Max.Y+i), src, nil, sp.Add(Pt(-i, 0)))  // bottom
}
