/// ////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Called at the Onstart() and override it. <see cref="TRR_Reflection"/>
        /// And do the reflection stuff
        /// </summary>
        /// <param name="state"></param>
        /// ////////////////////////////////////////////////////////////////////////////////////////
        public override void OnStart(StartState state)
        {
            //Util.log("++++ 'OnStart()' ++++");

            Reflections reflections = Reflections.instance;

            Shader reflectiveShader = shader.Length == 0 ? null : TextureReplacerReplaced.GetShader(shader);
            Color  reflectionColour = new Color(0.5f, 0.5f, 0.5f);
            int    updateInterval   = 1;

            Util.parse(ReflectionColor, ref reflectionColour);
            Util.parse(colour, ref reflectionColour);
            Util.parse(interval, ref updateInterval);

            updateInterval = Math.Max(updateInterval, 1);

            List <string> meshNames = Util.splitConfigValue(meshes).ToList();

            if (MeshesToChange != "all")
            {
                meshNames.AddUniqueRange(Util.splitConfigValue(MeshesToChange));
            }

            if (reflections.reflectionType == Reflections.Type.NONE)
            {
                return;
            }
            if (reflections.reflectionType == Reflections.Type.REAL)
            {
                script = new Reflections.Script(part, updateInterval, reflectionColour);
            }

            if (reflections.logReflectiveMeshes)
            {
                Util.log("Part \"{0}\"", part.name);
            }

            bool success = false;

            foreach (MeshFilter meshFilter in part.FindModelComponents <MeshFilter>())
            {
                if (meshFilter.GetComponent <Renderer>() == null)
                {
                    continue;
                }

                Material material = meshFilter.GetComponent <Renderer>().material;

                if (reflections.logReflectiveMeshes)
                {
                    Util.log("+ {0} [{1}]", meshFilter.name, material.shader.name);
                }

                if (meshNames.Count == 0 || meshNames.Contains(meshFilter.name))
                {
                    success |= script == null?
                               reflections.applyStatic(material, reflectiveShader, reflectionColour) :
                                   script.apply(material, reflectiveShader, reflectionColour);
                }
            }

            if (!success)
            {
                if (script != null)
                {
                    script.destroy();
                    script = null;
                }

                Util.log("Failed to replace any shader on \"{0}\" with its reflective counterpart", part.name);
            }
        }
        /// ////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Post-load initialisation.
        /// called after the awake() of KSP
        /// </summary>
        /// ////////////////////////////////////////////////////////////////////////////////////////
        public void load()
        {
            Util.log("++++ 'load()' ++++");

            Texture2D[] envMapFaces = new Texture2D[6];

            // Foreach non-null Texture2D in any of the EnvMap Folders
            foreach (KeyValuePair <Texture2D, string> EnvMapTexture in Textures_Loader.ENVMAP())
            {
                Texture2D texture      = EnvMapTexture.Key;
                string    originalName = EnvMapTexture.Value;

                switch (originalName)
                {
                case "PositiveX":
                    envMapFaces[0] = texture;
                    break;

                case "NegativeX":
                    envMapFaces[1] = texture;
                    break;

                case "PositiveY":
                    envMapFaces[2] = texture;
                    break;

                case "NegativeY":
                    envMapFaces[3] = texture;
                    break;

                case "PositiveZ":
                    envMapFaces[4] = texture;
                    break;

                case "NegativeZ":
                    envMapFaces[5] = texture;
                    break;

                default:
                    Util.log("Invalid enironment map texture name {0}", texture.name);
                    break;
                }
            }

            // Generate generic reflection cube map texture.
            if (envMapFaces.Contains(null))
            {
                Util.log("Some environment map faces are missing. Static reflections disabled.");
            }
            else
            {
                int envMapSize = envMapFaces[0].width;

                if (envMapFaces.Any(t => t.width != envMapSize || t.height != envMapSize) ||
                    envMapFaces.Any(t => !Util.isPow2(t.width) || !Util.isPow2(t.height)))
                {
                    Util.log("Invalid environment map faces. Static reflections disabled.");
                }
                else
                {
                    try
                    {
                        staticEnvMap           = new Cubemap(envMapSize, TextureFormat.RGB24, true);
                        staticEnvMap.hideFlags = HideFlags.HideAndDontSave;
                        staticEnvMap.wrapMode  = TextureWrapMode.Clamp;
                        staticEnvMap.SetPixels(envMapFaces[0].GetPixels(), CubemapFace.PositiveX);
                        staticEnvMap.SetPixels(envMapFaces[1].GetPixels(), CubemapFace.NegativeX);
                        staticEnvMap.SetPixels(envMapFaces[2].GetPixels(), CubemapFace.PositiveY);
                        staticEnvMap.SetPixels(envMapFaces[3].GetPixels(), CubemapFace.NegativeY);
                        staticEnvMap.SetPixels(envMapFaces[4].GetPixels(), CubemapFace.PositiveZ);
                        staticEnvMap.SetPixels(envMapFaces[5].GetPixels(), CubemapFace.NegativeZ);
                        staticEnvMap.Apply(true, false);

                        Util.log("Static environment map cube texture generated.");
                    }
                    catch (UnityException)
                    {
                        if (staticEnvMap != null)
                        {
                            Object.DestroyImmediate(staticEnvMap);
                        }

                        staticEnvMap = null;

                        Util.log("Failed to set up static reflections. Textures not readable?");
                    }
                }
            }

            // we now save the visor shader in the placeholder. The shader got loaded through the ksp asset bundle
            visorShader = TextureReplacerReplaced.GetShader("KSP/TR/Visor");

            // fill the shaderMappings dict, if we find the right shader from the mapping config.
            // we could have used names here, but it is not in the fast path, so it is ok to leave it this way
            foreach (string origShaderName in shaderMappingConfig.Keys)
            {
                Shader original   = TextureReplacerReplaced.GetShader(origShaderName);
                Shader reflective = TextureReplacerReplaced.GetShader(shaderMappingConfig[origShaderName]);

                if (original == null || original.name == "Hidden/InternalErrorShader")
                {
                    Util.log("Shader \"{0}\" missing", origShaderName);
                }
                else if (reflective == null || reflective.name == "Hidden/InternalErrorShader")
                {
                    Util.log("Shader \"{0}\" missing", shaderMappingConfig[origShaderName]);
                }
                else
                {
                    shaderMappings[original] = reflective;
                }
            }

            setReflectionType(reflectionType);
        }