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


namespace Rokojori.Reallusion
{  
  public class CCCustomShader:CCImportFileBase
  {  
    public string name;


    public CCCustomShader( CCImportFile file, string name ):base( file )
    {
      this.name = name;
    } 

    JSONObject _jsonObject;

    public void ReadFrom( JSONObject jsonObject )
    {
      _jsonObject = jsonObject;

      if ( name == "RLEyeOcclusion" )
      {
        ReadEyeOcclusion( jsonObject );
      }

      if ( name == "RLEye" )
      {
        ReadEye( jsonObject );
      }
    } 

    public CCJSONProperty<List<float>> shadowTopColor = new CCJSONProperty<List<float>>( "Shadow Color");
    public CCJSONProperty<List<float>> shadowBottomColor = new CCJSONProperty<List<float>>( "Shadow2 Color");

    void ReadEyeOcclusion( JSONObject jsonObject )
    {
      var variable = jsonObject.GetObject( "Variable" );

      shadowTopColor.Read( variable );
      shadowBottomColor.Read( variable );
    }

    public float GetFloatVariable( string name, float alternative = 0 )
    {
      var value = _jsonObject.ByPath<JSONValue>( "Variable", name );

      if ( value == null )
      {
        return alternative;
      }
      
      return value.floatValue;
    }

    public List<float> GetFloatArrayVariable( string name )
    {
      var value = _jsonObject.ByPath<JSONArray>( "Variable", name );

      return value.AsFloatList();
    }

    public Vector3 GetVector3Variable( string name )
    {
      var value = GetFloatArrayVariable( name );

      var v = Vector3.Zero;
      v.X = value[ 0 ];
      v.Y = value[ 1 ];
      v.Z = value[ 2 ];
      
      return v;
    }

    public Color GetColorVariable( string name, float basis, bool sRGB )
    {
      var value = GetFloatArrayVariable( name );

      var color = ColorX.From( value, basis );

      if ( sRGB )
      {
        color = color.LinearToSRGB();
      }

      return color;
    }

    public Vector3 GetColorVariableAsVector3( string name, float basis, bool sRGB )
    {
      var color = GetColorVariable( name, basis, sRGB );
      return new Vector3( color.R, color.G, color.B );
    }

    public string GetImageTexturePath( string name )
    {
      var value = _jsonObject.ByPath<JSONValue>( "Image", name, "Texture Path" );
      
      if ( value == null )
      {
        return null;
      }
      
      return value.stringValue;
      
    }

    public Texture2D GetImageTexture( string name )
    {
      var path = GetImageTexturePath( name );
      return GetTextureFromRelativePath( path );
    }

    Texture2D GetTextureFromRelativePath( string relativePath )
    {
      var rootDirectoryPath = FilePath.Absolute( importFile.directory );
      var relativeFilePath = rootDirectoryPath.MakeRelative( relativePath );

      try
      {
        var texture = ResourceLoader.Load<Texture2D>( relativeFilePath.fullPath );

        return texture;
      }
      catch( System.Exception e )
      {
        RJLog.Error( "Could not load texture", relativePath, relativeFilePath.fullPath );
        RJLog.Error( e );
      }

      return null;
    }


    void ReadEye( JSONObject jsonObject )
    {

    }

    /* EYE */

    public Texture2D GetIrisNormal()
    {
      return GetImageTexture( "Iris Normal" );
    }

    /* SKIN */

    public Texture2D GetMicroNormal()
    {
      return GetImageTexture( "MicroNormal" );
    }

    public Texture2D GetMicroNormalMask()
    {
      return GetImageTexture( "MicroNormalMask" );
    }

    public Texture2D GetSpecularMask()
    {
      return GetImageTexture( "Specular Mask" );
    }

    public Texture2D GetSSSMap()
    {
      return GetImageTexture( "SSS Map" );
    }

    public Texture2D GetTransmisionMap()
    {
      return GetImageTexture( "Transmission Map" );
    }

    /* HAIR */
    
    public Texture2D GetHairRootMap()
    {
      return GetImageTexture( "Hair Root Map" );
    }

    public Texture2D GetHairFlowMap()
    {
      return GetImageTexture( "Hair Flow Map" );
    }

    public Texture2D GetHairIDMap()
    {
      return GetImageTexture( "Hair ID Map" );
    }
  }
}