using ComponentFramework.Modules;
using ComponentFramework;

namespace OctreeRendering
{
    class SampleState : Service, ISampleState
    {
        public SampleState(ICore core) : base(core) { }

        readonly Eventful<CullingMode> octreeCullingMode = new Eventful<CullingMode>();
        public Eventful<CullingMode> OctreeCullingMode
        {
            get { return octreeCullingMode; }
            set { octreeCullingMode.Set(value); }
        }

        readonly Eventful<int> occlusionSurfaceFactor = new Eventful<int>();
        public Eventful<int> OcclusionSurfaceFactor
        {
            get { return occlusionSurfaceFactor; }
            set { occlusionSurfaceFactor.Set(value); }
        }

        readonly Eventful<int> octreeTraversalCoarseness = new Eventful<int>();
        public Eventful<int> OctreeTraversalCoarseness
        {
            get { return octreeTraversalCoarseness; }
            set { octreeTraversalCoarseness.Set(value); }
        }

        public bool ShowConsole { get; set; }

        public bool UseSynchronousQueries { get; set; }

        public override void Initialize()
        {
            ShowConsole = true;

            OctreeCullingMode = CullingMode.FurstumAndOcclusion;
            OctreeTraversalCoarseness = 3;

            UseSynchronousQueries = true;

            OcclusionSurfaceFactor = 2;
        }
    }

    interface ISampleState : IService
    {
        Eventful<CullingMode> OctreeCullingMode { get; set; }
        Eventful<int> OctreeTraversalCoarseness { get; set; }

        Eventful<int> OcclusionSurfaceFactor { get; set; }

        bool UseSynchronousQueries { get; set; }
        bool ShowConsole { get; set; }
    }

    enum CullingMode
    {
        None,
        FrustumBoxIntersection,
        HardwareOcclusionQueries,
        FurstumAndOcclusion
    }

    static class CullingModeExtensions
    {
        public static bool UsesOcclusionQueries(this CullingMode cullMode)
        {
            return cullMode == CullingMode.FurstumAndOcclusion || cullMode == CullingMode.HardwareOcclusionQueries;
        }
    }
}
