/*
 * 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();
}

