/*
 * 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
 */

/**
 * @file
 *
 * This example shows you how to create an application using the EZGL library.
 */

#include "ezgl/application.hpp"
#include "ezgl/graphics.hpp"

#include <iostream>

// Callback functions for event handling
void act_on_mouse_press(ezgl::application *application, GdkEventButton *event, double x, double y);
void act_on_mouse_move(ezgl::application *application, GdkEventButton *event, double x, double y);
void act_on_key_press(ezgl::application *application, GdkEventKey *event, char *key_name);
void initial_setup(ezgl::application *application);
void test_button(GtkWidget *widget, ezgl::application *application);

/**
 * Draw to the main canvas using the provided graphics object.
 *
 * The graphics object expects that x and y values will be in the main canvas' world coordinate system.
 */
void draw_main_canvas(ezgl::renderer &g);

/**
 * draw_main_canvas helper functions
 */
void draw_rectangle_example(ezgl::renderer &g);
void draw_arc_example(ezgl::renderer &g);
void rotated_text_example(ezgl::renderer &g);
void draw_poly_example(ezgl::renderer &g);
void draw_text_example(ezgl::renderer &g);
void draw_line_example(ezgl::renderer &g);
void screen_coordinates_example(ezgl::renderer &g);
void draw_png_example(ezgl::renderer &g);

static ezgl::rectangle initial_world{{0, 0}, 1100, 1150};

/**
 * The start point of the program.
 *
 * This function initializes an ezgl application and runs it.
 *
 * @param argc The number of arguments provided.
 * @param argv The arguments as an array of c-strings.
 *
 * @return the exit status of the application run.
 */
int main(int /*argc*/, char **/*argv*/)
{
  ezgl::application::settings settings;

  // Path to the resource that contains an XML description of the UI.
  // Note: this is not a file path, it is a resource path.
  settings.main_ui_resource = "/ezgl/main.ui";

  // Note: the "main.ui" file has a GtkWindow called "MainWindow".
  settings.window_identifier = "MainWindow";

  // Note: the "main.ui" file has a GtkDrawingArea called "MainCanvas".
  settings.canvas_identifier = "MainCanvas";

  // Create our EZGL application.
  ezgl::application application(settings);

  application.add_canvas("MainCanvas", draw_main_canvas, initial_world);

  // Run the application until the user quits.
  // This hands over all control to the GTK runtime---after this point
  // you will only regain control based on callbacks you have setup.
  // Three callbacks can be provided to handle mouse button presses,
  // mouse movement and keyboard button presses in the graphics area,
  // respectively. Also, an initial_setup function can be passed that will
  // be called before the activation of the application and can be used
  // to create additional buttons, initialize the status message, or
  // connect added widgets to their callback functions.
  // Those callbacks are optional, so we can pass nullptr if
  // we don't need to take any action on those events
  return application.run(initial_setup, act_on_mouse_press, act_on_mouse_move, act_on_key_press);
}

/**
 * The redrawing function for still pictures
 */
void draw_main_canvas(ezgl::renderer &g)
{
  // Draw some rectangles
  draw_rectangle_example(g);

  // Draw different arcs
  draw_arc_example(g);

  // Draw some rotated text
  rotated_text_example(g);

  // Draw different transparent and opaque polys
  draw_poly_example(g);

  // Draw some text with different sizes
  draw_text_example(g);

  // Draw wide lines with different end shapes
  draw_line_example(g);

  // Draw to screen coordinates
  screen_coordinates_example(g);

  // Draw a small png
  draw_png_example(g);
}

/**
 * Draw some rectangles with different colors
 */
void draw_rectangle_example(ezgl::renderer &g)
{
  const float rectangle_width = 50;
  const float rectangle_height = rectangle_width;
  const ezgl::point2d start_point(150, 30);
  ezgl::rectangle color_rectangle = {start_point, rectangle_width, rectangle_height};

  // Some of the available colors, a complete list is in ezgl/include/color.hpp
  ezgl::color color_indicies[] = {
    ezgl::GREY_55,
    ezgl::GREY_75,
    ezgl::WHITE,
    ezgl::BLACK,
    ezgl::BLUE,
    ezgl::GREEN,
    ezgl::YELLOW,
    ezgl::CYAN,
    ezgl::RED,
    ezgl::DARK_GREEN,
    ezgl::MAGENTA
  };

  // format text font and color
  g.set_color(ezgl::BLACK);
  g.format_font("monospace", ezgl::font_slant::normal, ezgl::font_weight::normal, 10);

  // draw text
  g.draw_text({110, color_rectangle.center_y()}, "colors", 2 * (start_point.x - 110), rectangle_height);

  for (size_t i = 0; i < sizeof (color_indicies) / sizeof (color_indicies[0]); ++i) {
    // Change the color of next draw calls
    g.set_color(color_indicies[i]);

    // Draw filled in rectangles
    g.fill_rectangle(color_rectangle);

    // Increment the start point
    color_rectangle += {rectangle_width, 0};
  }

  // Draw text
  g.draw_text({400, color_rectangle.center_y()}, "fill_rectangle", DBL_MAX, rectangle_height);

  /* Draw some rectangles with RGB triplet colors and alpha (transparency) */

  // Hack to make the colors change once per second
  std::srand(time(0));

  for (size_t i = 0; i < 3; ++i) {
    // Increment the start point
    color_rectangle += {rectangle_width, 0};

    // Change the next draw calls color. rgb and alpha values range from 0 to 255
    g.set_color(std::rand() % 256, std::rand() % 256, std::rand() % 256, 255);

    // Draw filled in rectangles
    g.fill_rectangle(color_rectangle);
  }

  /* Draw a black border rectangle */

  // Change the next draw calls color to black
  g.set_color(ezgl::BLACK);

  // Change the next draw calls line width
  g.set_line_width(1);

  // Draw a rectangle bordering all the drawn rectangles
  g.draw_rectangle(start_point, color_rectangle.top_right());
}

/**
 * Draw some example lines, shapes, and arcs
 */
void draw_arc_example(ezgl::renderer &g)
{
  float radius = 50;

  // Draw solid line
  g.set_color(ezgl::BLACK);
  g.draw_text({250, 150}, "draw_line", 150.0, DBL_MAX);
  g.set_line_dash(ezgl::line_dash::none);
  g.draw_line({200, 120}, {200, 200});

  // Draw dashed line
  g.set_line_dash(ezgl::line_dash::asymmetric_5_3);
  g.draw_line({300, 120}, {300, 200});

  // Draw elliptic arc
  g.set_color(ezgl::MAGENTA);
  g.draw_text({450, 160}, "draw_elliptic_arc", 150.0, DBL_MAX);
  g.draw_elliptic_arc({550, 160}, 30, 60, 90, 270);

  // Draw filled in elliptic arc
  g.draw_text({700, 160}, "fill_elliptic_arc", 150.0, DBL_MAX);
  g.fill_elliptic_arc({800, 160}, 30, 60, 90, 270);

  // Draw arcs
  g.set_color(ezgl::BLUE);
  g.draw_text({190, 300}, "draw_arc", radius * 2, 150);
  g.draw_arc({190, 300}, radius, 0, 270);
  g.draw_arc({300, 300}, radius, 0, -180);

  // Draw filled in arcs
  g.fill_arc({410, 300}, radius, 90, -90);
  g.fill_arc({520, 300}, radius, 0, 360);
  g.set_color(ezgl::BLACK);
  g.draw_text({520, 300}, "fill_arc", radius * 2, 150);
  g.set_color(ezgl::BLUE);
  g.fill_arc({630, 300}, radius, 90, 180);
  g.fill_arc({740, 300}, radius, 90, 270);
  g.fill_arc({850, 300}, radius, 90, 30);
}

/**
 * Draw some rotated text
 */
void rotated_text_example(ezgl::renderer &g)
{
  const float textsquare_width = 200;

  ezgl::rectangle textsquare = {{100, 400}, textsquare_width, textsquare_width};

  g.set_color(ezgl::BLUE);
  g.draw_rectangle(textsquare);

  g.set_color(ezgl::GREEN);
  g.draw_rectangle(textsquare.center(), {textsquare.right(), textsquare.top()});
  g.draw_rectangle({textsquare.left(), textsquare.bottom()}, textsquare.center());

  g.set_color(ezgl::RED);
  g.draw_line({textsquare.left(), textsquare.bottom()}, {textsquare.right(), textsquare.top()});
  g.draw_line({textsquare.left(), textsquare.top()}, {textsquare.right(), textsquare.bottom()});

  g.set_color(0, 0, 0, 100);
  g.set_font_size(14);
  g.draw_text({textsquare.center_x(), textsquare.bottom()}, "0 degrees", textsquare.width(), textsquare.height());

  g.set_text_rotation(90);
  g.draw_text({textsquare.right(), textsquare.center_y()}, "90 degrees", textsquare.width(), textsquare.height());

  g.set_text_rotation(180);
  g.draw_text({textsquare.center_x(), textsquare.top()}, "180 degrees", textsquare.width(), textsquare.height());

  g.set_text_rotation(270);
  g.draw_text({textsquare.left(), textsquare.center_y()}, "270 degrees", textsquare.width(), textsquare.height());

  g.set_text_rotation(45);
  g.draw_text(textsquare.center(), "45 degrees", textsquare.width(), textsquare.height());

  g.set_text_rotation(135);
  g.draw_text(textsquare.center(), "135 degrees", textsquare.width(), textsquare.height());

  // It is probably a good idea to set text rotation back to zero,
  g.set_text_rotation(0);
}

/**
 * Draw some Polygons
 */
void draw_poly_example(ezgl::renderer &g)
{
  g.set_font_size(10);
  g.set_color(ezgl::RED);

  // Draw a triangle
  g.fill_poly({{500, 400}, {440, 480}, {560, 480}});

  // Draw a 4-point polygon
  g.fill_poly({{700, 400}, {650, 480}, {750, 480}, {800, 400}});

  g.set_color(ezgl::BLACK);
  g.draw_text({500, 450}, "fill_poly", 80.0, DBL_MAX);
  g.draw_text({725, 440}, "fill_poly", 100.0, DBL_MAX);

  g.set_color(ezgl::DARK_GREEN);
  g.set_line_dash(ezgl::line_dash::none);
  ezgl::rectangle rect = {{350, 550}, {650, 670}};
  g.draw_text(rect.center(), "draw_rectangle", rect.width(), rect.height());
  g.draw_rectangle(rect);

  /* Draw some semi-transparent primitives */
  g.set_font_size(10);

  g.set_color(255, 0, 0, 255);
  g.fill_rectangle({1000, 400}, {1050, 800});

  g.set_color(0, 0, 255, 255);
  g.fill_rectangle({1000+50, 400}, {1050+50, 800});

  g.set_color(0, 255, 0, 255/2);  // 50% transparent
  g.fill_rectangle({1000+25, 400-100}, {1050+25, 800-200});

  g.set_color(255, 100, 255, 255/2);
  g.fill_poly({{465, 380}, {400, 450}, {765, 450}, {850, 380}});

  g.set_color(100, 100, 255, 255/3);
  g.fill_poly({{550, 420}, {475, 500}, {875, 500}});

  g.set_color(ezgl::BLACK);
  g.set_text_rotation(90);
  g.draw_text({1000 - 50, 500}, "Partially transparent polys", 500, DBL_MAX);
  g.set_text_rotation(0);
}

/**
 * Draw some example text, with the bounding box functions
 */
void draw_text_example(ezgl::renderer &g)
{

  const float text_example_width = 800;
  const int num_lines = 2;
  const int max_strings_per_line = 3;
  const int num_strings_per_line[num_lines] = {3, 2};

  const char* const line_text[num_lines][max_strings_per_line] = {
    {
      "8 Point Text",
      "12 Point Text",
      "18 Point Text"
    },
    {
      "24 Point Text",
      "32 Point Text"
    }
  };

  const int text_sizes[num_lines][max_strings_per_line] = {
    {8, 12, 15},
    {24, 32}
  };

  g.set_color(ezgl::BLACK);
  g.set_line_dash(ezgl::line_dash::asymmetric_5_3);

  for (int i = 0; i < num_lines; ++i) {
    ezgl::rectangle text_bbox = {{100., 710. + i * 60.}, text_example_width / num_strings_per_line[i], 60.};

    for (int j = 0; j < num_strings_per_line[i]; ++j) {
      g.set_font_size(text_sizes[i][j]);
      g.draw_text(text_bbox.center(), line_text[i][j], text_bbox.width(), text_bbox.height());
      g.draw_rectangle(text_bbox);
      text_bbox = {{text_bbox.left() + text_example_width / num_strings_per_line[i], text_bbox.bottom()} , text_bbox.width(), text_bbox.height()};
    }
  }
}

/**
 * Draw wide lines with different end shapes
 */
void draw_line_example(ezgl::renderer &g)
{
  g.set_font_size(10);

  for (int i = 0; i <= 2; ++i)
  {
    double offsetY = 50*i;

    g.set_horiz_text_just(ezgl::text_just::left);

    if (i == 0) {
      g.set_color(ezgl::BLACK);
      g.set_line_cap(ezgl::line_cap::butt); // Butt ends
      g.set_line_dash(ezgl::line_dash::none); // Solid line
      g.draw_text({950, 920+offsetY}, "Butt ends, opaque", 400, DBL_MAX);
    }

    else if (i == 1) {
      g.set_color(ezgl::GREEN, 255*2/3); // Green line that is 33% transparent)
      g.set_line_cap(ezgl::line_cap::round); // Round ends
      g.set_line_dash(ezgl::line_dash::none); // Solid line
      g.draw_text({950, 920+offsetY}, "Round ends, 33% transparent", 400, DBL_MAX);
    }

    else {
      g.set_color(ezgl::RED, 255/3);  // Red line that is 67% transparent
      g.set_line_cap(ezgl::line_cap::butt); // butt ends
      g.set_line_dash(ezgl::line_dash::asymmetric_5_3); // Dashed line
      g.draw_text({950, 920+offsetY}, "Butt ends, 67% transparent", 400, DBL_MAX);
    }

    g.set_horiz_text_just(ezgl::text_just::center);

    g.draw_text({200, 900+offsetY}, "Thin line (width 1)", 200, DBL_MAX);
    g.set_line_width(1);
    g.draw_line({100, 920+offsetY}, {300, 920+offsetY});

    g.draw_text({500, 900+offsetY}, "Width 3 Line", 200, DBL_MAX);
    g.set_line_width(3);
    g.draw_line({400, 920+offsetY}, {600, 920+offsetY});

    g.draw_text({800, 900+offsetY}, "Width 6 Line", 200, DBL_MAX);
    g.set_line_width(6);
    g.draw_line({700, 920+offsetY}, {900, 920+offsetY});

    g.set_line_width(1);
  }
}

/**
 * Draw to screen coordinates where (0,0) is the top-left corner of the window
 * These coordinates are not transformed so the object will not pan or zoom.
 */
void screen_coordinates_example(ezgl::renderer &g)
{
  // Set the coordinate system to SCREEN
  g.set_coordinate_system(ezgl::SCREEN);

  g.set_color(255, 0, 0, 255);
  g.set_line_dash(ezgl::line_dash::none);
  g.draw_rectangle({10, 10}, {100, 100});
  g.set_font_size(10);
  g.draw_text({55, 33}, "Screen coord");
  g.draw_text({55, 66}, "Fixed loc");

  // Set the coordinate system back to WORLD
  g.set_coordinate_system(ezgl::WORLD);
}

/**
 * Draw a small PNG
 */
void draw_png_example(ezgl::renderer &g)
{
  ezgl::surface *png_surface = ezgl::renderer::load_png("small_image.png");
  g.draw_surface(png_surface, {50, 200});
  ezgl::renderer::free_surface(png_surface);
  g.set_font_size(10);
  g.set_color(ezgl::BLACK);
  g.draw_text ({50, 225}, "draw_surface", 200, DBL_MAX);
}

/**
 * Function called before the activation of the application
 * Can be used to create additional buttons, initialize the status message,
 * or connect added widgets to their callback functions
 */
void initial_setup(ezgl::application *application)
{
  // Update the status bar message
  application->update_message("EZGL Application");

  // Create a Test button and link it with test_button callback fn.
  application->create_button("Test", 6, test_button);
}

/**
 * Function to handle mouse press event
 * The current mouse position in the main canvas' world coordinate system is returned
 * A pointer to the application and the entire GDK event are also returned
 */
void act_on_mouse_press(ezgl::application *application, GdkEventButton *event, double x, double y)
{
  application->update_message("Mouse Clicked");

  std::cout << "User clicked the ";

  if (event->button == 1)
    std::cout << "left ";
  else if (event->button == 2)
    std::cout << "middle ";
  else if (event->button == 3)
    std::cout << "right ";

  std::cout << "mouse button at coordinates (" << x << "," << y << ") ";

  if ((event->state & GDK_CONTROL_MASK) && (event->state & GDK_SHIFT_MASK))
    std::cout << "with control and shift pressed ";
  else if (event->state & GDK_CONTROL_MASK)
    std::cout << "with control pressed ";
  else if (event->state & GDK_SHIFT_MASK)
    std::cout << "with shift pressed ";

  std::cout << std::endl;
}

/**
 * Function to handle mouse move event
 * The current mouse position in the main canvas' world coordinate system is returned
 * A pointer to the application and the entire GDK event are also returned
 */
void act_on_mouse_move(ezgl::application */*application*/, GdkEventButton */*event*/, double x, double y)
{
  std::cout << "Mouse move at coordinates (" << x << "," << y << ") "<< std::endl;
}

/**
 * Function to handle keyboard press event
 * The name of the key pressed is returned (0-9, a-z, A-Z, Up, Down, Left, Right, Shift_R, Control_L, space, Tab, ...)
 * A pointer to the application and the entire GDK event are also returned
 */
void act_on_key_press(ezgl::application *application, GdkEventKey */*event*/, char *key_name)
{
  application->update_message("Key Pressed");

  std::cout << key_name <<" key is pressed" << std::endl;
}

/**
 * A callback function to test the Test button
 */
void test_button(GtkWidget */*widget*/, ezgl::application *application)
{
  // Update the status bar message
  application->update_message("Test Button Pressed");

  // Redraw the main canvas
  application->refresh_drawing();

  // Draw a temporary rectangle border
  ezgl::renderer g = application->get_renderer();
  g.set_line_width(1);
  g.set_color(ezgl::BLACK);
  g.draw_rectangle({{0, 0}, 1100, 1150});
  application->flush_drawing();
}

