package main

import (
	"fmt"
	rl "github.com/gen2brain/raylib-go/raylib"
	"github.com/ojrac/opensimplex-go"
)

type Field interface {
	/**
	 * return a value on the range 0,1
	 */
	Get(x float32, y float32) float32
}

// TRANSFORM FIELDS
type ScaleField struct {
	field Field
	scale float32
}

func (f *ScaleField) Get(x, y float32) float32 {
	return f.field.Get(x/f.scale, y/f.scale)
}

type TranslateField struct {
	field Field
	x, y  float32
}

func (f TranslateField) Get(x float32, y float32) float32 {
	return f.field.Get(x+f.x, y+f.y)
}

// NOISE FIELDS

type SimplexNoiseField struct {
	Noise opensimplex.Noise32
}

func (f *SimplexNoiseField) Get(x, y float32) float32 {
	return f.Noise.Eval2(x, y)
}

// IMAGE FIELDS

type ImageField struct {
	image            *rl.Image
	pixels           ImagePixels
	offsetX, offsetY int
}

type ImagePixels struct {
	w, h   int
	colors []rl.Color
}

func (p *ImagePixels) Get(x, y int) rl.Color {
	if x < 0 || x >= p.w {
		return rl.Black
	}
	if y < 0 || y >= p.h {
		return rl.Black
	}
	return p.colors[x+y*p.w]
}

func NewImageField(path string) *ImageField {
	image := rl.LoadImage(path)
	fmt.Printf("loaded image from %s\n", path)
	colors := rl.LoadImageColors(image)
	pixels := ImagePixels{
		w:      int(image.Width),
		h:      int(image.Height),
		colors: colors,
	}
	offsetX := int(image.Width)/2
	offsetY := int(image.Height)/2
	return &ImageField {
		image:   image,
		pixels:  pixels,
		offsetX: offsetX,
		offsetY: offsetY,
	}
}

// zero centered
func (f *ImageField) Get(x, y float32) float32 {
	// todo : blend colors
	c := f.pixels.Get(int(x+float32(f.offsetX)), int(y+float32(f.offsetY)))
	return Brightness(c)
}
