using System.Collections;
using System.Collections.Generic;
using Godot;
using System;


namespace Rokojori
{

  public class MaterialType
  {
    public Trillean isStandard = Trillean.Any;
    public Shader shader = null;
    public BaseMaterial3D.TransparencyEnum transparency;
    public BaseMaterial3D.BlendModeEnum blendMode;
    public BaseMaterial3D.CullModeEnum cullMode;
    public BaseMaterial3D.DepthDrawModeEnum depthDrawMode;
    public bool noDepthTest = false;

    public BaseMaterial3D.ShadingModeEnum shadingMode;
    public BaseMaterial3D.DiffuseModeEnum diffuseMode;
    public BaseMaterial3D.SpecularModeEnum specularMode;
    public bool disableAmbientLight = false;
    public bool disableFog = false;


    public bool Equals( MaterialType materialType )
    { 

      if ( isStandard != materialType.isStandard )
      {
        return false;
      }

      if ( Trillean.False == isStandard )
      {
        return shader == materialType.shader;
      }

      if ( transparency != materialType.transparency )
      {
        return false;
      }

      if ( blendMode != materialType.blendMode )
      {
        return false;
      }

      if ( cullMode != materialType.cullMode )
      {
        return false;
      }

      if ( depthDrawMode != materialType.depthDrawMode )
      {
        return false;
      }

      if ( noDepthTest != materialType.noDepthTest )
      {
        return false;
      }


      if ( shadingMode != materialType.shadingMode )
      {
        return false;
      }

      if ( diffuseMode != materialType.diffuseMode )
      {
        return false;
      }

      if ( specularMode != materialType.specularMode )
      {
        return false;
      }

      if ( disableAmbientLight != materialType.disableAmbientLight )
      {
        return false;
      }

      if ( disableFog != materialType.disableFog )
      {
        return false;
      }

      return true;

    }

    public bool EqualsTo( Material materialType )
    {
      if ( materialType is StandardMaterial3D sm )
      {
        return EqualsTo( sm );
      } 

      return false;
    }

    public bool EqualsTo( StandardMaterial3D materialType )
    {
      if ( ! TrilleanLogic.Matches( isStandard, true )  )
      {
        return false;
      }

      if ( transparency != materialType.Transparency )
      {
        return false;
      }

      if ( blendMode != materialType.BlendMode )
      {
        return false;
      }

      if ( cullMode != materialType.CullMode )
      {
        return false;
      }

      if ( depthDrawMode != materialType.DepthDrawMode )
      {
        return false;
      }

      if ( noDepthTest != materialType.NoDepthTest )
      {
        return false;
      }


      if ( shadingMode != materialType.ShadingMode )
      {
        return false;
      }

      if ( diffuseMode != materialType.DiffuseMode )
      {
        return false;
      }

      if ( specularMode != materialType.SpecularMode )
      {
        return false;
      }

      if ( disableAmbientLight != materialType.DisableAmbientLight )
      {
        return false;
      }

      if ( disableFog != materialType.DisableFog )
      {
        return false;
      }

      return true;

    }

    public void CopyFrom( MaterialType materialType )
    {
      isStandard = materialType.isStandard;

      shader = materialType.shader;

      transparency = materialType.transparency;
      blendMode = materialType.blendMode;
      cullMode = materialType.cullMode;
      depthDrawMode = materialType.depthDrawMode;
      noDepthTest = materialType.noDepthTest;

      shadingMode = materialType.shadingMode;
      diffuseMode = materialType.diffuseMode;
      specularMode = materialType.specularMode;
      disableAmbientLight = materialType.disableAmbientLight;
      disableFog = materialType.disableFog;
    }

    public override string ToString()
    {
      return JSON.StringifyObject( this );
    }

    public static MaterialType From( Material material )
    {
      if ( material is StandardMaterial3D sm )
      {
        return From( sm );
      }


      return From( material as ShaderMaterial );
    }

    public static MaterialType From( ShaderMaterial shaderMaterial )
    {
      var mt = new MaterialType();
      
      mt.isStandard = Trillean.False;
      mt.shader = shaderMaterial.Shader;

      // public (?:\w+\.)?\w+ (\w+).*?;
      // mt.$1 = standardMaterial3D.$1;

      // mt.transparency = standardMaterial3D.;
      // mt.blendMode = standardMaterial3D.BlendMode;
      // mt.cullMode = standardMaterial3D.CullMode;
      // mt.depthDrawMode = standardMaterial3D.DepthDrawMode;
      // mt.noDepthTest = standardMaterial3D.NoDepthTest;

      // mt.shadingMode = standardMaterial3D.ShadingMode;
      // mt.diffuseMode = standardMaterial3D.DiffuseMode;
      // mt.specularMode = standardMaterial3D.SpecularMode;
      // mt.disableAmbientLight = standardMaterial3D.DisableAmbientLight;
      // mt.disableFog = standardMaterial3D.DisableFog;

      return mt;
    }

    public static MaterialType From( StandardMaterial3D standardMaterial3D )
    {
      var mt = new MaterialType();
      
      mt.isStandard = Trillean.True;

      // public (?:\w+\.)?\w+ (\w+).*?;
      // mt.$1 = standardMaterial3D.$1;

      mt.transparency = standardMaterial3D.Transparency;
      mt.blendMode = standardMaterial3D.BlendMode;
      mt.cullMode = standardMaterial3D.CullMode;
      mt.depthDrawMode = standardMaterial3D.DepthDrawMode;
      mt.noDepthTest = standardMaterial3D.NoDepthTest;

      mt.shadingMode = standardMaterial3D.ShadingMode;
      mt.diffuseMode = standardMaterial3D.DiffuseMode;
      mt.specularMode = standardMaterial3D.SpecularMode;
      mt.disableAmbientLight = standardMaterial3D.DisableAmbientLight;
      mt.disableFog = standardMaterial3D.DisableFog;

      return mt;
    }

    public static MaterialType From( MaterialType materialType )
    {
       var mt = new MaterialType();
      
      mt.isStandard = materialType.isStandard;

      mt.transparency = materialType.transparency;
      mt.blendMode = materialType.blendMode;
      mt.cullMode = materialType.cullMode;
      mt.depthDrawMode = materialType.depthDrawMode;
      mt.noDepthTest = materialType.noDepthTest;

      mt.shadingMode = materialType.shadingMode;
      mt.diffuseMode = materialType.diffuseMode;
      mt.specularMode = materialType.specularMode;
      mt.disableAmbientLight = materialType.disableAmbientLight;
      mt.disableFog = materialType.disableFog;

      return mt;
    }

    public void ApplyTo( StandardMaterial3D standardMaterial3D )
    {
      standardMaterial3D.Transparency = transparency;
      standardMaterial3D.BlendMode = blendMode;
      standardMaterial3D.CullMode = cullMode;
      standardMaterial3D.DepthDrawMode = depthDrawMode;
      standardMaterial3D.NoDepthTest = noDepthTest;

      standardMaterial3D.ShadingMode = shadingMode;
      standardMaterial3D.DiffuseMode = diffuseMode;
      standardMaterial3D.SpecularMode = specularMode;
      standardMaterial3D.DisableAmbientLight = disableAmbientLight;
      standardMaterial3D.DisableFog = disableFog;
    }
  }
}