using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VisiMath;

namespace VisimBox.Renderer
{
    /// <summary>
    /// class containing info for render context settings and for it's initialization
    /// </summary>
    public class RenderContextSettings
    {
        IRenderWindow irw;
        int bpp;
        bool useZ;
        int zBits;
        ColorByte backcol;
        
        ///<summary> 
        ///If set to null, renderer will create it's own standard window. 
        ///Otherwise rendering context will be created from the embedded RenderWindow
        ///</summary>
        public IRenderWindow Window { get { return irw; } }
        ///<summary> Title of the window (if renderer creates it's own window) </summary>
        public string WindowTitle { get; set; }

        ///<summary> Run in fullscreen? </summary>
        public bool FullScreen { get; set; }
        ///<summary> Can be window switched between fullscreen and windowed mode? </summary>
        public bool FullScreenSwitch {get; set;}
        ///<summary> Will be window resizable?</summary>
        public bool Resizable { get; set; }
        /// <summary> If set to true window will keep aspect ratio when resizing </summary>
        public bool KeepAspectRatio { get; set; }

        ///<summary> Width of the renderer window in pixels. Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows.</summary>
        public int Width {get; set;}
        ///<summary> Height of the renderer window in pixels. Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows. </summary>
        public int Height { get; set; }
        ///<summary> Bits per pixel (color depth) for fullscreen modes, 0 means use desktop settings or default value </summary>
        public int BPP { get { return bpp; } }
        /// <summary> Use zbuffer? False value has meaning only for special 2d windows </summary>
        public bool UseZbuffer { get { return useZ; } }
        /// <summary> Number of the zbuffer bits (0, 16, 32), zero means default </summary>
        public int ZbufferBits { get { return zBits; } }

        /// <summary>
        /// Background color of the rendercontext
        /// </summary>
        public ColorByte BackgroundColor { get { return backcol; } set { backcol = value; } }

        /// <summary>
        /// If set to true, background will be cleared on start of every frame
        /// Setting to false when always rendering over the whole screen (complete scenes) has some small performance gain
        /// </summary>
        public bool ClearBackground {get; set;}


        ///<summary> Minimal width of the renderer window in pixels (for resizable windows). If set to zero, any value is possible. 
        ///Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows.</summary>
        public int MinWidth {get; set;}
        ///<summary> Maximal width of the renderer window in pixels (for resizable windows). If set to zero, any value is possible. 
        ///Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows.</summary>
        public int MaxWidth { get; set; }
        ///<summary> Minimal height of the renderer window in pixels (for resizable windows). If set to zero, any value is possible.
        ///Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows.</summary>
        public int MinHeight {get; set;}
        ///<summary> Maximal height of the renderer window in pixels (for resizable windows). If set to zero, any value is possible.
        ///Valid only for automatically created windows, use VISIMBOXcontrol properties for embeded windows.</summary>
        public int MaxHeight { get; set; }


        public RenderContextSettings()
        {
            irw = null;
            bpp = 0;
            useZ = true;
            zBits = 0;

            WindowTitle = "VISIMBOX Render Window";
            FullScreen = false;
            FullScreenSwitch = true;
            Resizable = true;
            KeepAspectRatio = false;
            Width = 640;
            Height = 480;
            MinWidth = 0;
            MinHeight = 0;
            MaxWidth = 0;
            MaxHeight = 0;
            BackgroundColor = ColorByte.Black;
            ClearBackground = true;
        }

        /// <summary>
        /// Creates default rendering context
        /// </summary>
        /// <param name="height">Requested width (0 to use default)</param>
        /// <param name="width">Requested height (0 to use default)</param>
        public RenderContextSettings(int width, int height) : this()
        {
            if (width == 0)
                width = 640;
            if (height == 0)
                height = 480;
            Width = width;
            Height = height;
        }

        public RenderContextSettings(IRenderWindow win) : this()
        {
            irw = win;
            bpp = 0;
            useZ = true;
            zBits = 0;

            BackgroundColor = ColorByte.Black;
            ClearBackground = true;
            WindowTitle = "";
            FullScreen = false;
            FullScreenSwitch = true;
            Resizable = true;
            KeepAspectRatio = false;
            var size = win.ClientRectangle;
            Width = win.Width;
            Height = win.Height;
            MinWidth = 0;
            MinHeight = 0;
            MaxWidth = 0;
            MaxHeight = 0;
        }

        /// <summary>
        /// used by renderer, don't touch this!
        /// </summary>
        /// <param name="irw"></param>
        public void SetIRW(IRenderWindow newwin)
        {
            irw = newwin;
        }

    }

    /// <summary>
    /// Enums for the type of the shading (no shading at all, flat shading same for the surface, per vertex shading and per pixel lighting are possible
    /// </summary>
    public enum ShadingType { No, Flat, PerVertex, PerPixel };

    /// <summary>
    /// Enums for quality setting of the textures - no textures, only basic diffuse map, standard materials, all types of texturing
    /// </summary>
    public enum TexturingType { No, Basic, Advanced, Full };

    /// <summary>
    /// Enums for quality setting of rendering materials, full is used for super quality materials
    /// </summary>
    public enum MaterialQuality { No, Basic, Advanced, Full };

    /// <summary>
    /// Viewport settings - type of view which shall be used to render viewport (wireframe/surfaces, no lightning etc...)
    /// </summary>
    public class ViewQuality
    {
        ///<summary> Show only wireframe?</summary>
        public bool WireFrame = false;
        ///<summary> Use colors for materials? If false, everything will be rendered with white on black background.</summary>
        public bool Colored = true;

        /// <summary>
        /// Show outlines of the objects (edges)
        /// </summary>
        public bool ShowOutlines = false;

        ///<summary> Type of shading to use.</summary>
        public ShadingType Shading = ShadingType.PerVertex;
        ///<summary> Type of texturing.</summary>
        public TexturingType Texturing = TexturingType.Advanced;
        public MaterialQuality Materials = MaterialQuality.Advanced;

        ///<summary> Shadows quality for dynamicaly cast shadows. Valid values are from 0-1. NOTE: UNUSED!!!</summary>
        public float Shadows;
        /// <summary> Maximal visibility (clip all objects in the distance), if 0 - no limit. NOTE!!! no limit = 10000 </summary>
        public float Visibility;
    }


}
