using System;
using VisimBox.Renderer.RenderObjects;
using VisiMath;
using VisiMath.Geometry;
using VisimBox.Scene;

namespace VisimBox.Renderer
{
    public interface IRenderContext : IDisposable
    {
        #region Settings and values

        /// <summary>
        /// Settings of the context
        /// </summary>
        RenderContextSettings Settings { get; }

        /// <summary>
        /// Main renderer for this context
        /// </summary>
        IRenderer Renderer { get; }

        /// <summary>
        /// Returns current rendering frames per second for this context
        /// </summary>
        int CurrentFPS { get; }

        /// <summary>
        /// Show fps on screen?
        /// </summary>
        bool ShowFPS { get; set; }

        /// <summary>
        /// Returns pointer to the main camera (camera in main viewport)
        /// </summary>
        ICamera MainCamera { get; set; }

        /// <summary>
        /// Currently selected texture
        /// </summary>
        Texture CurrentTexture { get; set; }

        /// <summary>
        /// Rendering flags used for rendering scene
        /// </summary>
        UInt64 RenderFlags { get; set; }


        #endregion

        #region Debug drawing

        Vector3 DebugPoint { get; set; }

        Vector3 DebugLine1 { get; set; }
        Vector3 DebugLine2 { get; set; }

        #endregion



        #region Utilities

        /// <summary>
        /// Creates default camera
        /// </summary>
        /// <returns>New default camera</returns>
        ICamera CreateDefaultCamera();


        /// <summary>
        /// Grabs actual content of the render context and converts it to bitmap
        /// </summary>
        /// <returns>BMP containg current output on the render context</returns>
        System.Drawing.Bitmap GetScreenShot();

        /// <summary>
        /// Saves screenshot with specified name, uses GetScreenShot()
        /// </summary>
        /// <param name="filename">filename to save, if null, creates file ScreenshotDATE-TIME.jpg</param>
        /// <param name="extension">can be set to png, jpg or bmp to override format from the filename (or if filename is specified without extension)</param>
        void SaveScreenShot(string filename = null, string extension = null);

        #endregion


        #region Events
        /// <summary>
        /// Called on the framestart before any rendering / clearing starts
        /// </summary>
        event RendererEvent FrameStart;

        /// <summary>
        /// Called on the end of the frame before showing results of the rendering
        /// </summary>
        event RendererEvent FrameEnd;
        
        #endregion


        #region Rendering Settings

        /// <summary>
        /// Enables / disables fog drawing
        /// </summary>
        bool Fog { get; set; }

        /// <summary>
        /// Color of the fog
        /// </summary>
        ColorByte FogColor { get; set; }

        /// <summary>
        /// Density of the fog
        /// </summary>
        float FogDensity { get; set; }

        #endregion


        #region High level rendering




        /// <summary>
        /// Renders frame in standard way (StartFrame and then EndFrame with associated callbacks)
        /// </summary>
        void RenderFrame();

        /// <summary>
        /// Starts rendering frame
        /// </summary>
        void StartFrame();
        /// <summary>
        /// Finished rendering frame and shows it
        /// </summary>
        void EndFrame();


        /// <summary>
        /// Renders spefified node hierarchy
        /// </summary>
        /// <param name="scene">Nodes to render</param>
        /// <remarks>Hierarchically travels the whole scene - calling OnRender for each visible node implementing IRenderable.
        /// </remarks>
        void RenderNodes(Node scene);

        /// <summary>
        /// Adds render item to the renderer queue
        /// </summary>
        /// <param name="item">Render buffer item</param>
        void AddRenderItem(RenderBufferItem item);

        /// <summary>
        /// Clears rendering queue
        /// </summary>
        void ClearRenderingQueue();

        /// <summary>
        /// Starts rendering queue (allows adding new items to render queue.
        /// If renderer uses multithreading, queue will be rendered as soon as some queue item will be added, except alpha values
        /// </summary>
        void StartRenderingQueue();

        /// <summary>
        /// Finishes rendering queue (renders all remaining items in the queue including sorted alpha items)
        /// </summary>
        void FinishRenderQueue();



        #endregion


        #region Direct Rendering

        /// <summary>
        /// Sets main rendering color (especially for 2d rendering)
        /// </summary>
        /// <param name="col">Color</param>
        void SetColor(ColorByte col);
        /// <summary>
        /// Sets main rendering color (especially for 2d rendering)
        /// </summary>
        /// <param name="col">Color</param>
        void SetColor(ref ColorByte col);
        /// <summary>
        /// Sets main rendering color (especially for 2d rendering)
        /// </summary>
        /// <param name="col">Color</param>
        void SetColor(System.Drawing.Color col);

        /// <summary>
        /// Sets model transformation (without camera transformation)
        /// </summary>
        /// <param name="mat"></param>
        void SetTransformation(ref Matrix4 mat);

        /// <summary>
        /// Sets model transformation (without camera transformation)
        /// </summary>
        /// <param name="mat"></param>
        void SetTransformation(Matrix4 mat);

        /// <summary>
        /// Use to directly change using of the zbuffer
        /// </summary>
        bool ZBufferUsing { get; set; }
        


        #region Immediate mode - don't use /overuse, maybe very slow on some implementations

        /// <summary>
        /// Draws one vertex as a point
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawPoint3D(IVertex point);
        /// <summary>
        /// Draws one vector as a point
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawPoint3D(ref Vector3 vec);
        /// <summary>
        /// Draws one vector as a point
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawPoint3D(Vector3 vec);
        /// <summary>
        /// Draws single line from first to second
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawLine3D(IVertex first, IVertex second);
        /// <summary>
        /// Draws single line from first to second
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawLine3D(ref Vector3 first, ref Vector3 second);
        /// <summary>
        /// Draws single line from first to second
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawLine3D(Vector3 first, Vector3 second);
        /// <summary>
        /// Draws single triangle specified by three vertices
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawTriangle3D(IVertex first, IVertex second, IVertex third);
        /// <summary>
        /// Draws single triangle specified by three vertices
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawTriangle3D(ref Vector3 first, ref Vector3 second, ref Vector3 third);
        /// <summary>
        /// Draws single triangle specified by three vertices
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawTriangle3D(Vector3 first, Vector3 second, Vector3 third);
        /// <summary>
        /// Draws single quad specified by four vertices
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawQuad3D(IVertex first, IVertex second, IVertex third, IVertex fourth);
        /// <summary>
        /// Draws single quad specified by four vertices
        /// </summary>
        void DrawQuad3D(ref Vector3 first, ref Vector3 second, ref Vector3 third, ref Vector3 fourth);
        /// <summary>
        /// Draws single quad specified by four vertices
        /// </summary>
        /// <remarks>This is slow, use only in special circumstances (debug rendering)</remarks>
        void DrawQuad3D(Vector3 first, Vector3 second, Vector3 third, Vector3 fourth);



        #endregion

        #region From system memory - faster, but still slower then vertex buffers

        /// <summary>
        /// Renders points from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderPoints(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders lines from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderLines(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders polyline from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderLine(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders triangles from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderTriangles(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders quads from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderQuads(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders polygon from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderPoly(IVertexArray varray, int startindex = 0, int count = 0);
        /// <summary>
        /// Renders indexed mesh from vertex array.
        /// </summary>
        /// <param name="varray">Vertex array with vertices (should be VertexArray, not VertexList)</param>
        /// <param name="indices">Indices for elements</param>
        /// <param name="type">Type of primitive in indexed mesh (valid are Poins, Lines, Triangles and Quads)</param>
        /// <param name="startindex">First vertice to render</param>
        /// <param name="count">Count of vertices to draw (if zero, all remaining elements from starting index will be drawn</param>
        /// <remarks>Rendering from system memory is (depending on the implementation, applies for openGL)
        /// much faster then direct rendering, but still slower then vertex buffers.</remarks>
        void RenderIndexedMesh(IVertexArray varray, int[] indices, PrimitiveTypes type, int startindex = 0, int count = 0);

        /// <summary>
        /// Renders geometry object - List of points
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(Point3DList geo);
        /// <summary>
        /// Renders geometry object - List of lines
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(LineList geo);
        /// <summary>
        /// Renders geometry object - PolyLine
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(PolyLine geo);
        /// <summary>
        /// Renders geometry object - List of triangles
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(TriangleList geo);
        /// <summary>
        /// Renders geometry object - List of quads
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(QuadList geo);
        /// <summary>
        /// Renders geometry object - generic indexed geometry
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(IndexedGeo geo, int subset = 0);
        /// <summary>
        /// Renders geometry object - Indexed triangle mesh
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(IndexedMesh geo, int subset = 0);
        /// <summary>
        /// Renders geometry object - Indexed quad mesh
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(IndexedQuads geo, int subset = 0);
        /// <summary>
        /// Renders geometry object - Indexed list of points
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(IndexedLines geo, int subset = 0);
        /// <summary>
        /// Renders generic geometry object - uses conversion routines from the object, will be very slow if overused!
        /// </summary>
        /// <param name="geo">Geometry object</param>
        /// <remarks>Renders from the vertexarray, might be much faster then direct rendering, but still slower then using vertex buffers</remarks>
        void RenderGeometry(IGeometry geometry);
       
        #endregion

        #region VertexBuffer rendering


        /// <summary>
        /// Render vertex buffer as specified type of primitive (can't be used for indexed meshes!)
        /// </summary>
        /// <param name="vertices">Vertex buffer</param>
        /// <param name="type">Primitive type</param>
        /// <param name="startindex">starting index</param>
        /// <param name="count">Number of elements</param>
        void RenderVertexBuffer(IVertexBuffer vertices, PrimitiveTypes type, int startindex = 0, int count = 0);

        /// <summary>
        /// Renders indexed mesh from vertex and index buffer
        /// </summary>
        /// <param name="vertices">Vertex buffer</param>
        /// <param name="indices">Index buffer</param>
        /// <param name="type">Primitive type</param>
        /// <param name="startindex">starting index</param>
        /// <param name="count">Number of elements</param>
        void RenderIndexedMesh(IVertexBuffer vertices, int[] indices, PrimitiveTypes type, int startindex = 0, int count = 0);

        /// <summary>
        /// Renders indexed mesh from vertex and index buffer
        /// </summary>
        /// <param name="vertices">Vertex buffer</param>
        /// <param name="indices">Index buffer</param>
        /// <param name="type">Primitive type</param>
        /// <param name="startindex">starting index</param>
        /// <param name="count">Number of elements</param>
        void RenderIndexedMesh(IVertexBuffer vertices, IIndexBuffer indices, PrimitiveTypes type, int startindex = 0, int count = 0);


        #endregion

        #region Special object rendering

        /// <summary>
        /// Draws simple skybox
        /// </summary>
        /// <param name="skybox">Skybox data (note, textures in skybox must be initialized!)</param>
        void DrawSkybox(ref SkyboxData skybox);

        #endregion

        #region 2D rendering

        /// <summary>
        /// Sets renderer to 2d context, all 2d rendering calls should be done after this call!
        /// </summary>
        void Start2DRender();

        /// <summary>
        /// Returns renderer to previous (3d) rendering state from the 2d renderer
        /// </summary>
        void Stop2DRender();


        #region points
        /// <summary>
        /// Draw point in screen coordinates with currently selected color
	    /// </summary>
	    /// <param name="x">X position</param>
	    /// <param name="y">Y position</param>
        void DrawPoint(int x, int y);

	    /// <summary>
        /// Draw point in screen coordinates 
	    /// </summary>
	    /// <param name="x">X position</param>
	    /// <param name="y">Y position</param>
	    /// <param name="Color">Color of the pixel</param>
	    void DrawPoint(int x, int y, ColorByte Color);
        /// <summary>
        /// Draw point in screen coordinates 
        /// </summary>
        /// <param name="x">X position</param>
        /// <param name="y">Y position</param>
        /// <param name="Color">Color of the pixel</param>
        void DrawPoint(int x, int y, System.Drawing.Color Color);

        #endregion

        #region lines
        /// <summary>
        /// Draw line in screen coordinates with currently selected color
        /// </summary>
        /// <param name="x1">x of the start of the line</param>
        /// <param name="y1">y of the start of the line</param>
        /// <param name="x2">X of the end of the line</param>
        /// <param name="y2">y of the end of the line</param>
        void DrawLine(int x1, int y1, int x2, int y2);

	    /// <summary>
        /// Draw line in screen coordinates 
	    /// </summary>
	    /// <param name="x1">x of the start of the line</param>
        /// <param name="y1">y of the start of the line</param>
        /// <param name="x2">X of the end of the line</param>
        /// <param name="y2">y of the end of the line</param>
	    /// <param name="Color">Color of the line</param>
        void DrawLine(int x1, int y1, int x2, int y2, ColorByte Color);
        /// <summary>
        /// Draw line in screen coordinates 
        /// </summary>
        /// <param name="x1">x of the start of the line</param>
        /// <param name="y1">y of the start of the line</param>
        /// <param name="x2">X of the end of the line</param>
        /// <param name="y2">y of the end of the line</param>
        /// <param name="Color">Color of the line</param>
        void DrawLine(int x1, int y1, int x2, int y2, System.Drawing.Color Color);

        #endregion

        #region Rectangles

        /// <summary>
        /// Draws outlined 2d rectangle with x1 and y1 coordinates of top left and width and height, using current color
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        void DrawRectangle(int x1, int y1, int width, int height);
        /// <summary>
        /// Draws outlined 2d rectangle with x1 and y1 coordinates of top left and width and height
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="color">Color of the outline</param>
        void DrawRectangle(int x1, int y1, int width, int height, ColorByte color);
        /// <summary>
        /// Draws outlined 2d rectangle with x1 and y1 coordinates of top left and width and height
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="color">Color of the outline</param>
        void DrawRectangle(int x1, int y1, int width, int height, System.Drawing.Color color);

        /// <summary>
        /// Draws outlined 2d rectangle with current color
        /// </summary>
        /// <param name="rect">Rectangle</param>
        void DrawRectangle(System.Drawing.Rectangle rect);
        
        /// <summary>
        /// Draws outlined 2d rectangle
        /// </summary>
        /// <param name="Color">Color of the outline</param>
        /// <param name="rect">Rectangle</param>
        void DrawRectangle(System.Drawing.Rectangle rect, ColorByte Color);

        /// <summary>
        /// Draws outlined 2d rectangle
        /// </summary>
        /// <param name="Color">Color of the outline</param>
        /// <param name="rect">Rectangle</param>
        void DrawRectangle(System.Drawing.Rectangle rect, System.Drawing.Color Color);


        /// <summary>
        /// Draws filled 2d rectangle with x1 and y1 coordinates of top left and width and height, using current color
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        void DrawFilledRectangle(int x1, int y1, int width, int height);
        /// <summary>
        /// Draws filled 2d rectangle with x1 and y1 coordinates of top left and width and height
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="color">Color of the outline</param>
        void DrawFilledRectangle(int x1, int y1, int width, int height, ColorByte color);
        /// <summary>
        /// Draws filled 2d rectangle with x1 and y1 coordinates of top left and width and height
        /// </summary>
        /// <param name="x1">left upper corner</param>
        /// <param name="y1">left upper corner</param>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="color">Color of the outline</param>
        void DrawFilledRectangle(int x1, int y1, int width, int height, System.Drawing.Color color);

        /// <summary>
        /// Draws filled 2d rectangle with current color
        /// </summary>
        /// <param name="rect">Rectangle</param>
        void DrawFilledRectangle(System.Drawing.Rectangle rect);

        /// <summary>
        /// Draws filled 2d rectangle
        /// </summary>
        /// <param name="Color">Color of the outline</param>
        /// <param name="rect">Rectangle</param>
        void DrawFilledRectangle(System.Drawing.Rectangle rect, ColorByte Color);

        /// <summary>
        /// Draws filled 2d rectangle
        /// </summary>
        /// <param name="Color">Color of the outline</param>
        /// <param name="rect">Rectangle</param>
        void DrawFilledRectangle(System.Drawing.Rectangle rect, System.Drawing.Color Color);


        #endregion


        #region Text rendering

        /// <summary>
        /// Changes current font of the context to specified font (from font manager)
        /// </summary>
        /// <param name="fontname">Name of the font in the font manager</param>
        void ChangeFont(string fontname);
        /// <summary>
        /// Changes current font of the context to the font
        /// </summary>
        /// <param name="font">Rendering font</param>
        void ChangeFont(Render2D.Font font);

        /// <summary>
        /// Simple text drawing on selected coordinate. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="text">text </param>
        void DrawText(int x, int y, string text);

        /// <summary>
        /// Simple text drawing on selected coordinate. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(int x, int y, string text, ColorByte color);

        /// <summary>
        /// Simple text drawing on selected coordinate. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(int x, int y, string text, System.Drawing.Color color);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="maxheight">Maximal height of the text block</param>
        /// <param name="maxwidth">Maximal width of the text block</param>
        /// <param name="text">text </param>
        void DrawText(int x, int y, int maxwidth, int maxheight, string text);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="maxheight">Maximal height of the text block</param>
        /// <param name="maxwidth">Maximal width of the text block</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(int x, int y, int maxwidth, int maxheight, string text, ColorByte color);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="x">X coordinate</param>
        /// <param name="y">Y coordinate</param>
        /// <param name="maxheight">Maximal height of the text block</param>
        /// <param name="maxwidth">Maximal width of the text block</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(int x, int y, int maxwidth, int maxheight, string text, System.Drawing.Color color);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="rect">Rectangle to write text to</param>
        /// <param name="text">text </param>
        void DrawText(System.Drawing.Rectangle rect, string text);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="rect">Rectangle to write text to</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(System.Drawing.Rectangle rect, string text, ColorByte color);

        /// <summary>
        /// Draw text on selected coordinate with specified max size of the text block. Uses currently selected font
        /// </summary>
        /// <param name="rect">Rectangle to write text to</param>
        /// <param name="text">text </param>
        /// <param name="color">Color of the text</param>
        void DrawText(System.Drawing.Rectangle rect, string text, System.Drawing.Color color);


        #endregion


        #region Images and sprites

        /// <summary>
        /// Draws currently selected texture in real size to specified place on screen.
        /// NOTE - uses current color, don't forget to set it to white unless you want colored image
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        void DrawImage(int x, int y);
        /// <summary>
        /// Draws selected texture in real size to specified place on screen.
        /// NOTE - uses current color, don't forget to set it to white unless you want colored image
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>        
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImage(int x, int y, string texture);
        /// <summary>
        /// Draws selected texture in real size to specified place on screen.
        /// NOTE - uses current color, don't forget to set it to white unless you want colored image
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImage(int x, int y, Texture tex);

        /// <summary>
        /// Draws currently selected texture scaled to specified width and height
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        void DrawImage(int x, int y, int width, int height);
        /// <summary>
        /// Draws selected texture scaled to specified width and height
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImage(int x, int y, int width, int height, string texture);
        /// <summary>
        /// Draws selected texture scaled to specified width and height
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImage(int x, int y, int width, int height, Texture tex);


        /// <summary>
        /// Draws currently selected texture scaled to specified rectangle
        /// </summary>
        /// <param name="rect">Rectangle on screen</param>
        void DrawImage(System.Drawing.Rectangle rect);
        /// <summary>
        /// Draws currently selected texture scaled to specified rectangle
        /// </summary>
        /// <param name="rect">Rectangle on screen</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImage(System.Drawing.Rectangle rect, string texture);
        /// <summary>
        /// Draws currently selected texture scaled to specified rectangle
        /// </summary>
        /// <param name="rect">Rectangle on screen</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImage(System.Drawing.Rectangle rect, Texture tex);

        /// <summary>
        /// Draws unscaled part of the currently selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        void DrawImagePart(int x, int y, int sourcex, int sourcey, int sourcewidth, int sourceheight);

        /// <summary>
        /// Draws unscaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImagePart(int x, int y, int sourcex, int sourcey, int sourcewidth, int sourceheight, string texture);

        /// <summary>
        /// Draws unscaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImagePart(int x, int y, int sourcex, int sourcey, int sourcewidth, int sourceheight, Texture tex);

        /// <summary>
        /// Draws unscaled part of the currently selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="source">Source rectangle in the texture</param>
        void DrawImagePart(int x, int y, System.Drawing.Rectangle source);

        /// <summary>
        /// Draws unscaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="source">Source rectangle in the texture</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImagePart(int x, int y, System.Drawing.Rectangle source, string texture);

        /// <summary>
        /// Draws unscaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="source">Source rectangle in the texture</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImagePart(int x, int y, System.Drawing.Rectangle source, Texture tex);

        /// <summary>
        /// Draws scaled part of the currently selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        void DrawImagePart(int x, int y, int width, int height, int sourcex, int sourcey, int sourcewidth, int sourceheight);

        /// <summary>
        /// Draws scaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImagePart(int x, int y, int width, int height, int sourcex, int sourcey, int sourcewidth, int sourceheight, string texture);

        /// <summary>
        /// Draws scaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="x">X coordinate of top left corner</param>
        /// <param name="y">Y coordinate of top left corner</param>
        /// <param name="width">Width of the drawn image</param>
        /// <param name="height">Height of the drawn image</param>
        /// <param name="sourcex">X coordinate of top left corner inside the texture</param>
        /// <param name="sourcey">Y coordinate of top left corner inside the texture</param>
        /// <param name="sourcewidth">Width of the texture part</param>
        /// <param name="sourceheight">Height of the texture part</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImagePart(int x, int y, int width, int height, int sourcex, int sourcey, int sourcewidth, int sourceheight, Texture tex);
        

        /// <summary>
        /// Draws scaled part of the currently selected texture on the screen.
        /// </summary>
        /// <param name="target">Target rectangle on the screen</param>
        /// <param name="source">Source rectangle in the texture</param>
        void DrawImagePart(System.Drawing.Rectangle target, System.Drawing.Rectangle source);

        /// <summary>
        /// Draws scaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="target">Target rectangle on the screen</param>
        /// <param name="source">Source rectangle in the texture</param>
        /// <param name="texture">Name of the texture in the texture manager</param>
        void DrawImagePart(System.Drawing.Rectangle target, System.Drawing.Rectangle source, string texture);

        /// <summary>
        /// Draws scaled part of the selected texture on the screen.
        /// </summary>
        /// <param name="target">Target rectangle on the screen</param>
        /// <param name="source">Source rectangle in the texture</param>
        /// <param name="tex">Texture to be set</param>
        void DrawImagePart(System.Drawing.Rectangle target, System.Drawing.Rectangle source, Texture tex);


        /// <summary>
        /// Draws sprite with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprite">Sprite information</param>
        void DrawSprite(int x, int y, Render2D.SpriteInfo sprite);
        /// <summary>
        /// Draws sprite with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprite">Sprite information</param>
        void DrawSprite(int x, int y, ref Render2D.SpriteInfo sprite);
        /// <summary>
        /// Draws sprite with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="texture">Texture name</param>
        /// <param name="sprite">Sprite information</param>
        void DrawSprite(int x, int y, Render2D.SpriteInfo sprite, string texture);
        /// <summary>
        /// Draws sprite with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="tex">Texture to be set</param>
        /// <param name="sprite">Sprite information</param>
        void DrawSprite(int x, int y, Render2D.SpriteInfo sprite, Texture tex);
        /// <summary>
        /// Draws array of sprites with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprites">Sprite information</param>
        void DrawSprites(int x, int y, Render2D.SpriteInfo[] sprites);
        /// <summary>
        /// Draws array of sprites with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprites">Sprite information</param>
        /// <param name="texture">Texture name</param>
        void DrawSprites(int x, int y, Render2D.SpriteInfo[] sprites, string texture);
        /// <summary>
        /// Draws array of sprites with currently selected texture
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="tex">Texture to be set</param>
        /// <param name="sprites">Sprite information</param>
        void DrawSprites(int x, int y, Render2D.SpriteInfo[] sprites, Texture tex);

        /// <summary>
        /// Draws batch of sprites
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprites">SpriteBatch (should contain valid texture!)</param>
        void DrawSprites(int x, int y, Render2D.SpriteBatch sprites);
        /// <summary>
        /// Draws batch of sprites
        /// </summary>
        /// <param name="x">X position (screen coords) for the sprite</param>
        /// <param name="y">Y position (screen coords) for the sprite</param>
        /// <param name="sprites">SpriteBatch (should contain valid texture!)</param>
        void DrawSprites(int x, int y, ref Render2D.SpriteBatch sprites);



        #endregion


        #endregion


        #endregion

    }
}
