// Copyright (c) 2016-2019 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#pragma once
#include <kiwano/render/RenderContext.h>
#include <kiwano/render/DirectX/TextRenderer.h>

namespace kiwano
{
namespace graphics
{
namespace directx
{
KGE_DECLARE_SMART_PTR(RenderContextImpl);

class KGE_API RenderContextImpl : public RenderContext
{
public:
    RenderContextImpl();

    virtual ~RenderContextImpl();

    HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1DeviceContext> ctx);

    void BeginDraw() override;

    void EndDraw() override;

    void CreateTexture(Texture& texture, const PixelSize& size) override;

    void DrawTexture(const Texture& texture, const Rect* src_rect, const Rect* dest_rect) override;

    void DrawTextLayout(const TextLayout& layout, const Point& offset, BrushPtr outline_brush) override;

    void DrawShape(const Shape& shape) override;

    void DrawLine(const Point& point1, const Point& point2) override;

    void DrawRectangle(const Rect& rect) override;

    void DrawRoundedRectangle(const Rect& rect, const Vec2& radius) override;

    void DrawEllipse(const Point& center, const Vec2& radius) override;

    void FillShape(const Shape& shape) override;

    void FillRectangle(const Rect& rect) override;

    void FillRoundedRectangle(const Rect& rect, const Vec2& radius) override;

    void FillEllipse(const Point& center, const Vec2& radius) override;

    void PushClipRect(const Rect& clip_rect) override;

    void PopClipRect() override;

    void PushLayer(Layer& layer) override;

    void PopLayer() override;

    void Clear() override;

    void Clear(const Color& clear_color) override;

    Size GetSize() const override;

    void SetCurrentBrush(BrushPtr brush) override;

    void SetCurrentStrokeStyle(StrokeStylePtr stroke_style) override;

    void SetTransform(const Matrix3x2& matrix) override;

    void SetBlendMode(BlendMode blend) override;

    void SetAntialiasMode(bool enabled) override;

    void SetTextAntialiasMode(TextAntialiasMode mode) override;

    bool CheckVisibility(const Rect& bounds, const Matrix3x2& transform) override;

    void Resize(const Size& size) override;

    TexturePtr GetTarget() const override;

private:
    void DiscardDeviceResources();

    void SaveDrawingState();

    void RestoreDrawingState();

private:
    ComPtr<ITextRenderer>          text_renderer_;
    ComPtr<ID2D1DeviceContext>     render_ctx_;
    ComPtr<ID2D1DrawingStateBlock> drawing_state_;
};

}  // namespace directx
}  // namespace graphics
}  // namespace kiwano
