package comm

import (
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

type OssType struct {
	Url  string `bson:"url" json:"url"`
	Size int64  `bson:"size" json:"size"`
}

func (o *OssType) UpdateSourceUrl(handler UpdateUrlHandler) {
	o.Url = handler(o.Url)
}

func NewOssTypeWithMap(data map[string]interface{}) *OssType {
	url := data["url"].(string)
	size := data["size"].(int64)

	return &OssType{Url: url, Size: size}
}

type MaterialConfig struct {
	Id   string
	Data interface{}
}

type Transform struct {
}

type Vect2 [2]float64
type Vect3 [3]float64
type Vect4 [4]float64

type VectXYWH struct {
	Y float64 `bson:"y" json:"y"`
	X float64 `bson:"x" json:"x"`
	W float64 `bson:"w" json:"w"`
	H float64 `bson:"h" json:"h"`
}

type Env3dOption struct {
	Rotation float64 `bson:"rotation" json:"rotation"`
	Exposure float64 `bson:"exposure" json:"exposure"`
}

type ToneMap struct {
	Method     *int32   `bson:"method,omitempty" json:"method"`         //0 "linear" 值0 "reinhard" 值 1 "filmic”:值2
	Exposure   *float64 `bson:"exposure,omitempty" json:"exposure"`     //默认值1 范围0到2
	Brightness *float64 `bson:"brightness,omitempty" json:"brightness"` //默认值0 范围-1到 1
	Contrast   *float64 `bson:"contrast,omitempty" json:"contrast"`     //默认值0 范围-1到1
	Saturation *float64 `bson:"saturation,omitempty" json:"saturation"` //默认值1 范围0-2
}

type Env3d struct {
	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	Name       string             `bson:"name,omitempty" json:"name"`
	CusNum     string             `bson:"cusNum,omitempty" json:"cusNum"` //自定义编号
	Thumbnail  *OssType           `bson:"thumbnail,omitempty" json:"thumbnail"`
	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
	HDR        *OssType           `bson:"hdr,omitempty" json:"hdr"`
	Config     *Evn3dHdrConf      `bson:"config,omitempty" json:"config"`
	Options    *Env3dOption       `bson:"options,omitempty" json:"options"`
	ToneMap    *ToneMap           `bson:"toneMap,omitempty" json:"toneMap"`
	Background *Evn3dBackground   `bson:"background,omitempty" json:"background"`

	UserData interface{} `bson:"userData,omitempty" json:"userData"` //用户数据
}

type Evn3dTextureImage struct {
	File             string  `bson:"file,omitempty" json:"file"`
	SizeUncompressed int32   `bson:"sizeUncompressed,omitempty" json:"sizeUncompressed"`
	Samples          uint32  `bson:"samples,omitempty" json:"samples"`
	Height           float32 `bson:"height,omitempty" json:"height"`
	Width            float32 `bson:"width,omitempty" json:"width"`
	SizeCompressed   int32   `bson:"sizeCompressed,omitempty" json:"sizeCompressed"`
	Blur             float32 `bson:"blur,omitempty,truncate" json:"blur"`
}

type Evn3dTexture struct {
	Images    []*Evn3dTextureImage `bson:"images,omitempty" json:"images"`
	LimitSize int32                `bson:"limitSize,omitempty" json:"limitSize"`
	Encoding  string               `bson:"encoding,omitempty" json:"encoding"`
	Type      string               `bson:"type,omitempty" json:"type"`
	Format    string               `bson:"format,omitempty" json:"format"`
}

type Evn3dLight struct {
	Direction  Vect3    `bson:"direction,omitempty" json:"direction"`
	Lum_ratio  float64  `bson:"lum_ratio,omitempty" json:"lum_ratio"`
	Color      Vect3    `bson:"color,omitempty" json:"color"`
	Luminosity float64  `bson:"luminosity,omitempty" json:"luminosity"`
	Sum        float64  `bson:"sum,omitempty" json:"sum"`
	Area       VectXYWH `bson:"area,omitempty" json:"area"`
	Error      int32    `bson:"error,omitempty" json:"error"`
	Variance   float64  `bson:"variance,omitempty" json:"variance"`
}

type Evn3dHdrConf struct {
	Textures       []*Evn3dTexture `bson:"textures,omitempty" json:"textures"`
	WriteByChannel bool            `bson:"writeByChannel,omitempty" json:"writeByChannel"`
	Lights         []*Evn3dLight   `bson:"lights,omitempty" json:"lights"`
	DiffuseSPH     []float64       `bson:"diffuseSPH,omitempty" json:"diffuseSPH"`
}

func (c *Evn3dHdrConf) UpdateSourceUrl(handler UpdateUrlHandler) {
	for _, t := range c.Textures {
		if t.Images == nil {
			continue
		}
		for _, img := range t.Images {
			img.File = handler(img.File)
		}
	}
}

type CanvasBackground struct {
	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	Color      *Vect3             `bson:"color,omitempty" json:"color"`
	Image      *OssType           `bson:"image,omitempty" json:"image"`
	Type       int32              `bson:"type,omitempty" json:"type"`
	Order      int32              `bson:"order,omitempty" json:"order"`
	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
}

func NewEnv3dToneMapWithMap(tone map[string]interface{}) *ToneMap {

	method := int32(0)
	Exposure := float64(1.0)
	Saturation := float64(1.0)
	Brightness := float64(0.0)
	Contrast := float64(0.0)

	if tone == nil {
		return &ToneMap{
			Method:     &method,
			Exposure:   &Exposure,
			Saturation: &Saturation,
			Brightness: &Brightness,
			Contrast:   &Contrast,
		}
	}

	if v, ok := tone["method"].(int32); ok {
		method = v
	}

	if v, ok := tone["exposure"].(float64); ok {
		Exposure = v
	}

	if v, ok := tone["saturation"].(float64); ok {
		Saturation = v
	}

	if v, ok := tone["brightness"].(float64); ok {
		Brightness = v
	}

	if v, ok := tone["contrast"].(float64); ok {
		Contrast = v
	}

	return &ToneMap{Method: &method, Exposure: &Exposure, Saturation: &Saturation, Brightness: &Brightness, Contrast: &Contrast}
}

type Evn3dBackground struct {
	Color *Vect3   `bson:"color,omitempty" json:"color"`
	Image *OssType `bson:"image,omitempty" json:"image"`
	Type  int32    `bson:"type,omitempty" json:"type"`
}
