package comm

import (
	"math"
	"time"

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

const (
	AssetTypeMesh          = 10 //"mesh"     //模型
	AssetTypeImage         = 20 //"image"    //图片
	AssetTypeMaterial      = 30 //"material" //材质球
	AssetTypeMaterialGroup = 31 //"material" //材质球组
	AssetTypeEnv3d         = 40 //"hdr "      //环境球
	AssetTypeScene         = 50 //"scene "    //场景

	AssetState_Empty    = 0
	AssetState_Waiting  = 100 //等待处理
	AssetState_Proccing = 101 //正在处理
	AssetState_Failed   = 102 //处理失败！
	AssetState_Succ     = 200 //处理成功
)

type DbAsset struct {
	Id     string `bson:"id,omitempty" json:"id"` //资产id
	UserId string `bson:"userId,omitempty" json:"userId"`
	Label  string `bson:"label,omitempty" json:"label"`
	Type   int    `bson:"type,omitempty" json:"type"` //AssetTypeMesh  AssetTypeImage ...

	Collection  string    `bson:"collection,omitempty" json:"collection"` //数据库存储集合
	CreateTime  time.Time `bson:"createTime,omitempty" json:"createTime"`
	CategoryIds []string  `bson:"categoryIds,omitempty" json:"categoryIds"`
}

type AssetDbConf struct {
	Db        *Database
	AssetConf *DbAsset
}

type DbCategoryOld struct {
	Id         string    `bson:"id,omitempty" json:"id"`
	Type       string    `bson:"type,omitempty" json:"type"`
	Parent     string    `bson:"parent,omitempty" json:"parent"`
	Name       string    `bson:"name,omitempty" json:"name"`
	Value      string    `bson:"value,omitempty" json:"value"`
	Level      *int32    `bson:"level,omitempty" json:"level"`
	CreateTime time.Time `bson:"createTime,omitempty" json:"createTime"`
	OrderId    int64     `bson:"orderId,omitempty" json:"orderId"`
}

type DatabaseOld struct {
	Id     primitive.ObjectID `bson:"_id,omitempty" json:"_id"`       //数据库Id
	UserId string             `bson:"userId,omitempty" json:"userId"` //数据库Id

	Name       string    `bson:"name,omitempty" json:"name"`   //数据库名字
	Label      string    `bson:"label,omitempty" json:"label"` //前端展示标签
	CreateTime time.Time `bson:"createTime,omitempty" json:"createTime"`

	Categories []*DbCategoryOld `bson:"categories,omitempty" json:"categories"` //数据的分类
	Assets     []*DbAsset       `bson:"assets,omitempty" json:"assets"`         //资产定义
}

type Database struct {
	Id     primitive.ObjectID `bson:"_id,omitempty" json:"_id"`       //数据库Id
	UserId string             `bson:"userId,omitempty" json:"userId"` //数据库Id

	Name       string    `bson:"name,omitempty" json:"name"`   //数据库名字
	Label      string    `bson:"label,omitempty" json:"label"` //前端展示标签
	CreateTime time.Time `bson:"createTime,omitempty" json:"createTime"`

	Categories *DbCategory `bson:"categories,omitempty" json:"categories" complex:"true"` //数据的分类
	Assets     []*DbAsset  `bson:"assets,omitempty" json:"assets"  complex:"true"`        //资产定义
}

type UserDatabase struct {
	Id       primitive.ObjectID `bson:"_id,omitempty" json:"_id"`           //userId
	UserName string             `bson:"userName,omitempty" json:"userName"` //用户名字
	Limits   int                `bson:"limits,omitempty" json:"limits"`     //数据库限制数据
}

func CreateDefaultDbAssets() []*DbAsset {
	return []*DbAsset{
		{
			Id:         primitive.NewObjectID().Hex(),
			Label:      "模型",
			Type:       AssetTypeMesh,
			Collection: "mesh",
			CreateTime: time.Now(),
		},
		{
			Id:         primitive.NewObjectID().Hex(),
			Label:      "图片",
			Type:       AssetTypeImage,
			Collection: "image",
			CreateTime: time.Now(),
		},
		{
			Id:         primitive.NewObjectID().Hex(),
			Label:      "材质球",
			Type:       AssetTypeMaterial,
			Collection: "material",
			CreateTime: time.Now(),
		},
		{
			Id:         primitive.NewObjectID().Hex(),
			Label:      "环境球",
			Type:       AssetTypeEnv3d,
			Collection: "env3d",
			CreateTime: time.Now(),
		},
	}
}

func CreateDefaultDatabase() *Database {
	return &Database{
		Name:       "qdb-default",
		Label:      "默认资产库",
		CreateTime: time.Now(),

		Assets:     CreateDefaultDbAssets(),
		Categories: &DbCategory{},
	}
}

type Obb struct {
	Min Vec3Obj `bson:"min,omitempty" json:"min"`
	Max Vec3Obj `bson:"max,omitempty" json:"max"`
}

type AssetBase struct {
	OwnerId    primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`
	Name       string             `bson:"name,omitempty" json:"name"`
	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime time.Time          `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail  *OssType           `bson:"thumbnail,omitempty" json:"thumbnail"`
	Categories []string           `bson:"categories,omitempty" json:"categories"` //所属分类Id
	TaskId     string             `bson:"taskId,omitempty" json:"taskId"`         //资产处理id
	AssetState int                `bson:"assetState,omitempty" json:"assetState"`
	Enable     *bool              `bson:"enable,omitempty" json:"enable"` //是否有效！
}

type UvSize struct {
	Width  int `bson:"width,omitempty" json:"width,omitempty"`
	Height int `bson:"height,omitempty" json:"height,omitempty"`
}

type MatTextureColor struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Color      *Vect3   `bson:"color" json:"color"`
}

func (m *MatTextureColor) UpdateSourceUrl(handler UpdateUrlHandler) {
	if m.Texture != nil {
		m.Texture.UpdateSourceUrl(handler)
	}
}

type MatDiamond struct {
	ScaleY     *float32 `bson:"scaleY" json:"scaleY"`
	ScaleX     *float32 `bson:"scaleX" json:"scaleX"`
	Brightness *float32 `bson:"brightness" json:"brightness"`
	Color      *Vect3   `bson:"color" json:"color"`
}

type MatTextureFactor struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
}

func (m *MatTextureFactor) UpdateSourceUrl(handler UpdateUrlHandler) {
	if m.Texture != nil {
		m.Texture.UpdateSourceUrl(handler)
	}
}

type MatNormal struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
	FlipY      *bool    `bson:"flipY" json:"flipY"`
}

func (n *MatNormal) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type MatTextureFactorWithEnable struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
	Enable     bool     `bson:"enable" json:"enable"`
}

func (n *MatTextureFactorWithEnable) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type MatAlbedo struct {
	Color      *Vect3   `bson:"color" json:"color"`
	Texture    *OssType `bson:"texture" json:"texture"`
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
}

func (n *MatAlbedo) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type MatRoughness struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
}

func (n *MatRoughness) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type MatMetalness struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
}

func (n *MatMetalness) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type MatDisplace struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
}

type MatDiffuse struct {
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
	Texture    *OssType `bson:"texture" json:"texture"`
	Factor     *float32 `bson:"factor" json:"factor"`
}

type MatOpacity struct {
	Enable     bool     `bson:"enable" json:"enable"`
	Factor     *float32 `bson:"factor" json:"factor"`
	Texture    *OssType `bson:"texture" json:"texture"`
	UseTexture *bool    `bson:"useTexture" json:"useTexture"`
}

func (n *MatOpacity) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Texture != nil {
		n.Texture.UpdateSourceUrl(handler)
	}
}

type TechMatConfig struct {
	Version     int           `bson:"version,omitempty" json:"version"`
	Type        string        `bson:"type,omitempty" json:"type"`
	Uvtransform *MaterailUv   `bson:"uvtransform,omitempty" json:"uvtransform"`
	CullFace    string        `bson:"cullFace" json:"cullFace"`
	Albedo      *MatAlbedo    `bson:"albedo" json:"albedo"`
	Roughness   *MatRoughness `bson:"roughness" json:"roughness"`
	Metalness   *MatMetalness `bson:"metalness" json:"metalness"`
	Specular    *MatAlbedo    `bson:"specular" json:"specular"`
	Normal      *MatNormal    `bson:"normal" json:"normal"`
	Opacity     *MatOpacity   `bson:"opacity" json:"opacity"`
}

func (n *TechMatConfig) UpdateSourceUrl(handler UpdateUrlHandler) {
	if n.Albedo != nil {
		n.Albedo.UpdateSourceUrl(handler)
	}
	if n.Roughness != nil {
		n.Roughness.UpdateSourceUrl(handler)
	}
	if n.Metalness != nil {
		n.Metalness.UpdateSourceUrl(handler)
	}
	if n.Specular != nil {
		n.Specular.UpdateSourceUrl(handler)
	}
	if n.Normal != nil {
		n.Normal.UpdateSourceUrl(handler)
	}
	if n.Opacity != nil {
		n.Opacity.UpdateSourceUrl(handler)
	}
}

type ComponentImage struct {
	Id     string   `bson:"id" json:"id"`
	Image  *OssType `bson:"image" json:"image"`
	Width  int      `bson:"width" json:"width"`
	Height int      `bson:"height" json:"height"`

	Position         Vect2   `bson:"position" json:"position"`
	Scale            Vect2   `bson:"scale" json:"scale"`
	Rotation         float64 `bson:"rotation" json:"rotation"`
	FillType         string  `bson:"fillType" json:"fillType"`
	Technology       string  `bson:"technology" json:"technology"`
	BasicColor       Vect3   `bson:"basicColor" json:"basicColor"`
	AotuFactor       float32 `bson:"aotuFactor" json:"aotuFactor"`
	RoughFactor      float32 `bson:"roughFactor" json:"roughFactor"`
	ReflectionFactor float32 `bson:"reflectionFactor" json:"reflectionFactor"`
	MetalFactor      float32 `bson:"metalFactor" json:"metalFactor"`

	IsAotu  *bool `bson:"isAotu" json:"isAotu"`
	TjColor Vect3 `bson:"tjColor" json:"tjColor"` //烫金颜色
}

type MeshMatConf struct {
	UvMap        *OssType          `bson:"uvmap" json:"uvmap"`
	UvSize       *UvSize           `bson:"uvsize" json:"uvsize"`
	Name         string            `bson:"name" json:"name"`
	Material     *MaterialConf     `bson:"material" json:"material"`
	TechMaterial *TechMatConfig    `bson:"techMaterial" json:"techMaterial"`
	Images       []*ComponentImage `bson:"images" json:"images"`
	Index        int               `bson:"index" json:"index"`
	Visible      *bool             `bson:"visible" json:"visible"`
	UserData     interface{}       `bson:"userData,omitempty" json:"userData,omitempty"` //自定义数据
}

type StaticMeshSource struct {
	Components  []*MeshMatConf `bson:"components,omitempty" json:"components"`
	Osgjs       *OssType       `bson:"osgjs,omitempty" json:"osgjs"`
	File        *OssType       `bson:"file,omitempty" json:"file"` //hdr or fbx
	Glb         *OssType       `bson:"glb,omitempty" json:"glb"`   //hdr or fbx
	Shadow      *OssType       `bson:"shadow,omitempty" json:"shadow,omitempty"`
	BoundingBox *Obb           `bson:"boundingBox,omitempty" json:"boundingBox,omitempty"`
}

type HdrSource struct {
	Config  *Evn3dHdrConf `bson:"config,omitempty" json:"config"`
	File    *OssType      `bson:"file,omitempty" json:"file"` //hdr or fbx
	Options *Env3dOption  `bson:"options,omitempty" json:"options"`
	ToneMap *ToneMap      `bson:"toneMap,omitempty" json:"toneMap"`
}

type ImageSource struct {
	File *OssType `bson:"file,omitempty" json:"file"` //hdr or fbx
}

type AssetStaticMesh struct {
	Id        primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	UserId    primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`
	OwnerId   primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`     //userId teamId companyId
	OwnerType string             `bson:"ownerType,omitempty" json:"ownerType,omitempty"` //user team company

	Name   string `bson:"name,omitempty" json:"name"`
	CusNum string `bson:"cusNum,omitempty" json:"cusNum,omitempty"` //型号

	CreateTime    time.Time `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime    time.Time `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail     *OssType  `bson:"thumbnail,omitempty" json:"thumbnail"`
	Categories    []string  `bson:"categories,omitempty" json:"categories"`       //所属分类Id
	CusCategories []string  `bson:"cusCategories,omitempty" json:"cusCategories"` //所属分类Id

	TaskId     string `bson:"taskId,omitempty" json:"taskId"` //资产处理id
	AssetState int    `bson:"assetState,omitempty" json:"assetState"`
	Enable     *bool  `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source *StaticMeshSource `bson:"source,omitempty" json:"source,omitempty"`

	UserData interface{} `bson:"userData,omitempty" json:"userData,omitempty"` //自定义数据
}

type AssetEnv3dHdr struct {
	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	UserId     primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`                    //用户Id
	UserInfo   *AssetUserInfo     `bson:"userInfo,omitempty" json:"userInfo,omitempty" complex:"true"` //用户Id
	OwnerId    primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`
	OwnerType  string             `bson:"ownerType,omitempty" json:"ownerType,omitempty"`
	AssetType  string             `bson:"assetType,omitempty" json:"assetType,omitempty"`
	Name       string             `bson:"name,omitempty" json:"name"`
	CreateTime time.Time          `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime time.Time          `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail  *OssType           `bson:"thumbnail,omitempty" json:"thumbnail" complex:"true"`
	Categories []string           `bson:"categories,omitempty" json:"categories" complex:"true"` //所属分类Id
	TaskId     string             `bson:"taskId,omitempty" json:"taskId"`                        //资产处理id
	AssetState int                `bson:"assetState,omitempty" json:"assetState"`
	Enable     *bool              `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source   *HdrSource  `bson:"source,omitempty" json:"source,omitempty" complex:"true"`
	UserData interface{} `bson:"userData,omitempty" json:"userData,omitempty" complex:"true"` //用户数据
}

func (s *AssetEnv3dHdr) UpdateSourceUrl(handler UpdateUrlHandler) {
	if s.Thumbnail != nil {
		s.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.UserInfo != nil && s.UserInfo.Thumbnail != nil {
		s.UserInfo.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Source == nil {
		return
	}

	if s.Source.Config != nil {
		s.Source.Config.UpdateSourceUrl(handler)
	}
	if s.Source.File != nil {
		s.Source.File.UpdateSourceUrl(handler)
	}
}

func (s *AssetEnv3dHdr) SetIdEmpty() {
	s.Id = primitive.NilObjectID
}

func (s *AssetEnv3dHdr) ResetCreateTime() {
	s.CreateTime = time.Now()
	s.UpdateTime = time.Now()
}
func (s *AssetEnv3dHdr) SetOwner(id string, otype string) {
	s.OwnerId, _ = primitive.ObjectIDFromHex(id)
	s.OwnerType = otype
}
func (s *AssetEnv3dHdr) SetAssetType(otype string) {
	s.AssetType = otype
}

func (s *AssetEnv3dHdr) SetUserInfo(id string, info *AssetUserInfo) {
	s.UserId, _ = primitive.ObjectIDFromHex(id)
	s.UserInfo = info
}

type CusColorParams struct {
	BaseAlbedoId         string   `bson:"baseAlbedoId,omitempty" json:"baseAlbedoId,omitempty"` //基础图片
	BaseAlbedo           *OssType `bson:"baseAlbedo,omitempty" json:"baseAlbedo,omitempty"`     //基础图片
	SourceMode           *int     `bson:"sourceMode,omitempty" json:"sourceMode,omitempty"`
	SourceColor          *Vect3   `bson:"sourceColor,omitempty" json:"sourceColor,omitempty"`
	TargetColor          *Vect3   `bson:"targetColor,omitempty" json:"targetColor,omitempty"`
	ColorVariationHue    *int     `bson:"color_variation_hue,omitempty" json:"color_variation_hue,omitempty"`
	ColorVariationChroma *float32 `bson:"color_variation_chroma,omitempty" json:"color_variation_chroma,omitempty"`
	ColorVariationLuma   *float32 `bson:"color_variation_luma,omitempty" json:"color_variation_luma,omitempty"`
	UseMask              bool     `bson:"useMask,omitempty" json:"useMask,omitempty"`
	MaskHue              *int     `bson:"mask_hue,omitempty" json:"mask_hue,omitempty"`
	MaskChroma           *float32 `bson:"mask_chroma,omitempty" json:"mask_chroma,omitempty"`
	MaskLuma             *float32 `bson:"mask_luma,omitempty" json:"mask_luma,omitempty"`
	MaskBlur             *float32 `bson:"mask_blur,omitempty" json:"mask_blur,omitempty"`
	MaskSmoothness       *float32 `bson:"mask_smoothness,omitempty" json:"mask_smoothness,omitempty"`
}

const (
	MatGenerateCusColor       = "cuscolor" //色卡换色 算法生成
	MatGenerateTech           = "tech"     //按工艺生成
	CusColorSourceModeAverage = 0
	CusColorSourceModeColor   = 1
	CusColorSourceModeTexure  = 2
)

type MatConfigSource struct {
	Id        string   `bson:"id,omitempty" json:"id,omitempty"`
	Name      string   `bson:"name,omitempty" json:"name,omitempty"`
	CusNum    string   `bson:"cusNum,omitempty" json:"cusNum,omitempty"`
	Thumbnail *OssType `bson:"thumbnail,omitempty" json:"thumbnail,omitempty"`

	UvTransform    *MaterailUv `bson:"uv,omitempty" json:"uv,omitempty"`
	CusUvTransform *MaterailUv `bson:"cusUv,omitempty" json:"cusUv,omitempty"`
	CullFace       string      `bson:"cullFace" json:"cullFace,omitempty"`

	Diamond   *MatDiamond                 `bson:"diamond" json:"diamond,omitempty"`
	Albedo    *MatTextureColor            `bson:"albedo" json:"albedo,omitempty"`
	Roughness *MatTextureFactor           `bson:"roughness" json:"roughness,omitempty"`
	Metalness *MatTextureFactor           `bson:"metalness" json:"metalness,omitempty"`
	Normal    *MatNormal                  `bson:"normal" json:"normal,omitempty"`
	Opacity   *MatTextureFactorWithEnable `bson:"opacity" json:"opacity,omitempty"`

	Displace *MatTextureFactorWithEnable `bson:"displace,omitempty" json:"displace,omitempty"` //置换
	Diffuse  *MatTextureColor            `bson:"diffuse,omitempty" json:"diffuse,omitempty"`
	Specular *MatTextureColor            `bson:"specular" json:"specular,omitempty"`
	Gloss    *MatTextureFactor           `bson:"gloss,omitempty" json:"gloss,omitempty"` //光泽贴图

	Version   int    `bson:"version,omitempty" json:"version,omitempty"`
	Type      string `bson:"type,omitempty" json:"type,omitempty"`           //高光流 金属流(默认) meta spec
	UvMap     string `bson:"uvMap,omitempty" json:"uvMap,omitempty"`         //uv包裹 box、uv
	ClassType string `bson:"classType,omitempty" json:"classType,omitempty"` //pbr(默认) / diamond

	//工艺相关材质球
	TechMaterial *TechMatConfig    `bson:"techMaterial" json:"techMaterial,omitempty"`
	Images       []*ComponentImage `bson:"images" json:"images,omitempty"`

	//自定义换色材质
	ColorMatch   *CusColorParams `bson:"colorMatch" json:"colorMatch,omitempty"`     //自定义颜色参数
	GenerateType string          `bson:"generateType" json:"generateType,omitempty"` //面临生成类型 cuscolor(换色) / tech(工艺)

	//其他数据

	Anisotropic           float32 `bson:"anisotropic" json:"anisotropic"`
	AnisotropicRotation   float32 `bson:"anisotropicRotation" json:"anisotropicRotation"`
	Clearcoat             float32 `bson:"clearcoat" json:"clearcoat"`
	ClearcoatRoughness    float32 `bson:"clearcoatRoughness" json:"clearcoatRoughness"`
	Emission              Vect3   `bson:"emission" json:"emission"`
	EmissionStrength      float32 `bson:"emissionStrength" json:"emissionStrength"`
	Ior                   float32 `bson:"ior" json:"ior"`
	Sheen                 float32 `bson:"sheen" json:"sheen"`
	SheenTint             float32 `bson:"sheenTint" json:"sheenTint"`
	SpecularTint          float32 `bson:"specularTint" json:"specularTint"`
	Subsurface            float32 `bson:"subsurface" json:"subsurface"`
	SubsurfaceColor       Vect3   `bson:"subsurfaceColor" json:"subsurfaceColor"`
	SubsurfaceRadius      Vect3   `bson:"subsurfaceRadius" json:"subsurfaceRadius"`
	Transmission          float32 `bson:"transmission" json:"transmission"`
	TransmissionRoughness float32 `bson:"transmissionRoughness" json:"transmissionRoughness"`
	Reflectivity          float32 `bson:"reflectivity" json:"reflectivity"`

	UserData interface{} `bson:"userData,omitempty" json:"userData,omitempty"` //指定要数据放置的字段
}

func (m *MatConfigSource) UpdateSourceUrl(handler UpdateUrlHandler) {
	if m.Thumbnail != nil {
		m.Thumbnail.UpdateSourceUrl(handler)
	}
	if m.Albedo != nil {
		m.Albedo.UpdateSourceUrl(handler)
	}
	if m.Roughness != nil {
		m.Roughness.UpdateSourceUrl(handler)
	}
	if m.Metalness != nil {
		m.Metalness.UpdateSourceUrl(handler)
	}
	if m.Normal != nil {
		m.Normal.UpdateSourceUrl(handler)
	}
	if m.Opacity != nil {
		m.Opacity.UpdateSourceUrl(handler)
	}

	if m.Displace != nil {
		m.Displace.UpdateSourceUrl(handler)
	}
	if m.Diffuse != nil {
		m.Diffuse.UpdateSourceUrl(handler)
	}

	if m.Specular != nil {
		m.Specular.UpdateSourceUrl(handler)
	}
	if m.Gloss != nil {
		m.Gloss.UpdateSourceUrl(handler)
	}
	if m.TechMaterial != nil {
		m.TechMaterial.UpdateSourceUrl(handler)
	}

	for _, im := range m.Images {
		if im.Image != nil {
			im.Image.UpdateSourceUrl(handler)
		}
	}
	if m.ColorMatch != nil && m.ColorMatch.BaseAlbedo != nil {
		m.ColorMatch.BaseAlbedo.UpdateSourceUrl(handler)
	}
}

type AssetMatGroupSource struct {
	Version    string             `bson:"version,omitempty" json:"version"`
	ColorCards []*MatConfigSource `bson:"colorCards,omitempty" json:"colorCards"`
}

type AssetMatGroup struct {
	Id       primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	UserId   primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`
	OwnerId  primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`
	UserInfo *AssetUserInfo     `bson:"userInfo,omitempty" json:"userInfo,omitempty" complex:"true"` //用户信息

	OwnerType string `bson:"ownerType,omitempty" json:"ownerType,omitempty"`
	AssetType string `bson:"assetType,omitempty" json:"assetType,omitempty"`

	Name   string `bson:"name,omitempty" json:"name"`     //名字
	CusNum string `bson:"cusNum,omitempty" json:"cusNum"` //编号

	CreateTime    time.Time `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime    time.Time `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail     *OssType  `bson:"thumbnail,omitempty" json:"thumbnail" complex:"true"`
	Categories    []string  `bson:"categories,omitempty" json:"categories" complex:"true"`       //所属分类Id
	CusCategories []string  `bson:"cusCategories,omitempty" json:"cusCategories" complex:"true"` //所属分类Id
	TaskId        string    `bson:"taskId,omitempty" json:"taskId"`                              //资产处理id
	AssetState    int       `bson:"assetState,omitempty" json:"assetState"`
	Enable        *bool     `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source   *AssetMatGroupSource `bson:"source,omitempty" json:"source,omitempty" complex:"true"`
	UserData interface{}          `bson:"userData,omitempty" json:"userData,omitempty" complex:"true"` //自定义数据
}

func (s *AssetMatGroup) UpdateSourceUrl(handler UpdateUrlHandler) {
	if s.UserInfo != nil && s.UserInfo.Thumbnail != nil {
		s.UserInfo.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Thumbnail != nil {
		s.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Source != nil && s.Source.ColorCards != nil {
		for _, c := range s.Source.ColorCards {
			c.UpdateSourceUrl(handler)
		}
	}
}

func (s *AssetMatGroup) SetIdEmpty() {
	s.Id = primitive.NilObjectID
}
func (s *AssetMatGroup) ResetCreateTime() {
	s.CreateTime = time.Now()
	s.UpdateTime = time.Now()
}
func (s *AssetMatGroup) SetOwner(id string, otype string) {
	s.OwnerId, _ = primitive.ObjectIDFromHex(id)
	s.OwnerType = otype
}

func (s *AssetMatGroup) SetAssetType(otype string) {
	s.AssetType = otype
}

func (s *AssetMatGroup) SetUserInfo(id string, info *AssetUserInfo) {
	s.UserId, _ = primitive.ObjectIDFromHex(id)
	s.UserInfo = info
}

type AssetMat struct {
	Id        primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	UserId    primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`
	OwnerId   primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`
	OwnerType string             `bson:"ownerType,omitempty" json:"ownerType,omitempty"`
	AssetType string             `bson:"assetType,omitempty" json:"assetType,omitempty"`

	UserInfo *AssetUserInfo `bson:"userInfo,omitempty" json:"userInfo,omitempty" complex:"true"` //用户信息

	Name   string `bson:"name,omitempty" json:"name"`     //名字
	CusNum string `bson:"cusNum,omitempty" json:"cusNum"` //编号

	CreateTime    time.Time `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime    time.Time `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail     *OssType  `bson:"thumbnail,omitempty" json:"thumbnail" complex:"true"`
	Categories    []string  `bson:"categories,omitempty" json:"categories" complex:"true"`       //所属分类Id
	CusCategories []string  `bson:"cusCategories,omitempty" json:"cusCategories" complex:"true"` //所属分类Id
	TaskId        string    `bson:"taskId,omitempty" json:"taskId"`                              //资产处理id
	AssetState    int       `bson:"assetState,omitempty" json:"assetState"`
	Enable        *bool     `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source *MatConfigSource `bson:"source,omitempty" json:"source,omitempty" complex:"true"`

	UserData interface{} `bson:"userData,omitempty" json:"userData,omitempty" complex:"true"` //自定义数据
}

func (s *AssetMat) UpdateSourceUrl(handler UpdateUrlHandler) {
	if s.UserInfo != nil && s.UserInfo.Thumbnail != nil {
		s.UserInfo.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Thumbnail != nil {
		s.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Source != nil {
		s.Source.UpdateSourceUrl(handler)
	}
}

func (s *AssetMat) SetIdEmpty() {
	s.Id = primitive.NilObjectID
}
func (s *AssetMat) ResetCreateTime() {
	s.CreateTime = time.Now()
	s.UpdateTime = time.Now()
}
func (s *AssetMat) SetOwner(id string, otype string) {
	s.OwnerId, _ = primitive.ObjectIDFromHex(id)
	s.OwnerType = otype
}

func (s *AssetMat) SetAssetType(otype string) {
	s.AssetType = otype
}

func (s *AssetMat) SetUserInfo(id string, info *AssetUserInfo) {
	s.UserId, _ = primitive.ObjectIDFromHex(id)
	s.UserInfo = info
}

func (m *AssetMat) CopyFromSpecMat(sm *SpecialMat) {
	m.Name = sm.Name
	m.CreateTime = sm.CreateTime
	m.UpdateTime = sm.CreateTime
	m.Thumbnail = sm.Thumbnail
	m.UserData = map[string]string{"category": sm.Category}
	m.AssetState = AssetState_Succ
	trueV := true
	m.Enable = &trueV
	m.Source = &MatConfigSource{
		Version:   1,
		Id:        sm.Id.Hex(),
		Name:      sm.Name,
		Thumbnail: sm.Thumbnail,

		Type:        sm.Type,
		UvTransform: sm.Uvtransform,
		Albedo:      &MatTextureColor{},
		Roughness:   &MatTextureFactor{},
		Metalness:   &MatTextureFactor{},
		Opacity:     &MatTextureFactorWithEnable{Enable: false},
		Displace:    &MatTextureFactorWithEnable{Enable: false},
		Diffuse:     &MatTextureColor{},
		Specular:    &MatTextureColor{},
		Gloss:       &MatTextureFactor{},
	}

	if len(m.Source.Type) < 1 {
		m.Source.Type = "meta"
	}

	falseV := false

	if sm.BaseMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Albedo.UseTexture = &trueV
			m.Source.Albedo.Texture = sm.BaseMap
		} else {
			m.Source.Albedo.UseTexture = &falseV
			m.Source.Albedo.Color = sm.BaseColor
		}
	}

	if sm.NormalMap != nil {
		m.Source.Normal = &MatNormal{
			UseTexture: &trueV,
			Texture:    sm.NormalMap,
			FlipY:      &falseV,
		}
	}
	if sm.RoughMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Roughness.UseTexture = &trueV
			m.Source.Roughness.Texture = sm.RoughMap
		} else {
			m.Source.Roughness.UseTexture = &falseV
			if sm.RoughFactor != nil {
				v := float32(*sm.RoughFactor)
				m.Source.Roughness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Roughness.Factor = &v
			}

		}
	}
	if sm.MetalMap != nil {
		if len(sm.MetalMap.Url) > 0 {
			m.Source.Metalness.UseTexture = &trueV
			m.Source.Metalness.Texture = sm.MetalMap
		} else {
			m.Source.Metalness.UseTexture = &falseV
			if sm.MetalFactor != nil {
				v := float32(*sm.MetalFactor)
				m.Source.Metalness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Metalness.Factor = &v
			}
		}
	}
	if sm.OpacMap != nil {
		if len(sm.OpacMap.Url) > 0 {
			m.Source.Opacity.UseTexture = &trueV
			m.Source.Opacity.Texture = sm.OpacMap
			m.Source.Opacity.Enable = true
			if sm.OpacFactor != nil {
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			} else {
				v := float32(1.0)
				m.Source.Opacity.Factor = &v
			}

		} else if sm.OpacFactor != nil {
			if math.Abs(*sm.OpacFactor-1.0) < 0.001 {
				m.Source.Opacity.UseTexture = &falseV
				m.Source.Opacity.Enable = true
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			}
		}
	}

	if sm.DisplaceMap != nil {
		if len(sm.DisplaceMap.Url) > 0 {
			m.Source.Displace.UseTexture = &trueV
			m.Source.Displace.Texture = sm.DisplaceMap
			m.Source.Displace.Enable = true
		} else if sm.DisplaceFactor != nil {
			v := float32(*sm.DisplaceFactor)
			m.Source.Displace.Factor = &v
		}
	}

	if sm.DiffuseMap != nil {
		if len(sm.DiffuseMap.Url) > 0 {
			m.Source.Diffuse.UseTexture = &trueV
			m.Source.Diffuse.Texture = sm.DiffuseMap
		} else {
			m.Source.Diffuse.UseTexture = &falseV
			m.Source.Diffuse.Color = sm.DiffuseColor
		}
	}
	if sm.SpecMap != nil {
		if len(sm.SpecMap.Url) > 0 {
			m.Source.Specular.UseTexture = &trueV
			m.Source.Specular.Texture = sm.SpecMap
		} else {
			m.Source.Specular.UseTexture = &falseV
			m.Source.Specular.Color = sm.SpecColor
		}
	}
	if sm.GlossMap != nil {
		if len(sm.GlossMap.Url) > 0 {
			m.Source.Gloss.UseTexture = &trueV
			m.Source.Gloss.Texture = sm.GlossMap
		} else {
			m.Source.Gloss.UseTexture = &falseV
			if sm.GlossFactor != nil {
				v := float32(*sm.GlossFactor)
				m.Source.Gloss.Factor = &v
			}
		}
	}
	m.Source.UvMap = "box"
}

func (m *AssetMat) CopyFromLineMat(sm *LineMat) {
	m.Name = sm.Name
	m.CreateTime = sm.CreateTime
	m.UpdateTime = sm.CreateTime
	m.Thumbnail = sm.Thumbnail
	m.UserData = map[string]string{"category": sm.Category}
	m.AssetState = AssetState_Succ
	trueV := true
	m.Enable = &trueV
	m.Source = &MatConfigSource{
		Version:   1,
		Id:        sm.Id.Hex(),
		Name:      sm.Name,
		Thumbnail: sm.Thumbnail,

		Type:        sm.Type,
		UvTransform: sm.Uvtransform,
		Albedo:      &MatTextureColor{},
		Roughness:   &MatTextureFactor{},
		Metalness:   &MatTextureFactor{},
		Opacity:     &MatTextureFactorWithEnable{Enable: false},
		Displace:    &MatTextureFactorWithEnable{Enable: false},
		Diffuse:     &MatTextureColor{},
		Specular:    &MatTextureColor{},
		Gloss:       &MatTextureFactor{},
	}

	if len(m.Source.Type) < 1 {
		m.Source.Type = "meta"
	}

	falseV := false

	if sm.BaseMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Albedo.UseTexture = &trueV
			m.Source.Albedo.Texture = sm.BaseMap
		} else {
			m.Source.Albedo.UseTexture = &falseV
			m.Source.Albedo.Color = sm.BaseColor
		}
	}

	if sm.NormalMap != nil {
		m.Source.Normal = &MatNormal{
			UseTexture: &trueV,
			Texture:    sm.NormalMap,
			FlipY:      &falseV,
		}
	}
	if sm.RoughMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Roughness.UseTexture = &trueV
			m.Source.Roughness.Texture = sm.RoughMap
		} else {
			m.Source.Roughness.UseTexture = &falseV
			if sm.RoughFactor != nil {
				v := float32(*sm.RoughFactor)
				m.Source.Roughness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Roughness.Factor = &v
			}

		}
	}
	if sm.MetalMap != nil {
		if len(sm.MetalMap.Url) > 0 {
			m.Source.Metalness.UseTexture = &trueV
			m.Source.Metalness.Texture = sm.MetalMap
		} else {
			m.Source.Metalness.UseTexture = &falseV
			if sm.MetalFactor != nil {
				v := float32(*sm.MetalFactor)
				m.Source.Metalness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Metalness.Factor = &v
			}
		}
	}
	if sm.OpacMap != nil {
		if len(sm.OpacMap.Url) > 0 {
			m.Source.Opacity.UseTexture = &trueV
			m.Source.Opacity.Texture = sm.OpacMap
			m.Source.Opacity.Enable = true
			if sm.OpacFactor != nil {
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			} else {
				v := float32(1.0)
				m.Source.Opacity.Factor = &v
			}

		} else if sm.OpacFactor != nil {
			if math.Abs(*sm.OpacFactor-1.0) < 0.001 {
				m.Source.Opacity.UseTexture = &falseV
				m.Source.Opacity.Enable = true
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			}
		}
	}

	if sm.DisplaceMap != nil {
		if len(sm.DisplaceMap.Url) > 0 {
			m.Source.Displace.UseTexture = &trueV
			m.Source.Displace.Texture = sm.DisplaceMap
			m.Source.Displace.Enable = true
		} else if sm.DisplaceFactor != nil {
			v := float32(*sm.DisplaceFactor)
			m.Source.Displace.Factor = &v
		}
	}

	if sm.DiffuseMap != nil {
		if len(sm.DiffuseMap.Url) > 0 {
			m.Source.Diffuse.UseTexture = &trueV
			m.Source.Diffuse.Texture = sm.DiffuseMap
		} else {
			m.Source.Diffuse.UseTexture = &falseV
			m.Source.Diffuse.Color = sm.DiffuseColor
		}
	}
	if sm.SpecMap != nil {
		if len(sm.SpecMap.Url) > 0 {
			m.Source.Specular.UseTexture = &trueV
			m.Source.Specular.Texture = sm.SpecMap
		} else {
			m.Source.Specular.UseTexture = &falseV
			m.Source.Specular.Color = sm.SpecColor
		}
	}
	if sm.GlossMap != nil {
		if len(sm.GlossMap.Url) > 0 {
			m.Source.Gloss.UseTexture = &trueV
			m.Source.Gloss.Texture = sm.GlossMap
		} else {
			m.Source.Gloss.UseTexture = &falseV
			if sm.GlossFactor != nil {
				v := float32(*sm.GlossFactor)
				m.Source.Gloss.Factor = &v
			}
		}
	}
	m.Source.UvMap = "box"
}

func (m *AssetMat) CopyFromMatConf(sm *MaterialConf) {
	m.Name = sm.Name
	m.CreateTime = time.Now()
	m.UpdateTime = time.Now()
	m.Thumbnail = sm.Thumbnail
	m.CusNum = sm.CusNum
	m.AssetState = AssetState_Succ
	trueV := true
	m.Enable = &trueV
	m.Source = &MatConfigSource{
		Version:        1,
		Id:             sm.MatId.Hex(),
		CusNum:         sm.CusNum,
		Name:           sm.Name,
		Thumbnail:      sm.Thumbnail,
		UserData:       sm.UserData,
		Type:           sm.Type,
		UvTransform:    sm.Uvtransform,
		CusUvTransform: sm.CusUvTransform,
		Albedo:         &MatTextureColor{},
		Roughness:      &MatTextureFactor{},
		Metalness:      &MatTextureFactor{},
		Opacity:        &MatTextureFactorWithEnable{Enable: false},
		Displace:       &MatTextureFactorWithEnable{Enable: false},
		Diffuse:        &MatTextureColor{},
		Specular:       &MatTextureColor{},
		Gloss:          &MatTextureFactor{},
	}

	if len(m.Source.Type) < 1 {
		m.Source.Type = "meta"
	}

	falseV := false

	if sm.BaseMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Albedo.UseTexture = &trueV
			m.Source.Albedo.Texture = sm.BaseMap
		} else {
			m.Source.Albedo.UseTexture = &falseV
			m.Source.Albedo.Color = sm.BaseColor
		}
	}

	if sm.NormalMap != nil {
		m.Source.Normal = &MatNormal{
			UseTexture: &trueV,
			Texture:    sm.NormalMap,
			FlipY:      &falseV,
		}
	}
	if sm.RoughMap != nil {
		if len(sm.BaseMap.Url) > 0 {
			m.Source.Roughness.UseTexture = &trueV
			m.Source.Roughness.Texture = sm.RoughMap
		} else {
			m.Source.Roughness.UseTexture = &falseV
			if sm.RoughFactor != nil {
				v := float32(*sm.RoughFactor)
				m.Source.Roughness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Roughness.Factor = &v
			}

		}
	}
	if sm.MetalMap != nil {
		if len(sm.MetalMap.Url) > 0 {
			m.Source.Metalness.UseTexture = &trueV
			m.Source.Metalness.Texture = sm.MetalMap
		} else {
			m.Source.Metalness.UseTexture = &falseV
			if sm.MetalFactor != nil {
				v := float32(*sm.MetalFactor)
				m.Source.Metalness.Factor = &v
			} else {
				v := float32(0.5)
				m.Source.Metalness.Factor = &v
			}
		}
	}
	if sm.OpacMap != nil {
		if len(sm.OpacMap.Url) > 0 {
			m.Source.Opacity.UseTexture = &trueV
			m.Source.Opacity.Texture = sm.OpacMap
			m.Source.Opacity.Enable = true
			if sm.OpacFactor != nil {
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			} else {
				v := float32(1.0)
				m.Source.Opacity.Factor = &v
			}

		} else if sm.OpacFactor != nil {
			if math.Abs(*sm.OpacFactor-1.0) < 0.001 {
				m.Source.Opacity.UseTexture = &falseV
				m.Source.Opacity.Enable = true
				v := float32(*sm.OpacFactor)
				m.Source.Opacity.Factor = &v
			}
		}
	}

	if sm.DisplaceMap != nil {
		if len(sm.DisplaceMap.Url) > 0 {
			m.Source.Displace.UseTexture = &trueV
			m.Source.Displace.Texture = sm.DisplaceMap
			m.Source.Displace.Enable = true
		} else if sm.DisplaceFactor != nil {
			v := float32(*sm.DisplaceFactor)
			m.Source.Displace.Factor = &v
		}
	}

	if sm.DiffuseMap != nil {
		if len(sm.DiffuseMap.Url) > 0 {
			m.Source.Diffuse.UseTexture = &trueV
			m.Source.Diffuse.Texture = sm.DiffuseMap
		} else {
			m.Source.Diffuse.UseTexture = &falseV
			m.Source.Diffuse.Color = sm.DiffuseColor
		}
	}
	if sm.SpecMap != nil {
		if len(sm.SpecMap.Url) > 0 {
			m.Source.Specular.UseTexture = &trueV
			m.Source.Specular.Texture = sm.SpecMap
		} else {
			m.Source.Specular.UseTexture = &falseV
			m.Source.Specular.Color = sm.SpecColor
		}
	}
	if sm.GlossMap != nil {
		if len(sm.GlossMap.Url) > 0 {
			m.Source.Gloss.UseTexture = &trueV
			m.Source.Gloss.Texture = sm.GlossMap
		} else {
			m.Source.Gloss.UseTexture = &falseV
			if sm.GlossFactor != nil {
				v := float32(*sm.GlossFactor)
				m.Source.Gloss.Factor = &v
			}
		}
	}
	m.Source.UvMap = "box"
}

type AssetImage struct {
	Id        primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	UserId    primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`                     //用户Id
	UserInfo  *AssetUserInfo     `bson:"userInfo,omitempty" json:"userInfo,omitempty"  complex:"true"` //用户Id
	OwnerId   primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`
	OwnerType string             `bson:"ownerType,omitempty" json:"ownerType,omitempty"` //user team company
	AssetType string             `bson:"assetType,omitempty" json:"assetType,omitempty"` //user team company

	Name   string `bson:"name,omitempty" json:"name"`
	CusNum string `bson:"cusNum,omitempty" json:"cusNum,omitempty"` //型号

	CreateTime    time.Time `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime    time.Time `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail     *OssType  `bson:"thumbnail,omitempty" json:"thumbnail"  complex:"true"`
	Categories    []string  `bson:"categories,omitempty" json:"categories"  complex:"true"`       //所属分类Id
	CusCategories []string  `bson:"cusCategories,omitempty" json:"cusCategories"  complex:"true"` //所属分类Id

	TaskId     string `bson:"taskId,omitempty" json:"taskId"` //资产处理id
	AssetState int    `bson:"assetState,omitempty" json:"assetState"`
	Enable     *bool  `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source *ImageSource `bson:"source,omitempty" json:"source,omitempty" complex:"true"`
}

func (s *AssetImage) UpdateSourceUrl(handler UpdateUrlHandler) {
	if s.Thumbnail != nil {
		s.Thumbnail.UpdateSourceUrl(handler)
	}
	if s.Source != nil && s.Source.File != nil {
		s.Source.File.UpdateSourceUrl(handler)
	}
}

func (s *AssetImage) SetIdEmpty() {
	s.Id = primitive.NilObjectID
}
func (s *AssetImage) ResetCreateTime() {
	s.CreateTime = time.Now()
	s.UpdateTime = time.Now()
}
func (s *AssetImage) SetOwner(id string, otype string) {
	s.OwnerId, _ = primitive.ObjectIDFromHex(id)
	s.OwnerType = otype
}

func (s *AssetImage) SetAssetType(otype string) {
	s.AssetType = otype
}
func (s *AssetImage) SetUserInfo(id string, info *AssetUserInfo) {
	s.UserId, _ = primitive.ObjectIDFromHex(id)
	s.UserInfo = info
}

type AssetUserInfo struct {
	Name      string   `bson:"name,omitempty" json:"name"`
	Thumbnail *OssType `bson:"thumbnail,omitempty" json:"thumbnail"`
}

type AssetPackage struct {
	Id        primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
	OwnerId   primitive.ObjectID `bson:"ownerId,omitempty" json:"ownerId,omitempty"`                  //userId teamId companyId
	OwnerType string             `bson:"ownerType,omitempty" json:"ownerType,omitempty"`              //user team company
	UserId    primitive.ObjectID `bson:"userId,omitempty" json:"userId,omitempty"`                    //用户Id
	UserInfo  *AssetUserInfo     `bson:"userInfo,omitempty" json:"userInfo,omitempty" complex:"true"` //用户Id

	AssetType string `bson:"assetType,omitempty" json:"assetType,omitempty"` //业务类型 shoe sole heel decorate
	Name      string `bson:"name,omitempty" json:"name"`
	CusNum    string `bson:"cusNum,omitempty" json:"cusNum,omitempty"` //型号

	CreateTime    time.Time `bson:"createTime,omitempty" json:"createTime"`
	UpdateTime    time.Time `bson:"updateTime,omitempty" json:"updateTime"`
	Thumbnail     *OssType  `bson:"thumbnail,omitempty" json:"thumbnail" complex:"true"`
	Categories    []string  `bson:"categories,omitempty" json:"categories" complex:"true"`       //所属分类Id
	CusCategories []string  `bson:"cusCategories,omitempty" json:"cusCategories" complex:"true"` //所属分类Id

	TaskId string `bson:"taskId,omitempty" json:"taskId"` //资产处理id

	AssetState int   `bson:"assetState,omitempty" json:"assetState"`
	Enable     *bool `bson:"enable,omitempty" json:"enable"` //是否有效！

	Source   *Queen3dPackageSource `bson:"source,omitempty" json:"source,omitempty" complex:"true"`
	UserData interface{}           `bson:"userData,omitempty" json:"userData,omitempty" complex:"true"` //用户数据
}

func (s *AssetPackage) SetIdEmpty() {
	s.Id = primitive.NilObjectID
}
func (s *AssetPackage) ResetCreateTime() {
	s.CreateTime = time.Now()
	s.UpdateTime = time.Now()
}
func (s *AssetPackage) SetOwner(id string, otype string) {
	s.OwnerId, _ = primitive.ObjectIDFromHex(id)
	s.OwnerType = otype
}

func (s *AssetPackage) SetAssetType(otype string) {
	s.AssetType = otype
}

func (s *AssetPackage) SetUserInfo(id string, info *AssetUserInfo) {
	s.UserId, _ = primitive.ObjectIDFromHex(id)
	s.UserInfo = info
}

type UpdateUrlHandler func(string) string

func (s *AssetPackage) UpdateSourceUrl(handler UpdateUrlHandler) {
	if s.Thumbnail != nil {
		s.Thumbnail.Url = handler(s.Thumbnail.Url)
	}
	if s.Source == nil {
		return
	}

	source := s.Source
	for _, g := range source.Geoms {
		g.UpdateSourceUrl(handler)
	}
	for _, e := range source.Env3ds {
		e.UpdateSourceUrl(handler)
	}
	for _, p := range source.Products {
		p.UpdateSourceUrl(handler)
	}
	for _, s := range source.Scenes {
		s.UpdateSourceUrl(handler)
	}
	for _, m := range source.Mats {
		m.UpdateSourceUrl(handler)
	}
}
