/// <summary>
/// Shader Control - (C) Copyright 2016-2022 Ramiro Oliva (Kronnect)
/// </summary>
/// 
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Text;

namespace ShaderControl {

    public partial class SCWindow : EditorWindow {

        const string JSON_NODE_DATA = "JSONnodeData";
        const string JSON_KEYWORD_SCOPE = "m_KeywordScope";

        [Serializable]
        public struct SerializedKeywordData {
            public string typeInfo;
            public string JSONnodeData;
        }

        [Serializable]
        public struct SerializedKeywordProxy {
            public string m_Name;
            public string m_DefaultReferenceName;
            public int m_KeywordScope;
            public int m_KeywordDefinition;
        }

        [Serializable]
        public struct ShaderGraphProxy {
            public SerializedKeywordData[] m_SerializedKeywords;
        }


        void ScanShaderGraphV1(SCShader shader, string shaderContents) { 

            shaderContents = shaderContents.Replace("UnityEditor.ShaderGraph.ShaderKeyword", "ShaderControl.SCWindow.SerializedKeyword");
            ShaderGraphProxy graph = JsonUtility.FromJson<ShaderGraphProxy>(shaderContents);
            
            SCShaderPass currentPass = new SCShaderPass();
            if (graph.m_SerializedKeywords != null) {
                for (int k = 0; k < graph.m_SerializedKeywords.Length; k++) {

                    SerializedKeywordData skw = graph.m_SerializedKeywords[k];
                    if (string.IsNullOrEmpty(skw.JSONnodeData)) continue;

                    SerializedKeywordProxy kw = JsonUtility.FromJson<SerializedKeywordProxy>(skw.JSONnodeData);

                    PragmaType pragmaType = PragmaType.Unknown;
                    if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_MULTI_COMPILE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_GLOBAL) {
                        pragmaType = PragmaType.MultiCompileGlobal;
                    } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_MULTI_COMPILE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_LOCAL) {
                        pragmaType = PragmaType.MultiCompileLocal;
                    } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_SHADER_FEATURE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_GLOBAL) {
                        pragmaType = PragmaType.FeatureGlobal;
                    } else if (kw.m_KeywordDefinition == SHADER_GRAPH_KEYWORD_DEFINITION_SHADER_FEATURE && kw.m_KeywordScope == SHADER_GRAPH_KEYWORD_SCOPE_LOCAL) {
                        pragmaType = PragmaType.FeatureLocal;
                    }

                    SCKeywordLine keywordLine = new SCKeywordLine();
                    keywordLine.pragmaType = pragmaType;

                    SCKeyword keyword = new SCKeyword(kw.m_DefaultReferenceName, kw.m_Name);
                    keywordLine.Add(keyword);
                    currentPass.Add(keywordLine);
                }
            }
            shader.Add(currentPass);
            shader.UpdateVariantCount();
        }

        void ConvertToLocalGraphV1(SCKeyword keyword, SCShader shader) {
            string contents = File.ReadAllText(shader.path, Encoding.UTF8);
            int i = contents.IndexOf("m_SerializedKeywords");
            if (i < 0) return;
            int j = contents.IndexOf("m_SerializedNodes");
            if (j < 0) j = contents.Length - 1;

            int pos = contents.IndexOf(keyword.name, i);
            bool changed = false;
            if (pos > i && pos < j) {
                int dataBlockPos = contents.LastIndexOf(JSON_NODE_DATA, pos);
                if (dataBlockPos > 0) {
                    int scopePos = contents.IndexOf(JSON_KEYWORD_SCOPE, dataBlockPos);
                    if (scopePos > dataBlockPos && scopePos < j) {
                        scopePos += JSON_KEYWORD_SCOPE.Length + 2;
                        int valuePos = contents.IndexOf("1", scopePos);
                        int safetyPos = contents.IndexOf("\"", scopePos);
                        if (valuePos > scopePos && valuePos < safetyPos && safetyPos > valuePos) {
                            contents = contents.Substring(0, valuePos) + "0" + contents.Substring(valuePos + 1);
                            changed = true;
                        }

                    }
                }
            }
            if (changed) {
                MakeBackup(shader);
                File.WriteAllText(shader.path, contents, Encoding.UTF8);
            }
        }


    }
}