/// <summary>
        /// Broadcast a normal texture switch
        /// </summary>
        /// <param name="profile">Selected profile - null means all CTS terrains</param>
        /// <param name="texture">New texture</param>
        /// <param name="textureIdx">Index</param>
        /// <param name="tiling">Tiling</param>
        public void BroadcastNormalTextureSwitch(CTSProfile profile, Texture2D texture, int textureIdx, float tiling)
        {
            //Make sure shaders are registered
            RegisterAllShaders(true);

            //Do the texture switch
            CompleteTerrainShader shader = null;

            for (int idx = 0; idx < m_shaderList.Count; idx++)
            {
                shader = m_shaderList[idx];
                if (shader != null && shader.Profile != null)
                {
                    if (profile == null)
                    {
                        shader.ReplaceNormalInTerrain(texture, textureIdx, tiling);
                    }
                    else
                    {
                        if (shader.Profile.GetInstanceID() == profile.GetInstanceID())
                        {
                            shader.ReplaceNormalInTerrain(texture, textureIdx, tiling);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Broadcast a profile update to all the shaders using it in the scene
        /// </summary>
        /// <param name="profile">Profile being updated</param>
        public void BroadcastProfileUpdate(CTSProfile profile)
        {
            //Make sure shaders are registered
            RegisterAllShaders();

            //Also make sure weather is registered
            RegisterAllControllers();

            //Can not do this on a null profile
            if (profile == null)
            {
                Debug.LogWarning("Cannot update shader on null profile.");
                return;
            }

            //Broadcast the update
            CompleteTerrainShader shader = null;

            for (int idx = 0; idx < m_shaderList.Count; idx++)
            {
                shader = m_shaderList[idx];
                if (shader != null && shader.Profile != null)
                {
                    if (shader.Profile.GetInstanceID() == profile.GetInstanceID())
                    {
                        shader.UpdateMaterialAndShader();
                    }
                }
            }
        }
        /// <summary>
        /// Return true if the profile is actively assigned to a terrain
        /// </summary>
        /// <param name="profile">The profile being checked</param>
        /// <returns>True if its been assiged to a terrain</returns>
        public bool ProfileIsActive(CTSProfile profile)
        {
            //Return rubbish if we have no usage
            if (profile == null)
            {
                return(false);
            }

            //Make sure shaders are registered
            RegisterAllShaders();

            CompleteTerrainShader shader = null;

            for (int idx = 0; idx < m_shaderList.Count; idx++)
            {
                shader = m_shaderList[idx];
                if (shader != null && shader.Profile != null)
                {
                    if (shader.Profile.GetInstanceID() == profile.GetInstanceID())
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Broadcast a shader setup on the selected profile in the scene, otherwise all
        /// </summary>
        /// <param name="profile">Profile being updated, otherwise all</param>
        public void BroadcastShaderSetup(CTSProfile profile)
        {
            //Make sure shaders are registered
            RegisterAllShaders(true);

            //First - check to see if we have one on the currently selected terrain - this will usually be where texture changes have been made
            CompleteTerrainShader shader = null;

            if (Terrain.activeTerrain != null)
            {
                shader = Terrain.activeTerrain.GetComponent <CompleteTerrainShader>();
                if (shader != null && shader.Profile != null)
                {
                    if (shader.Profile.GetInstanceID() == profile.GetInstanceID())
                    {
                        shader.UpdateProfileFromTerrainForced();
                        BroadcastProfileUpdate(profile);
                        return;
                    }
                }
            }

            //Otherwise broadcast the setup
            for (int idx = 0; idx < m_shaderList.Count; idx++)
            {
                shader = m_shaderList[idx];
                if (shader != null && shader.Profile != null)
                {
                    if (profile == null)
                    {
                        shader.UpdateProfileFromTerrainForced();
                    }
                    else
                    {
                        //Find the first match and update it
                        if (shader.Profile.GetInstanceID() == profile.GetInstanceID())
                        {
                            shader.UpdateProfileFromTerrainForced();
                            BroadcastProfileUpdate(profile);
                            return;
                        }
                    }
                }
            }
        }