//
//  SubtitlesRenderContext.h
 
//
//  Created by James McGill on 22/01/2016.
//  Copyright © 2016 castLabs. All rights reserved.
//

#ifndef SubtitlesRenderContext_h
#define SubtitlesRenderContext_h

#include "AbstractRenderContext.h"
#include <memory>

#import <UIKit/UIKit.h>

namespace timedText {

class SubtitlesRenderContext : public AbstractRenderContext {
private:
    struct RenderImp;
    std::unique_ptr<RenderImp> m_pImpl;

public:
    SubtitlesRenderContext();
    virtual ~SubtitlesRenderContext();

    SubtitlesRenderContext(const SubtitlesRenderContext&) = delete;
    SubtitlesRenderContext(SubtitlesRenderContext&&) = delete;
    SubtitlesRenderContext& operator=(const SubtitlesRenderContext&) = delete;
    SubtitlesRenderContext& operator=(SubtitlesRenderContext&&) = delete;

    void setContext(CGContextRef context);
    void setVideoContentSize(CGSize);
    void setCanvasSize(CGSize);

    // Drawing canvas area.
    virtual int getCanvasWidth() const override;
    virtual int getCanvasHeight() const override;

    // Video surface area (NB. Assumed to be centred on the canvas area).
    virtual int getVideoWidth() const override;
    virtual int getVideoHeight() const override;

    // Push/Pop rendering context.
    virtual void save() override;
    virtual void restore() override;

    // Transform the coordinate system.
    virtual void translate(int x, int y) override;
    virtual void scale(double x, double y) override;

    // Add a clipping region (drawing shown only inside this region).
    virtual void clipRect(const RectPx& rect) override;

    // Draw some text with the given style and position.
    virtual void drawTextFragment(
      const TextFragment& fragment,
      double x,
      double y) override;

    // Draw a line at the given position and colour(filling) info.
    virtual void drawLine(
      int startX,
      int startY,
      int stopX,
      int stopY,
      const FillInfo& fill) override;

    // Draw a rectangle region at the given position and colour(filling) info.
    virtual void drawRect(
      const RectPx& rect,
      const FillInfo& fill) override;

    // Erase any previous drawing on the canvas within the given rectangular region
    virtual void eraseRect(const RectPx& rect) override;
    
    // Provide screen measurement of a piece of text, if it where rendered.
    virtual std::shared_ptr<AbstractFontContext>
    createFontContext(const TextSpan& fragment, const RenderSettings &settings) override;
    
private:
    void applyFill(const FillInfo& fill);
};

struct FontContext : public AbstractFontContext {
    virtual ~FontContext() = default;

    // ascent() and descent() MUST always return positive values
    virtual double ascent() const override;
    virtual double descent() const override;
    virtual double measureTextWidth(const std::string&) const override;

    NSAttributedString* createAttributedString(const std::string& text, NSDictionary* attributes) const;

    UIFont* m_font;
    NSDictionary* m_fontAttributes;
    NSDictionary* m_fontShadowAttributes;
};

};

#endif
