// Copyright 2016 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 iconvg

import (
	"image/color"
	"math"

	"golang.org/x/image/math/f32"
)

const magic = "\x89IVG"

var magicBytes = []byte(magic)

var (
	negativeInfinity = math.Float32frombits(0xff800000)
	positiveInfinity = math.Float32frombits(0x7f800000)
)

func isNaNOrInfinity(f float32) bool {
	return math.Float32bits(f)&0x7f800000 == 0x7f800000
}

const (
	// File Format Version 0.
	midViewBox          = 0
	midSuggestedPalette = 1

	// File Format Version 1.
	ffv1MIDViewBox          = 8
	ffv1MIDSuggestedPalette = 16
)

var gradientShapeNames = [2]string{
	"linear",
	"radial",
}

var gradientSpreadNames = [4]string{
	"none",
	"pad",
	"reflect",
	"repeat",
}

// GradientSpread is how to spread a gradient past its nominal bounds (from
// offset being 0.0 to offset being 1.0).
type GradientSpread uint8

const (
	GradientSpreadNone    GradientSpread = 0
	GradientSpreadPad     GradientSpread = 1
	GradientSpreadReflect GradientSpread = 2
	GradientSpreadRepeat  GradientSpread = 3
)

// GradientStop is a color/offset gradient stop.
type GradientStop struct {
	Offset float32
	Color  color.Color
}

// Rectangle is defined by its minimum and maximum coordinates.
type Rectangle struct {
	Min, Max f32.Vec2
}

// AspectRatio returns the Rectangle's aspect ratio. An IconVG graphic is
// scalable; these dimensions do not necessarily map 1:1 to pixels.
func (r *Rectangle) AspectRatio() (dx, dy float32) {
	return r.Max[0] - r.Min[0], r.Max[1] - r.Min[1]
}

// Palette is an IconVG palette.
type Palette [64]color.RGBA

// Metadata is an IconVG's metadata.
type Metadata struct {
	ViewBox Rectangle

	// Palette is a 64 color palette. When encoding, it is the suggested
	// palette to place within the IconVG graphic. When decoding, it is either
	// the optional palette passed to Decode, or if no optional palette was
	// given, the suggested palette within the IconVG graphic.
	Palette Palette
}

// DefaultViewBox is the default ViewBox. Its values should not be modified.
var DefaultViewBox = Rectangle{
	Min: f32.Vec2{-32, -32},
	Max: f32.Vec2{+32, +32},
}

// DefaultPalette is the default Palette. Its values should not be modified.
var DefaultPalette = Palette{
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
	color.RGBA{0x00, 0x00, 0x00, 0xff},
}
