/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */
using Live2D.Cubism.Core;
using UnityEngine;
using UnityEngine.Rendering;
namespace Live2D.Cubism.Rendering.Masking
{
    /// 
    /// Renders out a single Cubism mask.
    /// 
    /// 
    /// Note that - depending on the model - multiple  might be assigned to a single .
    /// 
    internal sealed class CubismMaskRenderer
    {
        /// 
        /// Mask properties.
        /// 
        private MaterialPropertyBlock MaskProperties { get; set; }
        /// 
        /// Main renderer.
        /// 
        private CubismRenderer MainRenderer { get; set; }
        /// 
        /// Mask material.
        /// 
        private Material MaskMaterial { get; set; }
        /// 
        /// Mask culling material.
        /// 
        private Material MaskCullingMaterial { get; set; }
        /// 
        /// Culling setting.
        /// 
        private bool IsCulling { get; set; }
        /// 
        /// Bounds of .
        /// 
        internal Bounds MeshBounds
        {
            get { return MainRenderer.Mesh.bounds; }
        }
        #region Ctors
        /// 
        /// Initializes fields.
        /// 
        public CubismMaskRenderer()
        {
            MaskProperties = new MaterialPropertyBlock();
            MaskMaterial = CubismBuiltinMaterials.Mask;
            MaskCullingMaterial = CubismBuiltinMaterials.MaskCulling;
        }
        #endregion
        #region Interface For CubismMaskMaskedJunction
        /// 
        /// Sets the  to reference.
        /// 
        /// Value to set.
        /// Instance.
        internal CubismMaskRenderer SetMainRenderer(CubismRenderer value)
        {
            MainRenderer = value;
            IsCulling = !(MainRenderer.gameObject.GetComponent().IsDoubleSided);
            return this;
        }
        /// 
        /// Sets .
        /// 
        /// Value to set.
        /// Instance.
        internal CubismMaskRenderer SetMaskTile(CubismMaskTile value)
        {
            MaskProperties.SetVector(CubismShaderVariables.MaskTile, value);
            return this;
        }
        /// 
        /// Sets .
        /// 
        /// Value to set.
        /// Instance.
        internal CubismMaskRenderer SetMaskTransform(CubismMaskTransform value)
        {
            MaskProperties.SetVector(CubismShaderVariables.MaskTransform, value);
            return this;
        }
        /// 
        /// Enqueues
        /// 
        /// Buffer to enqueue in.
        internal void AddToCommandBuffer(CommandBuffer buffer)
        {
            // Lazily fetch drawable texture and mesh.
            var mainTexture = MainRenderer.MainTexture;
            var mesh = MainRenderer.Mesh;
            MaskProperties.SetTexture(CubismShaderVariables.MainTexture, mainTexture);
            // Add command.
            buffer.DrawMesh(mesh, Matrix4x4.identity,
                IsCulling
                    ? MaskCullingMaterial
                    : MaskMaterial,
                0, 0, MaskProperties);
        }
        #endregion
    }
}