using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace Ika.Graphics
{
    /// <summary>
    /// Represents a point light
    /// </summary>
    public class PointLight : Light
    {
        Vector3 m_lightPosition;
        /// <summary>
        /// Gets the light position
        /// </summary>
        public Vector3 LightPosition
        {
            get { return m_lightPosition; }
            set { m_lightPosition = value; }
        }

        float m_lightRadius;
        /// <summary>
        /// Gets the light radius
        /// </summary>
        public float LightRadius
        {
            get { return m_lightRadius; }
            set { m_lightRadius = value; ComputeEffectiveRadius(); }
        }

        float m_lightExponent;
        /// <summary>
        /// Gets the light fall off exponent
        /// </summary>
        public float LightExponent
        {
            get { return m_lightExponent; }
            set { m_lightExponent = value; ComputeEffectiveRadius(); }
        }

        float m_lightFallOffRadius;
        /// <summary>
        /// Gets the radius where the light start to attenuate
        /// </summary>
        public float LightFallOffRadius
        {
            get { return m_lightFallOffRadius; }
            set { m_lightFallOffRadius = value; ComputeEffectiveRadius(); }
        }

        float m_cutOutThreshold = 0.0f;
        /// <summary>
        /// The attenuation factor at wich the light is considered as null
        /// 0 is the full light, and 1 imitate infinite LightExponent.
        /// It reduces the light radius in order to eliminate the pixels with strong attenuation
        /// </summary>
        public float CutOutThreshold
        {
            get { return m_cutOutThreshold; }
            set { m_cutOutThreshold = value; ComputeEffectiveRadius(); }
        }

        float m_effectiveRadius;
        /// <summary>
        /// The effective radius of the light, based on the CutOutThreshold.
        /// </summary>
        public float EffectiveRadius
        {
            get { return m_effectiveRadius; }
        }

        protected void ComputeEffectiveRadius()
        {
            //Reduce the light radius in order to eliminate the pixels with strong attenuation
            //based on cutOutThreshold. 
            float cutOutFactor = 1 - (float)Math.Pow(m_cutOutThreshold, 1 / LightExponent);

            //The computed new radius, between LightRadius and LightFallOffRadius
            float fallOffRange = LightRadius - LightFallOffRadius;
            m_effectiveRadius = LightFallOffRadius + fallOffRange * cutOutFactor;
        }
    }
}
