/*
 * Copyright 2019 University of Toronto
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors: Mario Badr, Sameh Attia and Tanner Young-Schultz
 */

#ifndef EZGL_CANVAS_HPP
#define EZGL_CANVAS_HPP

#include "ezgl/camera.hpp"
#include "ezgl/rectangle.hpp"
#include "ezgl/graphics.hpp"
#include "ezgl/color.hpp"

#include <cairo.h>
#include <cairo-pdf.h>
#include <cairo-svg.h>
#include <gtk/gtk.h>

#include <string>

namespace ezgl {

/**** Functions in this class are for ezgl internal use; application code doesn't need to call them ****/

class renderer;

/**
 * The signature of a function that draws to an ezgl::canvas.
 */
using draw_canvas_fn = void (*)(renderer &);

/**
 * Responsible for creating, destroying, and maintaining the rendering context of a GtkWidget.
 *
 * Underneath, the class relies on a GtkDrawingArea as its GUI widget along with cairo to provide the rendering context.
 * The class connects to the relevant GTK signals, namely configure and draw events, to remain responsive.
 *
 * Each canvas is double-buffered. A draw callback (see: ezgl::draw_canvas_fn) is invoked each time the canvas needs to
 * be redrawn. This may be caused by the user (e.g., resizing the screen), but can also be forced by the programmer.
 */
class canvas {
public:
  /**
   * Destructor.
   */
  ~canvas();

  /**
   * Get the name (identifier) of the canvas.
   */
  char const *id() const
  {
    return m_canvas_id.c_str();
  }

  /**
   * Get the width of the canvas in pixels.
   */
  int width() const;

  /**
   * Get the height of the canvas in pixels.
   */
  int height() const;

  /**
   * Force the canvas to redraw itself.
   *
   * This will invoke the ezgl::draw_canvas_fn callback and queue a redraw of the GtkWidget.
   */
  void redraw();

  /**
   * Get an immutable reference to this canvas' camera.
   */
  camera const &get_camera() const
  {
    return m_camera;
  }

  /**
   * Get a mutable reference to this canvas' camera.
   */
  camera &get_camera()
  {
    return m_camera;
  }

  /**
   * Create a temporary renderer that can be used to draw on top of the current canvas
   *
   * The created renderer should be used only in the same callback in which it was created
   */
  renderer create_temporary_renderer();
  
  /**
   * print_pdf, print_svg, and print_png generate a PDF, SVG, or PNG output file showing 
   * all the graphical content of the current canvas. 
   * 
   * @param file_name   name of the output file
   * @return            returns true if the function has successfully generated the output file, otherwise
   *                    failed due to errors such as out of memory occurs. 
   */
  bool print_pdf(const char *file_name);
  bool print_svg(const char *file_name);
  bool print_png(const char *file_name);
  
  
protected:
  // Only the ezgl::application can create and initialize a canvas object.
  friend class application;

  /**
   * Create a canvas that can be drawn to.
   */
  canvas(std::string canvas_id, draw_canvas_fn draw_callback, rectangle coordinate_system, color background_color);

  /**
   * Lazy initialization of the canvas class.
   *
   * This function is required because GTK will not send activate/startup signals to an ezgl::application until control
   * of the program has been reliquished. The GUI is not built until ezgl::application receives an activate signal.
   */
  void initialize(GtkWidget *drawing_area);

private:
  // Name of the canvas in XML.
  std::string m_canvas_id;

  // The function to call when the widget needs to be redrawn.
  draw_canvas_fn m_draw_callback;

  // The transformations between the GUI and the world.
  camera m_camera;

  // The background color of the drawing area
  color m_background_color;

  // A non-owning pointer to the drawing area inside a GTK window.
  GtkWidget *m_drawing_area = nullptr;

  // The off-screen surface that can be drawn to.
  cairo_surface_t *m_surface = nullptr;

  // The off-screen cairo context that can be drawn to
  cairo_t *m_context = nullptr;

private:
  // Called each time our drawing area widget has changed (e.g., in size).
  static gboolean configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data);

  // Called each time we need to draw to our drawing area widget.
  static gboolean draw_surface(GtkWidget *widget, cairo_t *context, gpointer data);
};
}

#endif //EZGL_CANVAS_HPP
