/*
 * Easygl Version 3.0
 * Originally written by Vaughn Betz (vaughn@eecg.utoronto.ca)
 * Win32 port by Paul Leventis (pleventi@altera.com)
 * Enhanced version by William Chow (wchow@altera.com)
 * Minor updates by Guy Lemieux (lemieux@ece.ubc.ca)
 * More updates by Vaughn Betz to make win32 cleaner and more robust.
 * More updates and code cleanup by Long Yu Wang (longyu.wang@mail.utoronto.ca)
 * More updates and c++ integration - Matthew J.P. Walker (matthewjp.walker@mail.utoronto.ca)
 * Cairo integration and other updates by Harry Liang and Davis Wu
 *
 * All rights reserved by U of T, etc.                                      *
 *                                                                          *
 * You may freely use this graphics interface for non-commercial purposes   *
 * as long as you leave the author info above in it.                        *
 *                                                                          *
 * Revision History:                                                        *
 *                                                                          *
 * V4.0 Jan. 2017 - Harry Liang and Davis Wu                                *
 * - Integrated with Cairo to allow transparency. Direct X11 drawing used   *
 *   when alpha = 1 (255) as it is faster than using Cairo's layer above    *
 *   X11. Also added double buffering, png file bitmap drawing, and the     *
 *   ability to draw in screen coordinates that don't pan or zoom.          *
 *                                                                          *
 * V3.0 May 2014 - June 2014 (Matthew J.P. Walker)                          *
 * - continued integration with c++                                         *
 * - added ybounding and convenience functions to text drawing              *
 * - added get_visible_world() - returns a rectangle describing the bounds  *
 *   of the visible world.                                                  *
 * - Panning and zooming will drop events instead of drawing all of them.   *
 *   Much more usable on large drawings now.                                *
 * - Added support for aribtrary RGB color triplets to X11, windows and ps. *
 * - Modernized X11 font handling and text drawing by converting it to Xft. *
 * - Added text rotation to X11, windows and postscript.                    *
 * - Changed font caching, removing font size limit.                        *
 * - Added unicode support in all text, via UTF-8.                          *
 *                                                                          *
 * V2.0.2 May 2013 - June 2013 (Mike Wang)                                  *
 * - In Win32, removed "Window" operation with right mouse click to align   *
 *   with X11.                                                              *
 * - Fixed a bug in Win32 where when the "Window" button is clicked, if the *
 *   application window gets minimized then returned back up, the screen    *
 *   background would not be redrawn before new rubber band gets drawn.     *
 * - Grouped file scope variables into structures, factored out functions   *
 *   that were too long, and formatted code spacings etc.                   *
 * - Cleaned up Win32 code by removing the inefficient saving and updating  *
 *   of graphics contexts.                                                  *
 * - Added zooming with respect to cursor location.                         *
 * - Added panning with middle mouse button (or mousewheel) click and drag. *
 * - Ran experiment to test the impact of rect_off_screen() on drawscreen() *
 *   runtime. Found rect_off_screen() to be effective in speeding up screen *
 *   redraw.                                                                *
 * - Added zooming using mousewheel.                                        *
 *                                                                          *
 * V2.0.1 Sept. 2012 (Vaughn Betz)                                          *
 * - Fixed a bug in Win32 where postscript output would make the graphics   *
 *   crash when you redrew.                                                 *
 * - Made a cleaner makefile to simplify platform selection.                *
 * - Commented and reorganized some of the code.  Started cleaning up some  *
 *   of the win32 code.  Win32 looks inefficient; it is saving and updating *
 *   graphics contexts all the time even though we know when the context is *
 *   valid vs. not-valid.                                                   *
 *   TODO: make win32 work more like X11 (minimize gc updates).             *
 *                                                                          *
 * V2.0:  Nov. 21, 2011 (Vaughn Betz)                                       *
 * - Updated example code, and some cleanup and bug fixes to win32 code.    *
 * - Removed some win32 code that had no X11 equivalent or wasn't well      *
 *   documented.                                                            *
 * - Used const char * where appropriate to get rid of g++ warnings.        *
 * - Made interface to things like xor drawing more consistent, and added   *
 *   to example program.                                                    *
 * - Made a simpler (easygl.cpp) interface to the graphics library for      *
 *   use by undergraduate students.                                         *
 *                                                                          *
 * V1.06 : July 23, 2003 : (Guy Lemieux)                                    *
 * - added some typecasts to cleanly compile with g++ and MS c++ tools      *
 * - if WIN32 not defined, it defines X11 automatically                     *
 * - fixed X11 compilation; WIN32 broke some things                         *
 *                                                                          *
 * V1.05 : July 26, 2001 : (William)                                        *
 * - changed keyboard detect function to accept an int (virtual key)        *
 *                                                                          *
 * V1.04 : June 29, 2001 : (William)                                        *
 * - added drawcurve(), fillcurve() using Bezier curves                     *
 *   (support WIN32 screen / ps)                                            *
 * - added pt on object capability : using a memory buffer to draw an       *
 *   graphics objects, then query if a point fall on the object (bear the   *
 *   object's colour) : object_start(), object_end(), pt_on_object()        *
 * - added drawellipticarc(), fillellipticarc()                             *
 * - added findfontsize() to help find a pointsize of a given height        *
 * - extended t_report to keep xleft, xright, ytop, ybot                    *
 * - added update_window() to set the window bb                             *
 *                                                                          *
 * V1.03 : June 18, 2001 : (William)                                        *
 * - added change_button_text()                                             *
 *                                                                          *
 * V1.02 : June 13, 2001 : (William)                                        *
 * - extension to mouse click function : can tell if ctrl/shift keys are    *
 *   pressed                                                                *
 *                                                                          *
 * V1.01 : June 1, 2001 : (William)                                         *
 * - add tooltip support                                                    *
 *                                                                          *
 * V1.0 : May 14, 2001 : (William)                                          *
 * - fixed a problem with line styles, initial release on the internet      *
 *                                                                          *
 * March 27, 2001 : (William)                                               *
 * - added setcolor_by_colorref to make more colors available (in Win32)    *
 *                                                                          *
 * February 16, 2001 : (William)                                            *
 * - added quick zoom using right mouse clicks                              *
 *                                                                          *
 * February 11, 2001 : (William)                                            *
 * - can define cleanup(), passed in when calling init_graphics(), and      *
 *   called when shutting down                                              *
 *                                                                          *
 * February 1, 2001 : (William)                                             *
 * - fix xor mode redraw problem                                            *
 *                                                                          *
 * September 19, 2000 : (William)                                           *
 * - can define mouse_move callback function                                *
 * - can add separators in between buttons                                  *
 *                                                                          *
 * September 8, 2000 : (William)                                            *
 * - added result_structure(),                                              *
 * - can define background color in init_graphics                           *
 *                                                                          *
 * August 10, 2000 : (William Chow, choww@eecg.utoronto.ca)                 *
 * - Finished all Win32 support functions                                   *
 * - use XOR mode for window zooming box                                    *
 * - added double buffering feature                                         *
 *                                                                          *
 * January 12, 1999: (Paul)                                                 *
 * - Fixed a bunch of stuff with the Win32 support (memory leaks, etc)      *
 * - Made the clipping function using the update rectangle for Win32        *
 *                                                                          *
 * January 9, 1999:  (Paul Leventis, leventi@eecg.utoronto.ca)              *
 * - Added Win32 support.  Should work under Windows98/95/NT 4.0/NT 5.0.    *
 * - Added a check to deselect_all to determine whether the screen needs to *
 * be updated or not.  Should elminate flicker from mouse clicks            *
 * - Added win32_invalidate_screen() call to graphics.c that in turn calls  *
 *   update_screen, so this function was made non-static and added to the   *
 *   header file.  This is due to differences in the structure of Win32     *
 *   windowing apps.                                                        *
 * - Win32 needs clipping (though done automatically, could be faster)      *
 *                                                                          *
 * Sept. 19, 1997:  Incorporated Zoom Fit code of Haneef Mohammed at        *
 * Cypress.  Makes it easy to zoom to a full view of the graphics.          *
 *                                                                          *
 * Sept. 11, 1997:  Added the create_and destroy_button interface to        *
 * make it easy to add and destroy buttons from user code.  Removed the     *
 * bnum parameter to the button functions, since it wasn't really needed.   *
 *                                                                          *
 * June 28, 1997:  Added filled arc drawing primitive.  Minor modifications *
 * to PostScript driver to make the PostScript output slightly smaller.     *
 *                                                                          *
 * April 15, 1997:  Added code to init_graphics so it waits for a window    *
 * to be exposed before returning.  This ensures that users of non-         *
 * interactive graphics can never draw to a window before it is available.  *
 *                                                                          *
 * Feb. 24, 1997:  Added code so the package will allocate  a private       *
 * colormap if the default colormap doesn't have enough free colours.       *
 *                                                                          *
 * June 28, 1996:  Converted all internal functions in graphics.c to have   *
 * internal (static) linkage to avoid any conflicts with user routines in   *
 * the rest of the program.                                                 *
 *                                                                          *
 * June 12, 1996:  Added setfontsize and setlinewidth attributes.  Added    *
 * pre-clipping of objects for speed (and compactness of PS output) when    *
 * graphics are zoomed in.  Rewrote PostScript engine to shrink the output  *
 * and make it easier to read.  Made drawscreen a callback function passed  *
 * in rather than a global.  Graphics attribute calls are more efficient -- *
 * they check if they have to change anything before doing it.              *
 *                                                                          *
 * October 27, 1995:  Added the message area, a callback function for       *
 * interacting with user button clicks, and implemented a workaround for a  *
 * Sun X Server bug that misdisplays extremely highly zoomed graphics.      *
 *                                                                          *
 * Jan. 13, 1995:  Modified to incorporate PostScript Support.              */

/**************************** Top-level summary ******************************
This graphics package provides API for client program that wishes to implement
a graphical user interface. The client program will first call init_graphics()
for initial setup, which includes opening up an application window, setting up
the specified window_name and background colour, creating sublevel windows,
etc. Then the program will call a few more setup functions such as
set_visible_world(), which sets up world coordinates, create_button(), which sets up
menu buttons, and update_message(), which updates status bar message. After
all the setup, the program will call the main routine for the graphics,
event_loop(), which will take control of the program until the "Proceed"
button is pressed. Event_loop() directly communicates with X11/Win32 to
receive event notifications, and it either calls other event-handling
functions in the graphics package or callbacks passed as function pointers
from the client program. The most important callback function which the
client should provide is drawscreen(). Whenever the graphics need to be
redrawn, drawscreen() will be called. There are a number drawing routines
which the client can use to update the graphic contexts (ie. setcolor,
setfontsize, setlinewidth, and setlinestyle) and draw simple shapes as
desired. When the program is done executing the graphics, it should call
close_graphics() to release all drawing structures and close the graphics.*/

#ifndef NO_GRAPHICS  // Strip everything out and just put in stubs if NO_GRAPHICS defined

/**********************************
 * Common Preprocessor Directives *
 **********************************/
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include <cassert>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <unordered_map>
#include <sys/timeb.h>
#include "graphics.h"
#include "graphics_state.h"
#include "graphics_automark.h"

#include "SurfaceImpl.h" //Needed by draw_surface to access the underlying surface type

using namespace std;


#if defined(X11) || defined(WIN32)

// VERBOSE is very helpful for developing event handling features. Outputs
// useful information when user interacts with the graphic interface.
// Uncomment the line below to turn on VERBOSE.
//#define VERBOSE

#define MWIDTH			104 /* Width of menu window */
#define MENU_FONT_SIZE  11  /* Font for menus and dialog boxes. */
#define T_AREA_HEIGHT	24  /* Height of text window */

#define BUTTON_TEXT_LEN	100

#define ZOOM_FACTOR  1.6667 /* For zooming on the graphics */
#endif

#ifdef X11

/*********************************************
 * X-Windows Specific Preprocessor Directives *
 *********************************************/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include <X11/Xft/Xft.h>

// Some X11 implementations overflow with sufficiently large pixel
// coordinates and start drawing strangely. We will clip all pixels
// to lie in the range below. Don't want to make this too small as
// clipping an x-coordinate but not a y-coordinate can happen,
// and that makes the slope of lines change, etc.
#define MAXPIXEL 32000.f
#define MINPIXEL -32000.f

/* Uncomment the line below if your X11 header files don't define XPointer */
/* typedef char *XPointer;                                                 */

#endif /* X11 Preprocessor Directives */

#if defined(WIN32) || defined(CYGWIN)

/*************************************************************
 * Microsoft Windows (WIN32) Specific Preprocessor Directives *
 *************************************************************/

//#pragma warning(disable : 4996)		// Turn off annoying warnings about strcmp.

#ifndef UNICODE
#define UNICODE // force windows api into unicode (usually UTF-16) mode.
#endif

#include <windows.h>
#include <windowsx.h>

/* Using large values of pixel limits in order to preserve the slope of diagonal
 * lines when their endpoints are clipped (one at a time) to these pixel limits.
 * However, if these values are too large, then Windows will not draw the lines
 * when zoomed way in. I have increased MAXPIXEL and MINPIXEL to these values so
 * the diagonal lines do not change slope when zoomed way in. Also, I have tested
 * to make sure these values are safe. Adding one more digit to these values
 * may cause problems when zoomed way in.
 * MW, June 2013.
 */
#define MAXPIXEL 21474836.f
#define MINPIXEL -21474836.f

/* Windows work in degrees, where as X11 and PostScript both work in radians.
 * Thus, a conversion is needed for Windows.
 */
#define DEGTORAD(x) ((x)/180.*PI)
#endif /* Win32 preprocessor Directives */


/*************************************************************
 * Common Structure Definitions                              *
 *************************************************************/

/* Indicates if this button displays text, a polygon or is just a separator.
 */
typedef enum {
    BUTTON_TEXT = 0,
    BUTTON_POLY,
    BUTTON_SEPARATOR
} t_button_type;

/* Structure used to define the buttons on the right hand side of the main window (menu region).
 * width, height: button size, in pixels.
 * xleft, ytop: coordinates, in pixels, of the top-left corner of the button relative to its
 *    containing (menu) window.
 * fcn: a callback function that is called when the button is pressed. This function takes one
 *    argument, a function pointer to the routine that can draw the graphics area (user routine).
 * win, hwnd:  X11 and Win32 data pointer to the window, respectively.
 * button_type: indicates if this button displays text, a polygon or is just a separator.
 * text: the text to display if this is a text button.
 * poly: the polygon (up to 3 points right now) to display if this is a polygon button
 * is_pressed: has the button been pressed, and is currently executing its callback?
 * is_enabled: can you press this button right now? Visually will look "pushed in" when
 *      not enabled, and won't respond to clicks.
 */
typedef struct {
    int width;
    int height;
    int xleft;
    int ytop;
    void(*fcn) (void(*drawscreen) ());
#ifdef X11
    Window win;
    XftDraw* draw;
#else
    HWND hwnd;
#endif
    t_button_type type;
    char text[BUTTON_TEXT_LEN]; //Space for terminator
    int poly[3][2];
    bool ispressed;
    bool enabled;
} t_button;

/* Structure used to store all the buttons created in the menu region.
 * button: array of pointers to all the buttons created [0..num_buttons-1]
 * num_buttons: number of menu buttons created
 */
typedef struct {
    t_button *button;
    int num_buttons;
} t_button_state;

/* Structure used to store coordinate information used for
 * graphic transformations.
 * display_width and display_height: entire screen size
 * top_width and top_height: application window size in pixels
 * init_xleft, init_xright, init_ytop, and init_ybot: initial world	coordinates
 *							(for use in zoom_fit() to restore initial coordinates)
 * xleft, xright, ytop, and ybot: boundaries of the graphic child window in world
 * 									coordinates
 * wtos_xmult and wtos_ymult: world to screen transformation factors (number of
 *								screen pixels per world coordinate)
 * stow_xmult and stow_ymult: screen to world transformation factors (number of
 *								world coordinates per screen pixel)
 * ps_left, ps_right, ps_top, and ps_bot: figure boundaries for PostScript output,
 *					in PostScript (point, 1/72 of inch) coordinates
 * ps_xmult and ps_ymult: world to PostScript transformation factors (number of
 *							PostScript coordinates per world coordinate)
 * s_to_ps_xmult and s_to_ps_ymult: Transform from screen (pixel) space to
 *                                   postscript. typeset points per pixel.
 */
typedef struct {
    int display_width, display_height;
    int top_width, top_height;
    float init_xleft, init_xright, init_ytop, init_ybot;
    float xleft, xright, ytop, ybot;
    float wtos_xmult, wtos_ymult;
    float stow_xmult, stow_ymult;
    float ps_left, ps_right, ps_top, ps_bot;
    float ps_xmult, ps_ymult;
    float s_to_ps_xmult, s_to_ps_ymult;
} t_transform_coordinates;

/* Structure used to store state variables used for panning.
 * previous_x and previous_y: (in window (pixel) coordinates,) last location of
 * 								the cursor before new motion
 * panning_enabled: whether panning is activated or de-activated
 */
typedef struct {
    int previous_x, previous_y;
    bool panning_enabled;
} t_panning_state;

/*********************************************************************
 *        File scope variables.              *
 *********************************************************************/

static t_gl_state gl_state;

// Stores all the menu buttons created. Initialize the button pointer
// and num_buttons for safety.
static t_button_state button_state = {nullptr, 0};

// Contains all coordinates useful for graphics transformation
static t_transform_coordinates trans_coord;

// Initialize panning_enabled to false, so panning is not activated
static t_panning_state pan_state = {0, 0, false};

// assert(t_color::predef_colors.size() == NUM_COLOR);

// Color names, also used in postscript generation
static const char *ps_cnames[NUM_COLOR] = {
    "white",
    "black",
    "grey55",
    "grey75",
    "red",
    "orange",
    "yellow",
    "green",
    "cyan",
    "blue",
    "purple",
    "pink",
    "lightpink",
    "darkgreen",
    "magenta",
    "bisque",
    "lightskyblue",
    "thistle",
    "plum",
    "khaki",
    "coral",
    "turquoise",
    "mediumpurple",
    "darkslateblue",
    "darkkhaki",
    "lightmediumblue", // (Non X11, but that won't be a problem)
    "saddlebrown",
    "firebrick",
    "limegreen"
};

#ifdef X11

/*************************************************
 *     X-Windows Specific File-scope Variables   *
 *************************************************/

// Stores all state variables for X Windows
t_x11_state x11_state;

#endif /* X11 file scope variables */

#ifdef WIN32

/*****************************************************
 *  Microsoft Windows (Win32) File Scope Variables   *
 *****************************************************/

/* Linestyle references for Win32. */
static const int win32_line_styles[2] = {PS_SOLID, PS_DASH};

/* Name of each window */
static wchar_t szAppName[256], szGraphicsName[] = L"VPR Graphics",
    szStatusName[] = L"VPR Status", szButtonsName[] = L"VPR Buttons";

/* Stores all state variables for Win32 */
static t_win32_state win32_state {false, WINDOW_DEACTIVATED, -1};
#endif /* WIN32 file scope variables */


/*********************************************
 *       Common Subroutine Declarations      *
 *********************************************/

static void *my_malloc(int ibytes);
static void *my_realloc(void *memblk, int ibytes);

/* translation from screen coordinates to the world coordinates *
 * used by the client program.                                  */
static float xscrn_to_world(int x);
static float yscrn_to_world(int y);

/* translation from world to screen coordinates */
static int xworld_to_scrn(float worldx);
static int yworld_to_scrn(float worldy);
static float xworld_to_scrn_fl(float worldx); // without rounding to nearest pixel
static float yworld_to_scrn_fl(float worldy);
static float xrad_to_scrn (float xrad);
static float yrad_to_scrn (float yrad);

/* translation from world to PostScript coordinates */
static float x_to_post(float worldx);
static float y_to_post(float worldy);

static void force_setcolor(int cindex);
static void force_setcolor(const t_color& new_color);
static void update_brushes();
static void force_setlinestyle(int linestyle, int capstyle = 1);	// <Modification> as #define CapButt 1 in X.h
static void force_setlinewidth(int linewidth);
static void force_settextattrs(int pointsize, int degrees);

// <Modification>
#ifndef WIN32
static bool use_cairo();
#endif

static void reset_common_state();
static void build_default_menu();

/* Function declarations for button responses */
static void translate_up(void (*drawscreen) ());
static void translate_left(void (*drawscreen) ());
static void translate_right(void (*drawscreen) ());
static void translate_down(void (*drawscreen) ());
static void panning_execute(int x, int y, void (*drawscreen) ());
static void panning_on(int start_x, int start_y);
static void panning_off();
static void zoom_in(void (*drawscreen) ());
static void zoom_out(void (*drawscreen) ());
static void handle_zoom_in(float x, float y, void (*drawscreen) ());
static void handle_zoom_out(float x, float y, void (*drawscreen) ());
static void zoom_fit(void (*drawscreen) ());
static void adjustwin(void (*drawscreen) ());
static void postscript(void (*drawscreen) ());
static void proceed(void (*drawscreen) ());
static void quit(void (*drawscreen) ());
static void map_button(int bnum);
static void unmap_button(int bnum);

static bool is_droppable_event(
#ifdef X11
    const XEvent* event
#elif defined WIN32
    MSG* message
#endif
    );

#ifdef X11


//Returns 'orig_value' merged with 'new_value' based on 'new_mask'.
//Note that 'new_value' will be shifted (according to 'new_mask') before being merged
static unsigned long shift_merge_based_on_mask(unsigned long orig_value, unsigned long new_value, unsigned long new_mask);

//Returns the index of the first set bit in 'mask'
static unsigned long find_first_set(unsigned long mask);

/****************************************************
 *     X-Windows Specific Subroutine Declarations    *
 *****************************************************/

/* Helper functions for X11; not visible to client program. */
static void x11_init_graphics(const char* window_name);
static void init_cairo();
static void x11_event_loop(void (*act_on_mousebutton)
    (float x, float y, t_event_buttonPressed button_info),
    void (*act_on_mousemove)(float x, float y),
    void (*act_on_keypress)(char key_pressed, int keysym),
    void (*drawscreen) ());

static bool x11_drop_redundant_panning (const XEvent& report,
               unsigned int& last_skipped_button_press_button);
static void x11_redraw_all_if_needed (void (*drawscreen) ());
static Bool x11_test_if_exposed(Display *disp, XEvent *event_ptr,
    XPointer dummy);
static void x11_build_textarea();
static void x11_drawbut(int bnum);
static int x11_which_button(Window win);

static void x11_turn_on_off(int pressed);
static void x11_drawmenu();
static void menutext(XftDraw* draw, int xc, int yc, const char *text);

static void x11_handle_expose(const XEvent& report, void (*drawscreen) ());
static void x11_handle_configure_notify(const XEvent& report, void (*drawscreen) ());
static void x11_handle_button_info(t_event_buttonPressed *button_info,
    int buttonNumber, int Xbutton_state);

static unsigned long x11_convert_to_xcolor (t_color color);

#endif /* X11 Declarations */

#ifdef WIN32

/*******************************************************************
 *    Win32-specific subroutine declarations                       *
 *******************************************************************/

/* Helper function called by init_graphics(). Not visible to client program. */
static void win32_init_graphics(const char* window_name);

/* Callback functions for the top-level window and 3 sub-windows.
 * Windows uses an odd mix of events and callbacks, so it needs these.
 */
static LRESULT CALLBACK WIN32_GraphicsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WIN32_StatusWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WIN32_ButtonsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK WIN32_MainWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

// For Win32, need to save pointers to these callback functions at file
// scope, since windows has a bizarre event loop structure where you poll
// for events, but then dispatch the event and get  called via a callback
// from windows (WIN32_GraphicsWND, below).  I can't figure out why windows
// does things this way, but it is what makes saving these function pointers
// necessary.  VB.
static void (*win32_mouseclick_ptr)(float x, float y, t_event_buttonPressed button_info);
static void (*win32_mousemove_ptr)(float x, float y);
static void (*win32_keypress_ptr)(char entered_char, int keysym);
static void (*win32_drawscreen_ptr)(void);

// Helper functions for WIN32_GraphicsWND callback function
static void win32_GraphicsWND_handle_WM_PAINT(HWND hwnd, PAINTSTRUCT &ps, HPEN &hDotPen,
    RECT &oldAdjustRect);
static void win32_GraphicsWND_handle_WM_LRBUTTONDOWN(UINT message, WPARAM wParam, LPARAM lParam,
    int &X, int &Y, RECT &oldAdjustRect);
static void win32_GraphicsWND_handle_WM_MBUTTONDOWN(HWND hwnd, UINT message, WPARAM wParam,
    LPARAM lParam);
static void win32_GraphicsWND_handle_WM_MOUSEMOVE(LPARAM lParam, int &X, int &Y,
    RECT &oldAdjustRect);

// Functions for displaying errors in a message box on windows.
static void WIN32_SELECT_ERROR();
static void WIN32_CREATE_ERROR();
static void WIN32_DRAW_ERROR();

static void win32_invalidate_screen();

static void win32_reset_state();
static void win32_drain_message_queue();

static void win32_handle_mousewheel_zooming(WPARAM wParam, LPARAM lParam, bool draw_screen);
static void win32_handle_button_info(t_event_buttonPressed &button_info, UINT message,
    WPARAM wParam);

COLORREF convert_to_win_color(const t_color& src);

#endif /* Win32 Declarations */


/*********************************************************
 *          Common Subroutine Definitions                *
 *********************************************************/

/* safer malloc */
static void *my_malloc(int ibytes) {
    void *mem;

    mem = static_cast<void*> (malloc(ibytes));
    if (mem == nullptr) {
        printf("memory allocation failed!");
        exit(-1);
    }

    return mem;
}

/* safer realloc */
static void *my_realloc(void *memblk, int ibytes) {
    void *mem;

    mem = static_cast<void*> (realloc(memblk, ibytes));
    if (mem == nullptr) {
        printf("memory allocation failed!");
        exit(-1);
    }

    return mem;
}

/* translation from screen coordinates to the world coordinates *
 * in the x direction.											*/
static float xscrn_to_world(int x) {
    float world_coord_x;
    world_coord_x = x * trans_coord.stow_xmult + trans_coord.xleft;

    return world_coord_x;
}

/* translation from screen coordinates to the world coordinates *
 * in the y direction.											*/
static float yscrn_to_world(int y) {
    float world_coord_y;
    world_coord_y = y * trans_coord.stow_ymult + trans_coord.ytop;

    return world_coord_y;
}

t_point scrn_to_world(const t_point& point) {
    return t_point(
        xscrn_to_world(point.x),
        yscrn_to_world(point.y)
    );
}

t_bound_box scrn_to_world(const t_bound_box& box) {
    return t_bound_box(
        scrn_to_world(box.bottom_left()),
        scrn_to_world(box.top_right())
    );
}

/* Translates from world (client program) coordinates to screen coordinates
 * (pixels) in the x direction.  Add 0.5 at end for extra half-pixel accuracy.
 */
static int xworld_to_scrn(float worldx) {
    return static_cast<int> (xworld_to_scrn_fl(worldx) + 0.5);
}

static float xworld_to_scrn_fl(float worldx) {
    if (gl_state.currentcoordinatesystem == GL_SCREEN) return worldx;

    float winx;

    winx = (worldx - trans_coord.xleft) * trans_coord.wtos_xmult;

    /* Avoids overflow in the X11/Win32  routines.  This will allow horizontal
     * and vertical lines to be drawn correctly regardless of zooming, but   *
     * will cause diagonal lines that go way off screen to change their      *
     * slope as you zoom in.  The only way I can think of to completely fix  *
     * this problem is to do all the clipping in advance in floating point,  *
     * then convert to integers and call   Windows.  This is a lot of extra  *
     * coding, and means that coordinates will be clipped twice, even though *
     * this "Super Zoom" problem won't occur unless users zoom way in on     *
     * the graphics.                                                         */

    winx = max(winx, MINPIXEL);
    winx = min(winx, MAXPIXEL);

    return (winx);
}

/* Translates from world (client program) coordinates to screen coordinates
 * (pixels) in the y direction.  Add 0.5 at end for extra half-pixel accuracy.
 */
static int yworld_to_scrn(float worldy) {
    return static_cast<int> (yworld_to_scrn_fl(worldy) + 0.5);
}

static float yworld_to_scrn_fl(float worldy) {
    if (gl_state.currentcoordinatesystem == GL_SCREEN) return worldy;

    float winy;

    winy = (worldy - trans_coord.ytop) * trans_coord.wtos_ymult;

    /* Avoid overflow in the X/Win32 Window routines. */
    winy = max(winy, MINPIXEL);
    winy = min(winy, MAXPIXEL);

    return (winy);
}

t_point world_to_scrn(const t_point& point) {
    return t_point(
        xworld_to_scrn_fl(point.x),
        yworld_to_scrn_fl(point.y)
        );
}

t_bound_box world_to_scrn(const t_bound_box& box) {
    return t_bound_box(
        world_to_scrn(box.bottom_left()),
        world_to_scrn(box.top_right())
        );
}


// Convert an x-directed radius to screen coordinates (for arc drawing)
static float xrad_to_scrn (float xrad) {
    if (gl_state.currentcoordinatesystem == GL_SCREEN) {
        return xrad;
    }
    else {
        return (fabs (xrad * trans_coord.wtos_xmult));
    }
}


// Convert an y-directed radius to screen coordinates (for arc drawing)
static float yrad_to_scrn (float yrad) {
    if (gl_state.currentcoordinatesystem == GL_SCREEN) {
        return yrad;
    }
    else {
        return (fabs (yrad * trans_coord.wtos_ymult));
    }
}


/* translation from world or screen coords to PostScript coordinates in the x direction */
static float x_to_post(float x) {
    float ps_coord_x;
    if (gl_state.currentcoordinatesystem == GL_WORLD)
       ps_coord_x = (x - trans_coord.xleft) * trans_coord.ps_xmult + trans_coord.ps_left;
    else
        ps_coord_x = x * trans_coord.s_to_ps_xmult + trans_coord.ps_left;  // Screen coordinate left is at 0

    return ps_coord_x;
}

/* translation from world or screen coords to PostScript coordinates in the y direction */
static float y_to_post(float y) {
    float ps_coord_y;
    if (gl_state.currentcoordinatesystem == GL_WORLD)
       ps_coord_y = (y - trans_coord.ybot) * trans_coord.ps_ymult + trans_coord.ps_bot;
    else
        ps_coord_y = trans_coord.ps_top + y * trans_coord.s_to_ps_ymult; // Screen coordinate top is at 0

    return ps_coord_y;
}

#ifndef WIN32
static bool use_cairo()
{
    return (gl_state.foreground_color.alpha != 255);
}
#endif

/* Sets the current graphics context colour to cindex, regardless of whether we think it is
 * needed or not.
 */
static void force_setcolor(int cindex) {
    gl_state.foreground_color = t_color::predef_colors[cindex];
    update_brushes();
}

static void force_setcolor(const t_color& new_color) {
    gl_state.foreground_color = new_color;
    update_brushes();
}

static void update_brushes() {
    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        if (gl_state.foreground_color.alpha != 255)
        {
            cairo_set_source_rgba(x11_state.ctx,
                static_cast<double>(gl_state.foreground_color.red)/255,
                static_cast<double>(gl_state.foreground_color.green)/255,
                static_cast<double>(gl_state.foreground_color.blue)/255,
                static_cast<double>(gl_state.foreground_color.alpha)/255);
        }
        else
        {
            XSetForeground(
                x11_state.display,
                x11_state.current_gc,
                x11_convert_to_xcolor(gl_state.foreground_color)
                );
        }
        XRenderColor xr_textcolor;
        xr_textcolor.red = (gl_state.foreground_color.red << 8);
        xr_textcolor.green = (gl_state.foreground_color.green << 8);
        xr_textcolor.blue = (gl_state.foreground_color.blue << 8);
        xr_textcolor.alpha = (gl_state.foreground_color.alpha << 8);
        XftColorAllocValue(
            x11_state.display,
            x11_state.visual_info.visual,
            x11_state.colormap_to_use,
            &xr_textcolor,
            &x11_state.xft_currentcolor
            );
#else /* Win32 */
        int win_linestyle, linewidth;
        LOGBRUSH lb;
        lb.lbStyle = BS_SOLID;
        lb.lbColor = convert_to_win_color(gl_state.foreground_color);
        lb.lbHatch = (LONG) NULL;
        win_linestyle = win32_line_styles[gl_state.currentlinestyle];
        linewidth = max(gl_state.currentlinewidth, 1); // Win32 won't draw 0 width dashed lines.

        /* Delete previously used pen */
        if (!DeleteObject(win32_state.hGraphicsPen))
            WIN32_DELETE_ERROR();
        /* Create a new pen */
        win32_state.hGraphicsPen = ExtCreatePen(PS_GEOMETRIC | win_linestyle |
            PS_ENDCAP_FLAT, linewidth, &lb, (LONG) NULL, NULL);
        if (!win32_state.hGraphicsPen)
            WIN32_CREATE_ERROR();
        /* Select created pen into specified device context */
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsPen))
            WIN32_SELECT_ERROR();

        /* Delete previously used brush */
        if (!DeleteObject(win32_state.hGraphicsBrush))
            WIN32_DELETE_ERROR();
        /* Create a new brush */
        win32_state.hGraphicsBrush = CreateSolidBrush(
            convert_to_win_color(gl_state.foreground_color)
            );
        if (!win32_state.hGraphicsBrush)
            WIN32_CREATE_ERROR();
        /* Select created brush into specified device context */
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsBrush))
            WIN32_SELECT_ERROR();
#endif
    } else {
        auto color_index = std::find(
            t_color::predef_colors.begin(),
            t_color::predef_colors.end(),
            gl_state.foreground_color
            );
        if (color_index != t_color::predef_colors.end()) {
            fprintf(gl_state.ps, "%s\n", ps_cnames[color_index - t_color::predef_colors.begin()]);
        } else {
            fprintf(
                gl_state.ps,
                "%f %f %f setrgbcolor\n",
                gl_state.foreground_color.red / static_cast<float>(0xFF),
                gl_state.foreground_color.green / static_cast<float>(0xFF),
                gl_state.foreground_color.blue / static_cast<float>(0xFF)
                );
        }
    }
}

/* Sets the current graphics context colour to cindex if it differs from the old colour */
void setcolor(int cindex) {
    if (gl_state.foreground_color != t_color::predef_colors[cindex]) {
        force_setcolor(cindex);
    }
}

void setcolor(const t_color& color) {
    if (gl_state.foreground_color != color) {
        force_setcolor(color);
    }
}

void setcolor(uint_fast8_t r, uint_fast8_t g, uint_fast8_t b, uint_fast8_t a) {
    setcolor(t_color(r, g, b, a));
}

/* Sets the current graphics context color to the index that corresponds to the
 * string name passed in.  Slower, but maybe more convenient for simple
 * client code.
 */
void setcolor_by_name(string cname) {
    int icolor = -1;
    for (int i = 0; i < NUM_COLOR; i++) {
        if (cname == ps_cnames[i]) {
            icolor = i;
            break;
        }
    }
    if (icolor == -1) {
        cout << "Error: unknown color " << cname << endl;
    } else {
        setcolor(icolor);
    }
}

t_color getcolor() {
    return gl_state.foreground_color;
}

/* Sets the current linestyle to linestyle in the graphics context.
 * Note SOLID is 0 and DASHED is 1 for linestyle.
 * capstyle can be 0 (butt), or 1 (round)
 */
static void force_setlinestyle(int linestyle, int capstyle) {
    gl_state.currentlinestyle = linestyle;
    gl_state.currentlinecap = capstyle;

    if (gl_state.disp_type == SCREEN) {

#ifdef X11
        // XLIB DASH AND CAP
        static int x_vals[2] = {LineSolid, LineOnOffDash};
        XSetLineAttributes(x11_state.display, x11_state.current_gc, gl_state.currentlinewidth,
            x_vals[linestyle], capstyle == 0 ? CapButt : CapRound, JoinMiter);

        // CAIRO DASH
        static double dashes[] = {
            5.0,  /* ink */
            3.0,  /* skip */
        };
        if (linestyle == 1)
        {
            cairo_set_dash(x11_state.ctx, dashes, 2, 0);
        }
        else
        {
            cairo_set_dash(x11_state.ctx, dashes, 0, 0);
        }
        // CAIRO CAP
        if (capstyle == 0)
        {
            cairo_set_line_cap(x11_state.ctx, CAIRO_LINE_CAP_BUTT);
        }
        else
        {
            cairo_set_line_cap(x11_state.ctx, CAIRO_LINE_CAP_ROUND);
        }
#else  // Win32
        LOGBRUSH lb;
        lb.lbStyle = BS_SOLID;
        lb.lbColor = convert_to_win_color(gl_state.foreground_color);
        lb.lbHatch = (LONG) NULL;
        int win_linestyle = win32_line_styles[linestyle];
        /* Win32 won't draw 0 width dashed lines. */
        int linewidth = max(gl_state.currentlinewidth, 1);

        /* Delete previously used pen */
        if (!DeleteObject(win32_state.hGraphicsPen))
            WIN32_DELETE_ERROR();
        /* Create a new pen */
        win32_state.hGraphicsPen = ExtCreatePen(PS_GEOMETRIC | win_linestyle |
            PS_ENDCAP_FLAT, linewidth, &lb, (LONG) NULL, NULL);
        if (!win32_state.hGraphicsPen)
            WIN32_CREATE_ERROR();
        /* Select created pen into specified device context */
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsPen))
            WIN32_SELECT_ERROR();
#endif
    } else {
        if (linestyle == SOLID)
            fprintf(gl_state.ps, "linesolid\n");
        else if (linestyle == DASHED)
            fprintf(gl_state.ps, "linedashed\n");
        else {
            printf("Error: invalid linestyle: %d\n", linestyle);
            exit(1);
        }
    }
}

/* Change the linestyle in the graphics context only if it differs from the current
 * linestyle.
 */
void setlinestyle(int linestyle, int capstyle) {
    if (linestyle != gl_state.currentlinestyle || capstyle != gl_state.currentlinecap)
        force_setlinestyle(linestyle, capstyle);
}

/* Sets current linewidth in the graphics context.
 * linewidth should be greater than or equal to 0 to make any sense.
 */
static void force_setlinewidth(int linewidth) {
    gl_state.currentlinewidth = linewidth;

    if (gl_state.disp_type == SCREEN) {

#ifdef X11
        // X11
        static int x_vals[2] = {LineSolid, LineOnOffDash};
        XSetLineAttributes(x11_state.display, x11_state.current_gc, linewidth,
            x_vals[gl_state.currentlinestyle], gl_state.currentlinecap == 0 ? CapButt : CapRound, JoinMiter);

        // CAIRO
        cairo_set_line_width(x11_state.ctx, linewidth);
#else /* Win32 */
        LOGBRUSH lb;
        lb.lbStyle = BS_SOLID;
        lb.lbColor = convert_to_win_color(gl_state.foreground_color);
        lb.lbHatch = (LONG) NULL;
        int win_linestyle = win32_line_styles[gl_state.currentlinestyle];

        if (linewidth == 0)
            linewidth = 1; // Win32 won't draw dashed 0 width lines.

        /* Delete previously used pen */
        if (!DeleteObject(win32_state.hGraphicsPen))
            WIN32_DELETE_ERROR();
        /* Create a new pen */
        win32_state.hGraphicsPen = ExtCreatePen(PS_GEOMETRIC | win_linestyle |
            PS_ENDCAP_FLAT, linewidth, &lb, (LONG) NULL, NULL);
        if (!win32_state.hGraphicsPen)
            WIN32_CREATE_ERROR();
        /* Select created pen into specified device context */
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsPen))
            WIN32_SELECT_ERROR();
#endif
    } else {
        fprintf(gl_state.ps, "%d setlinewidth\n", linewidth);
    }
}

/* Sets the linewidth in the grahpics context, if it differs from the current value.
 */
void setlinewidth(int linewidth) {
    if (linewidth != gl_state.currentlinewidth)
        force_setlinewidth(linewidth);
}

/* Force the selected fontsize to be applied to the graphics context,
 * whether or not it appears to match the current fontsize. This is necessary
 * when switching between postscript and window out, for example.
 * Valid point sizes are between 1 and MAX_FONT_SIZE.
 */
static void force_settextattrs(int pointsize, int degrees) {

    if (pointsize < 1)
        pointsize = 1;

    gl_state.currentfontsize = pointsize;
    gl_state.currentfontrotation = degrees;

    if (gl_state.disp_type == SCREEN) {
#ifdef WIN32
        if (win32_state.hGraphicsFont != NULL) {
            /* Delete previously used font */
            if (!DeleteObject(win32_state.hGraphicsFont)) {
                WIN32_DELETE_ERROR();
            }
        }
        win32_state.hGraphicsFont = NULL; // expected by drawtext(..)
#endif
    } else {
        fprintf(gl_state.ps, "%d setfontsize\n", pointsize);
    }
}

/* For efficiency, these routines doesn't do anything if no change is
 * implied.  If you want to force the graphics context or PS file
 * to have font info set, call force_settextattrs (this is necessary
 * in initialization and screen / Postscript switches).
 */
void setfontsize(int pointsize) {
    if (pointsize != gl_state.currentfontsize) {
        force_settextattrs(pointsize, gl_state.currentfontrotation);
    }
}

int getfontsize() {
    return gl_state.currentfontsize;
}

void settextrotation(int degrees) {
    if (degrees != gl_state.currentfontrotation) {
        force_settextattrs(gl_state.currentfontsize, degrees);
    }
}

int gettextrotation() {
    return gl_state.currentfontrotation;
}

void settextattrs(int pointsize, int degrees) {
    if (degrees != gl_state.currentfontrotation
        || pointsize != gl_state.currentfontsize) {
        force_settextattrs(pointsize, degrees);
    }
}

/* Puts a triangle in the poly array for button[bnum]. Haven't made this work for
 * win32 yet and instead put "U", "D" excetra on the arrow buttons.
 * VB To-do: make work for win32 someday.
 */
#ifdef X11

static void setpoly(int bnum, int xc, int yc, int r, float theta) {
    int i;

    button_state.button[bnum].type = BUTTON_POLY;
    for (i = 0; i < 3; i++) {
        button_state.button[bnum].poly[i][0] = xc + r * cos(theta) + 0.5;
        button_state.button[bnum].poly[i][1] = yc + r * sin(theta) + 0.5;
        theta += 2. * PI / 3.;
    }
}
#endif // X11

/* Maps a button onto the screen and set it up for input, etc.        */
static void map_button(int bnum) {
    button_state.button[bnum].ispressed = false;

    if (button_state.button[bnum].type != BUTTON_SEPARATOR) {
#ifdef X11
        button_state.button[bnum].win = XCreateSimpleWindow(
            x11_state.display, x11_state.menu,
            button_state.button[bnum].xleft,
            button_state.button[bnum].ytop,
            button_state.button[bnum].width,
            button_state.button[bnum].height, 0,
            x11_convert_to_xcolor(t_color::predef_colors[WHITE]),
            x11_convert_to_xcolor(t_color::predef_colors[LIGHTGREY])
            );

        XMapWindow(x11_state.display, button_state.button[bnum].win);
        XSelectInput(x11_state.display, button_state.button[bnum].win, ButtonPressMask);
        button_state.button[bnum].draw = XftDrawCreate(
            x11_state.display,
            button_state.button[bnum].win,
            x11_state.visual_info.visual,
            x11_state.colormap_to_use
            );
#else
        wchar_t* WIN32_wchar_button_text = new wchar_t[BUTTON_TEXT_LEN];
        MultiByteToWideChar(CP_UTF8, 0, button_state.button[bnum].text, -1,
            WIN32_wchar_button_text, BUTTON_TEXT_LEN);
        button_state.button[bnum].hwnd = CreateWindowW(
            L"button",
            WIN32_wchar_button_text,
            WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            button_state.button[bnum].xleft,
            button_state.button[bnum].ytop,
            button_state.button[bnum].width,
            button_state.button[bnum].height,
            win32_state.hButtonsWnd,
			(HMENU) (200 + (intptr_t) bnum),
            (HINSTANCE) GetWindowLongPtr(win32_state.hMainWnd, GWLP_HINSTANCE),
            NULL
            );

        delete[] WIN32_wchar_button_text;

        if (!InvalidateRect(win32_state.hButtonsWnd, NULL, TRUE))
            WIN32_DRAW_ERROR();
        if (!UpdateWindow(win32_state.hButtonsWnd))
            WIN32_DRAW_ERROR();
#endif
    } else { // Separator, not a button.
#ifdef X11
        button_state.button[bnum].win = -1;
#else // WIN32
        button_state.button[bnum].hwnd = NULL;
        if (!InvalidateRect(win32_state.hButtonsWnd, NULL, TRUE))
            WIN32_DRAW_ERROR();
        if (!UpdateWindow(win32_state.hButtonsWnd))
            WIN32_DRAW_ERROR();
#endif
    }
}

static void unmap_button(int bnum) {
    /* Unmaps (removes) a button from the screen.        */
    if (button_state.button[bnum].type != BUTTON_SEPARATOR) {
#ifdef X11
        XUnmapWindow(x11_state.display, button_state.button[bnum].win);
        XftDrawDestroy(button_state.button[bnum].draw);
#else
        if (!DestroyWindow(button_state.button[bnum].hwnd))
            WIN32_DRAW_ERROR();
        if (!InvalidateRect(win32_state.hButtonsWnd, NULL, TRUE))
            WIN32_DRAW_ERROR();
        if (!UpdateWindow(win32_state.hButtonsWnd))
            WIN32_DRAW_ERROR();
#endif
    }
}

/* Creates a new button below the button containing prev_button_text.       *
 * The text and button function are set according to button_text and        *
 * button_func, respectively.                                               */
void create_button(const char *prev_button_text, const char *button_text,
    void (*button_func) (void (*drawscreen) ())) {
    int i, bnum, space, bheight;
    t_button_type button_type = BUTTON_TEXT;


    space = 8;

    /* Only allow new buttons that are text or separator (not poly) types.
     * They can also only go after buttons that are text buttons.
     */

    bnum = -1;

    for (i = 0; i < button_state.num_buttons; i++) {
        if (button_state.button[i].type == BUTTON_TEXT &&
            strcmp(button_state.button[i].text, prev_button_text) == 0) {
            bnum = i + 1;
            break;
        }
    }

    if (bnum == -1) {
        printf("Error in create_button:  button with text %s not found.\n",
            prev_button_text);
        exit(1);
    }

    button_state.button = static_cast<t_button *> (my_realloc(button_state.button,
        (button_state.num_buttons + 1) * sizeof (t_button)));
    /* NB:  Requirement that you specify the button that this button goes under *
     * guarantees that button[num_buttons-2] exists and is a text button.       */

    /* Special string to make a separator. */
    if (!strncmp(button_text, "---", 3)) {
        bheight = 2;
        button_type = BUTTON_SEPARATOR;
    } else
        bheight = 26;

    for (i = button_state.num_buttons; i > bnum; i--) {
        button_state.button[i].xleft = button_state.button[i - 1].xleft;
        button_state.button[i].ytop = button_state.button[i - 1].ytop + bheight + space;
        button_state.button[i].height = button_state.button[i - 1].height;
        button_state.button[i].width = button_state.button[i - 1].width;
        button_state.button[i].type = button_state.button[i - 1].type;
        strcpy(button_state.button[i].text, button_state.button[i - 1].text);
        button_state.button[i].fcn = button_state.button[i - 1].fcn;
        button_state.button[i].ispressed = button_state.button[i - 1].ispressed;
        button_state.button[i].enabled = button_state.button[i - 1].enabled;
        unmap_button(i - 1);
    }

    i = bnum;
    button_state.button[i].xleft = 6;
    button_state.button[i].ytop = button_state.button[i - 1].ytop + button_state.button[i - 1].height
        + space;
    button_state.button[i].height = bheight;
    button_state.button[i].width = 90;
    button_state.button[i].type = button_type;
    strncpy(button_state.button[i].text, button_text, BUTTON_TEXT_LEN);
    button_state.button[i].text[BUTTON_TEXT_LEN-1] = '\0'; //Ensure null termination
    button_state.button[i].fcn = button_func;
    button_state.button[i].ispressed = false;
    button_state.button[i].enabled = true;

    button_state.num_buttons++;

    for (; i < button_state.num_buttons; i++)
        map_button(i);
}

/* Destroys the button with text button_text. */
void
destroy_button(const char *button_text) {
    int i, bnum, space, bheight;

    bnum = -1;
    space = 8;
    for (i = 0; i < button_state.num_buttons; i++) {
        if (button_state.button[i].type == BUTTON_TEXT &&
            strcmp(button_state.button[i].text, button_text) == 0) {
            bnum = i;
            break;
        }
    }

    if (bnum == -1) {
        printf("Error in destroy_button:  button with text %s not found.\n",
            button_text);
        exit(1);
    }

    bheight = button_state.button[bnum].height;

    unmap_button(bnum);
    for (i = bnum + 1; i < button_state.num_buttons; i++) {
        button_state.button[i - 1].xleft = button_state.button[i].xleft;
        button_state.button[i - 1].ytop = button_state.button[i].ytop - bheight - space;
        button_state.button[i - 1].height = button_state.button[i].height;
        button_state.button[i - 1].width = button_state.button[i].width;
        button_state.button[i - 1].type = button_state.button[i].type;
        strcpy(button_state.button[i - 1].text, button_state.button[i].text);
        button_state.button[i - 1].fcn = button_state.button[i].fcn;
        button_state.button[i - 1].ispressed = button_state.button[i].ispressed;
        button_state.button[i - 1].enabled = button_state.button[i].enabled;
        unmap_button(i);
    }

    button_state.button = static_cast<t_button *> (my_realloc(button_state.button,
        (button_state.num_buttons - 1) * sizeof (t_button)));

    button_state.num_buttons--;

    for (i = bnum; i < button_state.num_buttons; i++)
        map_button(i);
}

/* Open the toplevel window, get the colors, 2 graphics         *
 * contexts, load a font, and set up the toplevel window        *
 * Calls build_default_menu to set up the default menu.         */
void
init_graphics(const std::string& window_name, int cindex) {
    init_graphics(window_name, t_color::predef_colors[cindex]);
}


void init_graphics(const std::string& window_name, const t_color& background) {
    if (gl_state.initialized) // Singleton graphics.
        return;

    reset_common_state();

    gl_state.disp_type = SCREEN;
    gl_state.background_color = background;

    // The Win32 and X11 APIs use C-strings.
    const char* cstring_window_name = window_name.c_str();

#ifdef X11
    x11_init_graphics(cstring_window_name);
#else /* WIN32 */
    win32_init_graphics(cstring_window_name);
#endif

    gl_state.initialized = true;
}

void change_graphics_background(const t_color & background)
{
	gl_state.background_color = background;
}

static void reset_common_state() {
    gl_state.foreground_color = t_color::predef_colors[BLACK];
    gl_state.currentlinestyle = SOLID;
    gl_state.currentlinewidth = 0;
    gl_state.currentfontsize = 12;
    gl_state.currentfontrotation = 0;
    gl_state.current_draw_to = ON_SCREEN;
    gl_state.current_draw_mode = DRAW_NORMAL;
    gl_state.font_info.clear();
    gl_state.ProceedPressed = false;
    gl_state.get_keypress_input = false;
    gl_state.get_mouse_move_input = false;
    gl_state.redraw_needed = false;

#ifdef WIN32
    win32_reset_state();
#endif
}


static void
update_transform() {
    /* Set up the factors for transforming from the user world to X/Win32 screen
     * (pixel) coordinates.                                                         */

    float mult, diff, y1, y2, x1, x2;

    /* X Window coordinates go from (0,0) to (width-1,height-1) */
    diff = trans_coord.xright - trans_coord.xleft;
    trans_coord.wtos_xmult = (trans_coord.top_width - 1 - MWIDTH) / diff;
    diff = trans_coord.ybot - trans_coord.ytop;
    trans_coord.wtos_ymult = (trans_coord.top_height - 1 - T_AREA_HEIGHT) / diff;

    /* Need to use same scaling factor to preserve aspect ratio */
    if (fabs(trans_coord.wtos_xmult) <= fabs(trans_coord.wtos_ymult)) {
        mult = fabs(trans_coord.wtos_ymult / trans_coord.wtos_xmult);
        y1 = trans_coord.ytop - (trans_coord.ybot - trans_coord.ytop)*(mult - 1) / 2;
        y2 = trans_coord.ybot + (trans_coord.ybot - trans_coord.ytop)*(mult - 1) / 2;
        trans_coord.ytop = y1;
        trans_coord.ybot = y2;
    } else {
        mult = fabs(trans_coord.wtos_xmult / trans_coord.wtos_ymult);
        x1 = trans_coord.xleft - (trans_coord.xright - trans_coord.xleft)*(mult - 1) / 2;
        x2 = trans_coord.xright + (trans_coord.xright - trans_coord.xleft)*(mult - 1) / 2;
        trans_coord.xleft = x1;
        trans_coord.xright = x2;
    }
    diff = trans_coord.xright - trans_coord.xleft;
    trans_coord.wtos_xmult = (trans_coord.top_width - 1 - MWIDTH) / diff;
    diff = trans_coord.ybot - trans_coord.ytop;
    trans_coord.wtos_ymult = (trans_coord.top_height - 1 - T_AREA_HEIGHT) / diff;

    trans_coord.stow_xmult = 1 / trans_coord.wtos_xmult;
    trans_coord.stow_ymult = 1 / trans_coord.wtos_ymult;
}


static void
update_ps_transform() {

    /* Postscript coordinates start at (0,0) for the lower left hand corner *
     * of the page and increase upwards and to the right.  For 8.5 x 11     *
     * sheet, coordinates go from (0,0) to (612,792).  Spacing is 1/72 inch.*
     * I'm leaving a minimum of half an inch (36 units) of border around    *
     * each edge.                                                           */

    float mult, ps_width, ps_height;

    ps_width = 540.; /* 72 * 7.5 */
    ps_height = 720.; /* 72 * 10  */

    trans_coord.ps_xmult = ps_width / (trans_coord.xright - trans_coord.xleft);
    trans_coord.ps_ymult = ps_height / (trans_coord.ytop - trans_coord.ybot);
    /* Need to use same scaling factor to preserve aspect ratio.   *
     * I show exactly as much on paper as the screen window shows, *
     * or the user specifies.                                      */
    if (fabs(trans_coord.ps_xmult) <= fabs(trans_coord.ps_ymult)) {
        trans_coord.ps_left = 36.;
        trans_coord.ps_right = 36. + ps_width;
        mult = fabs(trans_coord.ps_xmult * (trans_coord.ytop - trans_coord.ybot));
        trans_coord.ps_bot = 396. - mult / 2.;
        mult = fabs(trans_coord.ps_xmult * (trans_coord.ytop - trans_coord.ybot));
        trans_coord.ps_top = 396. + mult / 2.;
        /* Maintain aspect ratio but watch signs */
        trans_coord.ps_ymult = (trans_coord.ps_xmult * trans_coord.ps_ymult < 0) ?
            -trans_coord.ps_xmult : trans_coord.ps_xmult;
    } else {
        trans_coord.ps_bot = 36.;
        trans_coord.ps_top = 36. + ps_height;
        mult = fabs(trans_coord.ps_ymult * (trans_coord.xright - trans_coord.xleft));
        trans_coord.ps_left = 306. - mult / 2.;
        mult = fabs(trans_coord.ps_ymult * (trans_coord.xright - trans_coord.xleft));
        trans_coord.ps_right = 306. + mult / 2.;
        /* Maintain aspect ratio but watch signs */
        trans_coord.ps_xmult = (trans_coord.ps_xmult * trans_coord.ps_ymult < 0) ?
            -trans_coord.ps_ymult : trans_coord.ps_ymult;
    }

    // /The user can also draw in screen coordinates, so we also need a
    // transformation from screen coordinates to postscript.
    trans_coord.s_to_ps_xmult = trans_coord.ps_xmult * trans_coord.stow_xmult;
    trans_coord.s_to_ps_ymult = trans_coord.ps_ymult * trans_coord.stow_ymult;
}


static bool is_droppable_event(
#ifdef X11
    const XEvent* event
#elif defined WIN32
    MSG* message
#endif
    ) {
#ifdef X11
    return
    event->type == MotionNotify || (
        event->type == ButtonPress && (
        event->xbutton.button == Button4 ||
        event->xbutton.button == Button5
        )
        );
#elif defined WIN32
    return message->message == WM_MOUSEWHEEL
        || message->message == WM_MOUSEMOVE;
#endif
}

/* The program's main event loop.  Must be passed a user routine
 * drawscreen which redraws the screen.  It handles all window resizing
 * zooming etc. itself.
 * The three other callbacks are optional -- they can be NULL if you don't
 * want to use them in your program. If non-NULL, they are called when the user
 * clicks a mouse button, moves the mouse or presses the keyboard while the
 * cursor is in the graphics area.
 */
void
event_loop(void (*act_on_mousebutton)(float x, float y, t_event_buttonPressed button_info),
    void (*act_on_mousemove)(float x, float y),
    void (*act_on_keypress)(char key_pressed, int keysym),
    void (*drawscreen) ()) {

    if (drawscreen == nullptr) {
        cerr << "Error in event_loop: drawscreen is NULL, but it is a mandatory callback.\n";
        exit(1);
    }

    // The following settings are useful for automarking in courses.
    if (gl_state.redirect_to_postscript)
        postscript (drawscreen);

    if (gl_state.disable_event_loop)  // Avoids hanging the automarker when students call the event_loop
        return;

#ifdef X11
    x11_event_loop(act_on_mousebutton, act_on_mousemove, act_on_keypress, drawscreen);
#else /* Win32 */

    // For event handling with Win32, need to set these file scope function
    // pointers, then dispatch the event and get called via callbacks from
    // Windows (eg. WIN32_GraphicsWND()). Actual event handling is done
    // in these Win32-specific callback functions.

    MSG msg;

    win32_mouseclick_ptr = act_on_mousebutton;
    win32_mousemove_ptr = act_on_mousemove;
    win32_keypress_ptr = act_on_keypress;
    win32_drawscreen_ptr = drawscreen;
    gl_state.ProceedPressed = false;
    win32_state.InEventLoop = true;

    win32_invalidate_screen();

    // timeout timer, for event loop. Supposed to be 2 seconds, but isn't?
    // UINT_PTR timeout_timer = SetTimer(NULL, NULL, 2000, NULL);

    // Windows event dropping explanation:
    // like X11, it will drop events which match is_droppable_event(...), and
    // are followed by another event which matches is_droppable_event(...).
    // However, there is no way to sync events with the system; no way to make
    // sure that this application has all pending events in it's queue to
    // process. So, hopefully this doesn't cause any problems. Also, due to the
    // fact that windows groups multiple fast scrolls into one message, there
    // is logic in win32_handle_mousewheel_zooming to address this.
    while (!gl_state.ProceedPressed && GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        if (msg.message == WM_CHAR) { // only the top window can get keyboard events
            msg.hwnd = win32_state.hMainWnd;
        }
        if (is_droppable_event(&msg)) {
            MSG next_msg;
            if (PeekMessage(&next_msg, NULL, 0, 0, PM_NOREMOVE)) {
                // if the current event is droppable, check if
                // if the next event is droppable.
                if (is_droppable_event(&next_msg)) {
                    // if both droppable, skip the event.
                    if (msg.message == WM_MOUSEWHEEL) {
                        // if dropping scroll event, do the scroll, but don't redraw.
                        win32_handle_mousewheel_zooming(msg.wParam, msg.lParam, false);
                    }
                    continue;
                }
            }
        }
        DispatchMessage(&msg);
    }
    win32_state.InEventLoop = false;
#endif
}

void
clearscreen() {
    t_color savecolor;
    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        if (x11_state.draw_area == &(x11_state.toplevel)) {
            XClearWindow(x11_state.display, x11_state.toplevel);
        }
        else {
            setcolor(gl_state.background_color);
            XFillRectangle(x11_state.display, x11_state.draw_buffer, x11_state.current_gc, 0, 0,
                    x11_state.attributes.width, x11_state.attributes.height);
        }
#else /* Win32 */
        savecolor = gl_state.foreground_color;
        setcolor(gl_state.background_color);
        fillrect(trans_coord.xleft, trans_coord.ytop,
            trans_coord.xright, trans_coord.ybot);
        setcolor(savecolor);
#endif
    } else { // Postscript
        /* erases current page.  Don't use erasepage, since this will erase *
         * everything, (even stuff outside the clipping path) causing       *
         * problems if this picture is incorporated into a larger document. */
        savecolor = gl_state.foreground_color;
        setcolor(gl_state.background_color);
        fprintf(gl_state.ps, "clippath fill\n\n");
        setcolor(savecolor);
    }
}

/* Return 1 if I can quarantee no part of this rectangle will         *
 * lie within the user drawing area.  Otherwise return 0.             *
 * Note:  this routine is only used to help speed (and to shrink ps   *
 * files) -- it will be highly effective when the graphics are zoomed *
 * in and lots are off-screen.  I don't have to pre-clip for          *
 * correctness.                                                       */
static int
rect_off_screen(float x1, float y1, float x2, float y2) {
    // No pre-clip if you're in screen coordinates; user should know where he/she is
    // drawing that case so not necessary to pre-clip for speed.
    if (gl_state.currentcoordinatesystem == GL_SCREEN)
        return 0;

    float xmin, xmax, ymin, ymax;

    xmin = min(trans_coord.xleft, trans_coord.xright);
    if (x1 < xmin && x2 < xmin)
        return (1);

    xmax = max(trans_coord.xleft, trans_coord.xright);
    if (x1 > xmax && x2 > xmax)
        return (1);

    ymin = min(trans_coord.ytop, trans_coord.ybot);
    if (y1 < ymin && y2 < ymin)
        return (1);

    ymax = max(trans_coord.ytop, trans_coord.ybot);
    if (y1 > ymax && y2 > ymax)
        return (1);

    return (0);
}

static int rect_off_screen(const t_bound_box& bbox) {
    return rect_off_screen(bbox.left(), bbox.bottom(), bbox.right(), bbox.top());
}

t_bound_box get_visible_world() {
    return t_bound_box(
        trans_coord.xleft,
        trans_coord.ybot,
        trans_coord.xright,
        trans_coord.ytop
        );
}

/* Returns the limits of the user-drawable window (graphics area) in screen
 * coordinates.
 */
t_bound_box get_visible_screen() {
    // Screen coordinates are (0,0) at the top left. Top level window goes from
    // 0 to top_width-1 or top_height - 1.
    return (t_bound_box (
            0, trans_coord.top_height - 1 - T_AREA_HEIGHT,
            trans_coord.top_width - 1 - MWIDTH, 0)
            );
}


bool LOD_screen_area_test(t_bound_box test, float screen_area_threshold) {
    return world_to_scrn(test).area() > screen_area_threshold;
}

bool LOD_min_dim_test(float dim_threshold) {
    t_bound_box vis_world = get_visible_world();
    //printf("visible world width = %f, height = %f",vis_world.get_width(),vis_world.get_height());
    return
    (
            (abs(vis_world.get_height()) < abs(vis_world.get_width())) ?
            abs(vis_world.get_height()) : abs(vis_world.get_width())
            ) < dim_threshold;
}

void drawline(const t_point& p1, const t_point& p2) {
    drawline(p1.x, p1.y, p2.x, p2.y);
}

void
drawline(float x1, float y1, float x2, float y2) {
    /* Draw a line from (x1,y1) to (x2,y2) in the user-drawable area. *
     * Coordinates are in world (user) space.                         */

    /* Pre-clipping has been tested on both Windows and Linux, and it was found to be useful *
     * for speeding up drawscreen() runtime.												 */
    if (rect_off_screen(x1, y1, x2, y2))
        return;

    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        /* Xlib.h prototype has x2 and y1 mixed up. */
        if (use_cairo())
        {
            cairo_move_to(x11_state.ctx, xworld_to_scrn(x1), yworld_to_scrn(y1));
            cairo_line_to(x11_state.ctx, xworld_to_scrn(x2), yworld_to_scrn(y2));
            cairo_stroke(x11_state.ctx);
        }
        else
        {
            XDrawLine(x11_state.display, *(x11_state.draw_area), x11_state.current_gc, xworld_to_scrn(x1),
                yworld_to_scrn(y1), xworld_to_scrn(x2), yworld_to_scrn(y2));
        }
#else /* Win32 */
        if (!BeginPath(win32_state.hGraphicsDC))
            WIN32_DRAW_ERROR();
        if (!MoveToEx(win32_state.hGraphicsDC, xworld_to_scrn(x1), yworld_to_scrn(y1), NULL))
            WIN32_DRAW_ERROR();
        if (!LineTo(win32_state.hGraphicsDC, xworld_to_scrn(x2), yworld_to_scrn(y2)))
            WIN32_DRAW_ERROR();
        if (!EndPath(win32_state.hGraphicsDC))
            WIN32_DRAW_ERROR();
        if (!StrokePath(win32_state.hGraphicsDC))
            WIN32_DRAW_ERROR();
#endif
    } else {
        fprintf(gl_state.ps, "%.2f %.2f %.2f %.2f drawline\n", x_to_post(x1), y_to_post(y1),
            x_to_post(x2), y_to_post(y2));
    }
}

void drawrect(const t_bound_box& rect) {
    drawrect(rect.bottom_left(), rect.top_right());
}

void drawrect(const t_point& bottomleft, const t_point& upperright) {
    drawrect(bottomleft.x, bottomleft.y, upperright.x, upperright.y);
}

/* (x1,y1) and (x2,y2) are diagonally opposed corners, in world coords. */
void
drawrect(float x1, float y1, float x2, float y2) {
    int xw1, yw1, xw2, yw2;

    if (rect_off_screen(x1, y1, x2, y2))
        return;

    if (gl_state.disp_type == SCREEN) {
        /* translate to X Windows calling convention. */
        xw1 = xworld_to_scrn(x1);
        xw2 = xworld_to_scrn(x2);
        yw1 = yworld_to_scrn(y1);
        yw2 = yworld_to_scrn(y2);
#ifdef X11
        unsigned int width, height;
        int xl, yt;

        xl = min(xw1, xw2);
        yt = min(yw1, yw2);
        width = abs(xw1 - xw2);
        height = abs(yw1 - yw2);

        if (use_cairo())
        {
            cairo_rectangle(x11_state.ctx, xl, yt, width, height);
            cairo_stroke(x11_state.ctx);
        }
        else
        {
            XDrawRectangle(x11_state.display, *(x11_state.draw_area),
                x11_state.current_gc, xl, yt, width, height);
        }

#else /* Win32 */
        if (xw1 > xw2) {
            int temp = xw1;
            xw1 = xw2;
            xw2 = temp;
        }
        if (yw1 > yw2) {
            int temp = yw1;
            yw1 = yw2;
            yw2 = temp;
        }

        HBRUSH hOldBrush;

        /* NULL_BRUSH is a Windows stock object which does not fill any space. Thus, a  *
         * rectangle can be drawn by outlining it with the current pen and not filling  *
         * it since NULL_BRUSH is used. Another alternative to drawing a rectangle is   *
         * to draw four lines individually.												*/
        hOldBrush = (HBRUSH) SelectObject(win32_state.hGraphicsDC, GetStockObject(NULL_BRUSH));
        if (!(hOldBrush))
            WIN32_SELECT_ERROR();

        if (!Rectangle(win32_state.hGraphicsDC, xw1, yw1, xw2, yw2))
            WIN32_DRAW_ERROR();

        /* Need to restore the previous brush into the specified device context after   *
         * the rectangle is drawn.													    */
        if (!SelectObject(win32_state.hGraphicsDC, hOldBrush))
            WIN32_SELECT_ERROR();
#endif

    } else {
        fprintf(gl_state.ps, "%.2f %.2f %.2f %.2f drawrect\n", x_to_post(x1), y_to_post(y1),
            x_to_post(x2), y_to_post(y2));
    }
}

void fillrect(const t_bound_box& rect) {
    fillrect(rect.bottom_left(), rect.top_right());
}

void fillrect(const t_point& bottomleft, const t_point& upperright) {
    fillrect(bottomleft.x, bottomleft.y, upperright.x, upperright.y);
}

/* (x1,y1) and (x2,y2) are diagonally opposed corners in world coords. */
void
fillrect(float x1, float y1, float x2, float y2) {
    int xw1, yw1, xw2, yw2;

    if (rect_off_screen(x1, y1, x2, y2))
        return;

    if (gl_state.disp_type == SCREEN) {
        /* translate to X Windows calling convention. */
        xw1 = xworld_to_scrn(x1);
        xw2 = xworld_to_scrn(x2);
        yw1 = yworld_to_scrn(y1);
        yw2 = yworld_to_scrn(y2);
#ifdef X11
        unsigned int width, height;
        int xl, yt;

        xl = min(xw1, xw2);
        yt = min(yw1, yw2);
        width = abs(xw1 - xw2);
        height = abs(yw1 - yw2);

        if (use_cairo())
        {
            cairo_rectangle(x11_state.ctx, xl, yt, width, height);
            cairo_fill(x11_state.ctx);
        }
        else
        {
            XFillRectangle(x11_state.display, *(x11_state.draw_area),
                x11_state.current_gc, xl, yt, width, height);
        }
#else /* Win32 */
        if (xw1 > xw2) {
            int temp = xw1;
            xw1 = xw2;
            xw2 = temp;
        }
        if (yw1 > yw2) {
            int temp = yw1;
            yw1 = yw2;
            yw2 = temp;
        }

        if (!Rectangle(win32_state.hGraphicsDC, xw1, yw1, xw2, yw2))
            WIN32_DRAW_ERROR();
#endif
    } else {
        fprintf(gl_state.ps, "%.2f %.2f %.2f %.2f fillrect\n", x_to_post(x1),
            y_to_post(y1), x_to_post(x2), y_to_post(y2));
    }
}

/* Normalizes an angle to be between 0 and 360 degrees. */
static float
angnorm(float ang) {
    int scale;

    if (ang < 0) {
        scale = static_cast<int>(ang / 360. - 1);
    } else {
        scale = static_cast<int>(ang / 360.);
    }
    ang = ang - scale * 360;
    return (ang);
}

void drawellipticarc(
    const t_point& center, float radx, float rady, float startang, float angextent) {

    drawellipticarc(center.x, center.y, radx, rady, startang, angextent);
}

void
drawellipticarc(float xc, float yc, float radx, float rady, float startang, float angextent) {
    int xl, yt;
    unsigned int width, height;

    /* Conservative (but fast) clip test -- check containing rectangle of *
     * an ellipse.                                                         */

    if (rect_off_screen(xc - radx, yc - rady, xc + radx, yc + rady))
        return;

    /* X Windows has trouble with very large angles. (Over 360).    *
     * Do following to prevent its inaccurate (overflow?) problems. */
    if (fabs(angextent) > 360.)
        angextent = 360.;

    startang = angnorm(startang);

    if (gl_state.disp_type == SCREEN) {
        float screen_rad_x = xrad_to_scrn (radx);  // Convert radx to pixels
        float screen_rad_y = yrad_to_scrn (rady);  // Convert rady to pixels
        xl = static_cast<int>(xworld_to_scrn(xc) - screen_rad_x);
        yt = static_cast<int>(yworld_to_scrn(yc) - screen_rad_y);
        width = static_cast<unsigned int>(2 * screen_rad_x);
        height = static_cast<unsigned int>(2 * screen_rad_y);
#ifdef X11
        XDrawArc(x11_state.display, *(x11_state.draw_area), x11_state.current_gc, xl, yt, width, height,
            static_cast<int>(startang * 64), static_cast<int>(angextent * 64));
#else  // Win32
        int p1, p2, p3, p4;

        /* set arc direction */
        float startang_rad, endang_rad;
        if (angextent > 0) {
            startang_rad = (float) DEGTORAD(startang);
            endang_rad = (float) DEGTORAD(startang + angextent - .001);
        } else {
            startang_rad = (float) DEGTORAD(startang + angextent + .001);
            endang_rad = (float) DEGTORAD(startang);
        }
        p1 = (int) (xworld_to_scrn(xc) + screen_rad_x * cos(startang_rad));
        p2 = (int) (yworld_to_scrn(yc) - screen_rad_y * sin(startang_rad));
        p3 = (int) (xworld_to_scrn(xc) + screen_rad_x * cos(endang_rad));
        p4 = (int) (yworld_to_scrn(yc) - screen_rad_y * sin(endang_rad));

        if (!Arc(win32_state.hGraphicsDC, xl, yt, xl + width, yt + height, p1, p2, p3, p4))
            WIN32_DRAW_ERROR();
#endif
    } else {
        fprintf(gl_state.ps, "gsave\n");
        fprintf(gl_state.ps, "%.2f %.2f translate\n", x_to_post(xc), y_to_post(yc));
        fprintf(gl_state.ps, "%.2f 1 scale\n",
            fabs(x_to_post(radx) - x_to_post(0)) / fabs(y_to_post(rady) - y_to_post(0)));
        fprintf(gl_state.ps, "0 0 %.2f %.2f %.2f %s\n",
            fabs(x_to_post(rady) - x_to_post(0)), startang,
            startang + angextent, (angextent < 0) ? "drawarcn" : "drawarc");
        fprintf(gl_state.ps, "grestore\n");
    }
}

/* Startang is relative to the Window's positive x direction.  Angles in degrees.
 */
void
drawarc(float xc, float yc, float rad, float startang,
    float angextent) {
    drawellipticarc(xc, yc, rad, rad, startang, angextent);
}

/* Fills a elliptic arc.  Startang is relative to the Window's positive x
 * direction.  Angles in degrees.
 */

void fillellipticarc(
    const t_point& center, float radx, float rady, float startang, float angextent) {

    fillellipticarc(center.x, center.y, radx, rady, startang, angextent);
}

void
fillellipticarc(float xc, float yc, float radx, float rady, float startang,
    float angextent) {
    int xl, yt;
    unsigned int width, height;

    /* Conservative (but fast) clip test -- check containing rectangle of *
     * a circle.                                                          */

    if (rect_off_screen(xc - radx, yc - rady, xc + radx, yc + rady))
        return;

    /* X Windows has trouble with very large angles. (Over 360).    *
     * Do following to prevent its inaccurate (overflow?) problems. */

    if (fabs(angextent) > 360.)
        angextent = 360.;

    startang = angnorm(startang);

    if (gl_state.disp_type == SCREEN) {
        float screen_rad_x = xrad_to_scrn (radx);  // Convert radx to pixels
        float screen_rad_y = yrad_to_scrn (rady);  // Convert rady to pixels
        xl = static_cast<int>(xworld_to_scrn(xc) - screen_rad_x);
        yt = static_cast<int>(yworld_to_scrn(yc) - screen_rad_y);
        width = static_cast<unsigned int>(2 * screen_rad_x);
        height = static_cast<unsigned int>(2 * screen_rad_y);
#ifdef X11
        XFillArc(x11_state.display, *(x11_state.draw_area), x11_state.current_gc, xl, yt, width, height,
            static_cast<int>(startang * 64), static_cast<int>(angextent * 64));
#else  // Win32
        HPEN hOldPen;
        int p1, p2, p3, p4;

        /* set pie direction */
        float startang_rad, endang_rad;
        if (angextent > 0) {
            startang_rad = (float) DEGTORAD(startang);
            endang_rad = (float) DEGTORAD(startang + angextent - .001);
        } else {
            startang_rad = (float) DEGTORAD(startang + angextent + .001);
            endang_rad = (float) DEGTORAD(startang);
        }
        p1 = (int) (xworld_to_scrn(xc) + screen_rad_x * cos(startang_rad));
        p2 = (int) (yworld_to_scrn(yc) - screen_rad_y * sin(startang_rad));
        p3 = (int) (xworld_to_scrn(xc) + screen_rad_x * cos(endang_rad));
        p4 = (int) (yworld_to_scrn(yc) - screen_rad_y * sin(endang_rad));

        /* NULL_PEN is a Windows stock object which does not draw anything. Set current *
         * pen to NULL_PEN in order to fill the arc without drawing the outline.        */
        hOldPen = (HPEN) SelectObject(win32_state.hGraphicsDC, GetStockObject(NULL_PEN));
        if (!(hOldPen))
            WIN32_SELECT_ERROR();

        // Win32 API says a zero return value indicates an error, but it seems to always
        // return zero.  Don't check for an error on Pie.
        Pie(win32_state.hGraphicsDC, xl, yt, xl + width, yt + height, p1, p2, p3, p4);
        //if(!Pie(win32_state.hGraphicsDC, xl, yt, xl+width, yt+height, p1, p2, p3, p4));
        //WIN32_DRAW_ERROR();

        /* Need to restore the original pen into the device context after filling. */
        if (!SelectObject(win32_state.hGraphicsDC, hOldPen))
            WIN32_SELECT_ERROR();
#endif
    } else {
        fprintf(gl_state.ps, "gsave\n");
        fprintf(gl_state.ps, "%.2f %.2f translate\n", x_to_post(xc), y_to_post(yc));
        fprintf(gl_state.ps, "%.2f 1 scale\n",
            fabs(x_to_post(radx) - x_to_post(0)) / fabs(y_to_post(rady) - y_to_post(0)));
        fprintf(gl_state.ps, "%.2f %.2f %.2f 0 0 %s\n",
            fabs(x_to_post(rady) - x_to_post(0)), startang,
            startang + angextent, (angextent < 0) ? "fillarcn" : "fillarc");
        fprintf(gl_state.ps, "grestore\n");
    }
}

void fillarc(const t_point& center, float rad, float startang, float angextent) {
    fillellipticarc(center.x, center.y, rad, rad, startang, angextent);
}

void fillarc(float xc, float yc, float rad, float startang, float angextent) {
    fillellipticarc(xc, yc, rad, rad, startang, angextent);
}


// For speed, use a fixed size polygon point buffer when possible (no dynamic
// memory allocation). Dynamically allocate an arbitrary size buffer only when
// necessary.
#define MAX_FIXED_POLY_PTS 100

void
fillpoly(t_point *points, int npoints) {
    float xmin, ymin, xmax, ymax;


    /* Conservative (but fast) clip test -- check containing rectangle of *
     * polygon.                                                           */

    xmin = xmax = points[0].x;
    ymin = ymax = points[0].y;

    for (int i = 1; i < npoints; i++) {
        xmin = min(xmin, points[i].x);
        xmax = max(xmax, points[i].x);
        ymin = min(ymin, points[i].y);
        ymax = max(ymax, points[i].y);
    }

    if (rect_off_screen(xmin, ymin, xmax, ymax))
        return;

    if (gl_state.disp_type == SCREEN) {
#ifdef X11
#define MY_POINT XPoint
#else // WIN32 --> uses a different type but with same field names.
#define MY_POINT POINT
#endif
        MY_POINT fixed_transpoints[MAX_FIXED_POLY_PTS];
        MY_POINT *transpoints = fixed_transpoints;
        if (npoints > MAX_FIXED_POLY_PTS) {
            transpoints = static_cast<MY_POINT *> (my_malloc(npoints * sizeof (MY_POINT)));
        }
        for (int i = 0; i < npoints; i++) {
            transpoints[i].x = static_cast<long>(xworld_to_scrn(points[i].x));
            transpoints[i].y = static_cast<long>(yworld_to_scrn(points[i].y));
        }
#ifdef X11
        if (use_cairo())
        {
            cairo_move_to(x11_state.ctx, transpoints[0].x, transpoints[0].y);
            for (int i = 1; i < npoints; ++i)
            {
                cairo_line_to(x11_state.ctx, transpoints[i].x, transpoints[i].y);
            }
            cairo_close_path(x11_state.ctx);
            cairo_fill(x11_state.ctx);
        }
        else
        {
            XFillPolygon(x11_state.display, *(x11_state.draw_area), x11_state.current_gc,
                transpoints, npoints, Complex, CoordModeOrigin);
        }
#else
        HPEN hOldPen;
        /* NULL_PEN is a Windows stock object which does not draw anything. Set current *
         * pen to NULL_PEN in order to fill polygon without drawing its outline.        */
        hOldPen = (HPEN) SelectObject(win32_state.hGraphicsDC, GetStockObject(NULL_PEN));
        if (!(hOldPen))
            WIN32_SELECT_ERROR();

        if (!Polygon(win32_state.hGraphicsDC, transpoints, npoints))
            WIN32_DRAW_ERROR();

        /* Need to restore the original pen into the device context after drawing. */
        if (!SelectObject(win32_state.hGraphicsDC, hOldPen))
            WIN32_SELECT_ERROR();
#endif

        if (npoints > MAX_FIXED_POLY_PTS)
            free(transpoints);
    } else {
        fprintf(gl_state.ps, "\n");

        for (int i = npoints - 1; i >= 0; i--)
            fprintf(gl_state.ps, "%.2f %.2f\n", x_to_post(points[i].x),
            y_to_post(points[i].y));

        fprintf(gl_state.ps, "%d fillpoly\n", npoints);
    }
}

/**
 * drawtext convenience functions
 */

void drawtext_in(const t_bound_box& bbox, const std::string& text) {
    drawtext(bbox.get_center(), text, bbox);
}

void drawtext_in(const t_bound_box& bbox, const std::string& text, float tolerance) {
    drawtext(bbox.get_center(), text, bbox, tolerance);
}

void drawtext(
    const t_point& text_center, const std::string& text, const t_bound_box& bounds, float tolerance) {

    t_point tolerance_pt(tolerance, tolerance);
    t_bound_box tolerance_bounds = bounds;

    tolerance_bounds.bottom_left() -= tolerance_pt;
    tolerance_bounds.top_right() += tolerance_pt;

    drawtext(text_center, text, tolerance_bounds);
}

void drawtext(const t_point& text_center, const std::string& text, const t_bound_box& bounds) {
    if (bounds.intersects(text_center) != true) {
        cout << "The center of the text \"" << text << "\" isn't in its bounding box.\n";
//        printf("the center of the text \"%s\" isn't in its bounding box", text.c_str());
    }
    t_point bottomleft_bounds = text_center - bounds.bottom_left();
    t_point topright_bounds = bounds.top_right() - text_center;
    t_point min_bounds(
        min(bottomleft_bounds.x, topright_bounds.x),
        min(bottomleft_bounds.y, topright_bounds.y)
        );
    min_bounds *= 2;
    drawtext(text_center, text, min_bounds.x, min_bounds.y);
}

void drawtext(const t_point& text_center, const std::string& text, float boundx, float boundy) {
    drawtext(text_center.x, text_center.y, text, boundx, boundy);
}

/**
 * the real drawtext function.
 * First, using a non rotated font (probably already loaded), it conservatively checks
 * if an approximation of the bbox is on the screen, and not to large for the given
 * bound{x,y}. Then it loads the proper (possibly rotated) font, and checks the real
 * bounds of the text and performs the same checks. Then it draws the text to the
 * XftDraw (X11) or screen (WIN32). boundx and boundy are in the current coordinate
 * system (world or screen).
 */
void drawtext(float xc, float yc, const std::string& str_text, float boundx, float boundy) {
    // Need a C-string to call the low-level (X11 or win32) apis.
    const char* text = str_text.c_str();
    int text_byte_length = strlen(text);
    float angle = PI * gl_state.currentfontrotation / 180.;
    float abscos = fabs(cos(angle));
    float abssin = fabs(sin(angle));
#ifdef WIN32
    wchar_t* WIN32_wchar_text = new wchar_t[text_byte_length + 1];
    size_t WIN32_wchar_text_len =
        MultiByteToWideChar(CP_UTF8, 0, text, text_byte_length, WIN32_wchar_text, text_byte_length);
    WIN32_wchar_text[text_byte_length] = 0;
#endif

    // exit early (conservatively) to prevent filling the font cache with fonts not visible
    if (rect_off_screen(t_bound_box(t_point(xc - boundx / 2, yc - boundy / 2), boundx, boundy))) {
        // if the largest bbox the text could have is off the screen, don't even load the font.
        return;
    }

    float trans_xmult, trans_ymult;
    if (gl_state.currentcoordinatesystem == GL_WORLD) {
        trans_xmult = trans_coord.stow_xmult;
        trans_ymult = trans_coord.stow_ymult;
    }
    else {  // Screen coordinates:  clip bounding box passed in already in pixels.
        trans_xmult = 1;
        trans_ymult = 1;
    }
    // approximate width & height and check against bound{x,y}
    font_ptr zero_font = gl_state.font_info.get_font_info(gl_state.currentfontsize, 0);

#ifdef X11
    XGlyphInfo zero_extents;
    XftTextExtentsUtf8(
        x11_state.display, zero_font, reinterpret_cast<const FcChar8*>(text), text_byte_length, &zero_extents);
    int zero_approx_height = zero_extents.height;
    int zero_approx_width = zero_extents.width;

#elif defined WIN32
    HFONT zero_hfont = CreateFontIndirect(zero_font);
    if (!zero_hfont) {
        WIN32_CREATE_ERROR();
    }
    // Select zero font into specified device context
    if (!SelectObject(win32_state.hGraphicsDC, zero_hfont)) {
        WIN32_SELECT_ERROR();
    }

    SIZE textsize;
    if (!GetTextExtentPoint32W(
        win32_state.hGraphicsDC,
        WIN32_wchar_text,
        WIN32_wchar_text_len,
        &textsize)
        ) {
        WIN32_DRAW_ERROR();
    }

    int zero_approx_width = textsize.cx;
    int zero_approx_height = textsize.cy;

    // reselect normal font
    if (win32_state.hGraphicsFont != NULL) {
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsFont)) {
            WIN32_SELECT_ERROR();
        }
    }

    // eventhough it might be selected, we wont't be drawing with it, because
    // the HFONT in wit32_state is NULL, so it will be set before something
    // tries to draw text. Putting it in a later, more proper, place in this
    // function causes an draw error on font cache cache overflow, for some reason.
    if (zero_hfont != NULL) {
        if (!DeleteObject(zero_hfont)) {
            WIN32_DELETE_ERROR();
        }
    }
#endif
    // conservatively check if the bbox is to large
    if (
        fabs(0.9 *
        (abssin * zero_approx_width + abscos * zero_approx_height) * trans_ymult) > boundy ||
        fabs(0.9 *
        (abscos * zero_approx_width + abssin * zero_approx_height) * trans_xmult) > boundx) {

        return;  // Text bigger than user wants; don't draw
    }

    int width, height;
    font_ptr current_font = gl_state.font_info.get_font_info(
        gl_state.currentfontsize,
        gl_state.currentfontrotation
        );
#ifdef X11
    XGlyphInfo extents;
    XftTextExtentsUtf8(x11_state.display, current_font, reinterpret_cast<const FcChar8*>(text), text_byte_length, &extents);
    width = extents.width;
    height = extents.height;
#else /* WC : WIN32 */
    if (win32_state.hGraphicsFont == NULL) {
        // if the font isn't already created, create it.
        // note: set to NULL by settextattrs(...) if something changed
        win32_state.hGraphicsFont = CreateFontIndirect(current_font);

        if (!win32_state.hGraphicsFont) {
            WIN32_CREATE_ERROR();
        }
        // Select created font into specified device context
        if (!SelectObject(win32_state.hGraphicsDC, win32_state.hGraphicsFont)) {
            WIN32_SELECT_ERROR();
        }
    }

    if (SetTextColor(
        win32_state.hGraphicsDC,
        convert_to_win_color(gl_state.foreground_color)
        ) == CLR_INVALID) {
        WIN32_DRAW_ERROR();
    }

    if (!GetTextExtentPoint32W(
        win32_state.hGraphicsDC,
        WIN32_wchar_text,
        WIN32_wchar_text_len,
        &textsize)
        ) {
        WIN32_DRAW_ERROR();
    }

    width = (int) (textsize.cx * abscos + textsize.cy*abssin);
    height = (int) (textsize.cx * abssin + textsize.cy*abscos);
#endif

    // Text width and height in whatever coordinate system the user has active (SCREEN or WORLD)
    float coord_width = width * trans_xmult;
    float coord_height = height * trans_ymult;

    if ((fabs(coord_width) > fabs(boundx)) || (fabs(coord_height) > fabs(boundy))) {
        return; // don't draw if it won't fit in xbound or ybound.
    }

    // These are more-or-less magic offsets. The members of extents are not documented
    // anywhere I could find, and after much experimentation, I determined some of their
    // meaning, and derived offsets to find the true center of the text - ie the center
    // point in the x direction, with the y center being halfway up a normal letter
    // (eg. 'a', ie. nothing below the baseline (like 'p'), or anything extra tall (like 'b')).
    //
    // XGlyphInfo.{x,y} - relative location of the start of the text to the point passed
    //     to XftDrawString*().
    // XGlyphInfo.{x,y}Off - relative location of the end of the text to (x,y); where
    //     the drawing of the next character would start, I believe.
    // XGlyphInfo.{width,height} - these ones mean what they say - ie. width and height
    //     of a bounding rectangle, but note that they will change based on rotation and
    //     whether or not the text contains non short letters like 'p' or 'b').
    //
    // Also, it should be noted that with rotation,
    // XftFont.{height,descent,ascent,max_advance_width} cannot be trusted.
    // You would have to take those values from an unrotated font.
#ifdef X11
    // these two work almost perfectly, with aligned baselines, but only for the interval [0-90]
    //float X11_xmagicoffset = (extents.width - (extents.x + extents.xOff))*trans_coord.stow_xmult;
    // float X11_ymagicoffset = - (extents.y - extents.height)*trans_coord.stow_ymult;

    // however just leaving them at 0 works good enough for [0-360], however baselines
    // will not be aligned, and text with different heights and the same yc will look bad next
    // to each other. If you would like aligned baselines, use the previous equations, but note
    // their caveats.
    float X11_xmagicoffset = 0;
    float X11_ymagicoffset = 0;
#endif

    t_bound_box text_bbox(
#ifdef X11
        t_point(
        xc + (-coord_width + X11_xmagicoffset) / 2.0,
        yc + (-coord_height + X11_ymagicoffset) / 2.0
        ),
#elif defined WIN32
        t_point(xc - coord_width / 2, yc - coord_height / 2),
#endif
        coord_width,
        coord_height
        );

    if (rect_off_screen(text_bbox)) {
        return;
    }

    // #define SHOW_TEXT_BBOX // useful for debugging text placement.
#ifdef SHOW_TEXT_BBOX
    drawrect(text_bbox);
    t_color save = getcolor();
    setcolor(RED);

    if (fabs(coord_width) < fabs(boundx)) {
        drawline(xc, yc - boundy / 2, xc, yc + boundy / 2);
    }
    if (fabs(coord_height) < fabs(boundy)) {
        drawline(xc - boundx / 2, yc, xc + boundx / 2, yc);
    }

    setcolor(GREEN);
    drawline(xc, yc - coord_height / 2, xc, yc + coord_height / 2);
    drawline(xc - coord_width / 2, yc, xc + coord_width / 2, yc);
    setcolor(save);
#endif

    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        XftDrawStringUtf8(
            x11_state.draw_area_draw,
            &x11_state.xft_currentcolor,
            current_font,
            // more magic offsets
            xworld_to_scrn(text_bbox.left()) + extents.x,
            yworld_to_scrn(text_bbox.top()) + extents.y - extents.height,
            reinterpret_cast<const FcChar8*>(text),
            text_byte_length
            );
#elif defined WIN32
        float WIN_xtextoffset = 0;
        float WIN_ytextoffset = 0;
        float normalized_angle = (float) (angle - (int) (angle / (2 * PI))*2 * PI);
        if (normalized_angle < PI / 2) { // quadrant I
            WIN_ytextoffset = textsize.cx*abssin;
        } else if (normalized_angle < PI) { // quadrant II
            WIN_ytextoffset = (float) height;
            WIN_xtextoffset = textsize.cx*abscos;
        } else if (normalized_angle < PI * 3 / 2) { // quadrant III
            WIN_xtextoffset = (float) width;
            WIN_ytextoffset = textsize.cy*abscos;
        } else { // quadrant IV
            WIN_xtextoffset = textsize.cy*abssin;
        }
        SetBkMode(win32_state.hGraphicsDC, TRANSPARENT);
        if (TextOutW(
            win32_state.hGraphicsDC,
            xworld_to_scrn(text_bbox.left()) + (int) WIN_xtextoffset,
            yworld_to_scrn(text_bbox.bottom()) + (int) WIN_ytextoffset,
            WIN32_wchar_text,
            WIN32_wchar_text_len
            ) == 0) {
            WIN32_DRAW_ERROR();
        }

        delete[] WIN32_wchar_text;
#endif
    } else {
        fprintf(gl_state.ps, "gsave\n");
        fprintf(gl_state.ps, "%.2f %.2f moveto\n", x_to_post(xc), y_to_post(yc));
        fprintf(gl_state.ps, "0.8 0.8 scale\n"); // text comes out a little bit bigger in ps than X11
        fprintf(gl_state.ps, "%d rotate\n", static_cast<int>(gl_state.currentfontrotation) % 360);
        fprintf(gl_state.ps, "(%s) 0 0 rcenshow\n", text);
        fprintf(gl_state.ps, "grestore\n");
    }
}

void
set_coordinate_system(t_coordinate_system coord)
{
    gl_state.currentcoordinatesystem = coord;
}

void
flushinput() {
    if (gl_state.disp_type != SCREEN)
        return;
#ifdef X11
    XFlush(x11_state.display);
#endif
}

void set_visible_world(float left, float bottom, float right, float top) {
    set_visible_world(t_bound_box(left, bottom, right, top));
}

void set_visible_world(const t_bound_box& bounds) {
    /* Sets the coordinate system the user wants to draw into.          */

    trans_coord.xleft = bounds.left();
    trans_coord.xright = bounds.right();
    trans_coord.ytop = bounds.top();
    trans_coord.ybot = bounds.bottom();

    /* Save initial world coordinates to allow full view button
     * to zoom all the way out.
     */
    trans_coord.init_xleft = trans_coord.xleft;
    trans_coord.init_xright = trans_coord.xright;
    trans_coord.init_ytop = trans_coord.ytop;
    trans_coord.init_ybot = trans_coord.ybot;

    if (gl_state.disp_type == SCREEN) {
        update_transform();
    } else {
        update_ps_transform();
    }
}

/* Draw the current message in the text area at the screen bottom. */
void
draw_message() {
    int savefontsize;
    t_color savecolor;
    float ylow;

    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        XClearWindow(x11_state.display, x11_state.textarea);

        XSetForeground(x11_state.display, x11_state.gc_menus,
                    x11_convert_to_xcolor(t_color::predef_colors[WHITE]));
        XDrawRectangle(x11_state.display, x11_state.textarea, x11_state.gc_menus, 0, 0,
            trans_coord.top_width - MWIDTH, T_AREA_HEIGHT);
        XSetForeground(x11_state.display, x11_state.gc_menus,
                    x11_convert_to_xcolor(t_color::predef_colors[BLACK]));
        XDrawLine(x11_state.display, x11_state.textarea, x11_state.gc_menus, 0, T_AREA_HEIGHT - 1,
            trans_coord.top_width - MWIDTH, T_AREA_HEIGHT - 1);
        XDrawLine(x11_state.display, x11_state.textarea, x11_state.gc_menus,
            trans_coord.top_width - MWIDTH - 1, 0, trans_coord.top_width - MWIDTH - 1,
            T_AREA_HEIGHT - 1);

        menutext(
            x11_state.textarea_draw,
            (trans_coord.top_width - MWIDTH) / 2,
            T_AREA_HEIGHT / 2,
            gl_state.statusMessage
            );
#else
        if (!InvalidateRect(win32_state.hStatusWnd, NULL, TRUE))
            WIN32_DRAW_ERROR();
        if (!UpdateWindow(win32_state.hStatusWnd))
            WIN32_DRAW_ERROR();
#endif
    } else {
        /* Draw the message in the bottom margin.  Printer's generally can't  *
         * print on the bottom 1/4" (area with y < 18 in PostScript coords.)  */

        savecolor = gl_state.foreground_color;
        setcolor(BLACK);
        savefontsize = gl_state.currentfontsize;
        setfontsize(MENU_FONT_SIZE - 2); /* Smaller OK on paper */
        ylow = trans_coord.ps_bot - 8;
        fprintf(gl_state.ps, "(%s) %.2f %.2f censhow\n", gl_state.statusMessage,
            (trans_coord.ps_left + trans_coord.ps_right) / 2., ylow);
        setcolor(savecolor);
        setfontsize(savefontsize);
    }
}

/* Changes the message to be displayed on screen.   */
void
update_message(const string& msg) {
    strncpy(gl_state.statusMessage, msg.c_str(), BUFSIZE);
    gl_state.statusMessage[BUFSIZE-1] = '\0'; //Ensure null termination
    draw_message();
#ifdef X11
    // Make this appear immediately.  Win32 does that automaticaly.
    XFlush(x11_state.display);
#endif // X11
}

/* Zooms in menu button pressed. Zoom in at center
 * of graphics area.
 */
static void
zoom_in(void (*drawscreen) ()) {
    float xcen, ycen;

    xcen = (trans_coord.xright + trans_coord.xleft) / 2;
    ycen = (trans_coord.ybot + trans_coord.ytop) / 2;

    handle_zoom_in(xcen, ycen, drawscreen);
}

/* Zoom out menu button pressed. Zoom out from center
 * of graphics area.
 */
static void
zoom_out(void (*drawscreen) ()) {
    float xcen, ycen;

    xcen = (trans_coord.xright + trans_coord.xleft) / 2;
    ycen = (trans_coord.ybot + trans_coord.ytop) / 2;

    handle_zoom_out(xcen, ycen, drawscreen);
}

/* Zooms in by a factor of ZOOM_FACTOR */
static void
handle_zoom_in(float x, float y, void (*drawscreen) ()) {
    //make xright - xleft = 0.6 of the original distance
    trans_coord.xleft = x - (x - trans_coord.xleft) / ZOOM_FACTOR;
    trans_coord.xright = x + (trans_coord.xright - x) / ZOOM_FACTOR;
    //make ybot - ytop = 0.6 of the original distance
    trans_coord.ytop = y - (y - trans_coord.ytop) / ZOOM_FACTOR;
    trans_coord.ybot = y + (trans_coord.ybot - y) / ZOOM_FACTOR;

    update_transform();
    if (drawscreen != nullptr) {
        drawscreen();
    }
}

/* Zooms out by a factor of ZOOM_FACTOR */
static void
handle_zoom_out(float x, float y, void (*drawscreen) ()) {
    //restore the original distances before previous zoom in
    trans_coord.xleft = x - (x - trans_coord.xleft)* ZOOM_FACTOR;
    trans_coord.xright = x + (trans_coord.xright - x)* ZOOM_FACTOR;
    trans_coord.ytop = y - (y - trans_coord.ytop)* ZOOM_FACTOR;
    trans_coord.ybot = y + (trans_coord.ybot - y)* ZOOM_FACTOR;

    update_transform();
    if (drawscreen != nullptr) {
        drawscreen();
    }
}

/* Sets the view back to the initial view set by set_visible_world (i.e. a full     *
 * view) of all the graphics.                                                */
static void
zoom_fit(void (*drawscreen) ()) {
    trans_coord.xleft = trans_coord.init_xleft;
    trans_coord.xright = trans_coord.init_xright;
    trans_coord.ytop = trans_coord.init_ytop;
    trans_coord.ybot = trans_coord.init_ybot;

    update_transform();
    drawscreen();
}

/* Moves view 1/2 screen up. */
static void
translate_up(void (*drawscreen) ()) {
    float ystep;

    ystep = (trans_coord.ybot - trans_coord.ytop) / 2;
    trans_coord.ytop -= ystep;
    trans_coord.ybot -= ystep;
    update_transform();
    drawscreen();
}

/* Moves view 1/2 screen down. */
static void
translate_down(void (*drawscreen) ()) {
    float ystep;

    ystep = (trans_coord.ybot - trans_coord.ytop) / 2;
    trans_coord.ytop += ystep;
    trans_coord.ybot += ystep;
    update_transform();
    drawscreen();
}

/* Moves view 1/2 screen left. */
static void
translate_left(void (*drawscreen) ()) {

    float xstep;

    xstep = (trans_coord.xright - trans_coord.xleft) / 2;
    trans_coord.xleft -= xstep;
    trans_coord.xright -= xstep;
    update_transform();
    drawscreen();
}

/* Moves view 1/2 screen right. */
static void
translate_right(void (*drawscreen) ()) {
    float xstep;

    xstep = (trans_coord.xright - trans_coord.xleft) / 2;
    trans_coord.xleft += xstep;
    trans_coord.xright += xstep;
    update_transform();
    drawscreen();
}

/* Panning is enabled by pressing and holding down mouse wheel
 * (or middle mouse button)
 */
static void
panning_execute(int x, int y, void (*drawscreen) ()) {
    float x_change_world, y_change_world;

    x_change_world = xscrn_to_world(x) - xscrn_to_world(pan_state.previous_x);
    y_change_world = yscrn_to_world(y) - yscrn_to_world(pan_state.previous_y);
    trans_coord.xleft -= x_change_world;
    trans_coord.xright -= x_change_world;
    trans_coord.ybot -= y_change_world;
    trans_coord.ytop -= y_change_world;

    update_transform();
    drawscreen();

    pan_state.previous_x = x;
    pan_state.previous_y = y;
}

/* Turn panning_enabled on */
static void
panning_on(int start_x, int start_y) {
    pan_state.previous_x = start_x;
    pan_state.previous_y = start_y;
    pan_state.panning_enabled = true;
}

/* Turn panning_enabled off */
static void
panning_off() {
    pan_state.panning_enabled = false;
}


// Updates the graphics transformation so that the graphics drawn within the
// box (in pixels) defined by x[0],y[0] to x[1],y[1] will be scaled to fill
// the whole window area.

static void
update_win(int x[2], int y[2], void (*drawscreen)()) {
    float x1, x2, y1, y2;

    x[0] = min(x[0], trans_coord.top_width - MWIDTH); /* Can't go under menu */
    x[1] = min(x[1], trans_coord.top_width - MWIDTH);
    y[0] = min(y[0], trans_coord.top_height - T_AREA_HEIGHT); /* Can't go under text area */
    y[1] = min(y[1], trans_coord.top_height - T_AREA_HEIGHT);

    if ((x[0] == x[1]) || (y[0] == y[1])) {
        printf("Illegal (zero area) window.  Window unchanged.\n");
        return;
    }
    x1 = xscrn_to_world(min(x[0], x[1]));
    x2 = xscrn_to_world(max(x[0], x[1]));
    y1 = yscrn_to_world(min(y[0], y[1]));
    y2 = yscrn_to_world(max(y[0], y[1]));
    trans_coord.xleft = x1;
    trans_coord.xright = x2;
    trans_coord.ytop = y1;
    trans_coord.ybot = y2;
    update_transform();
    drawscreen();
}

/* The window button was pressed.  Let the user click on the two *
 * diagonally opposed corners, and zoom in on this area.         */
static void
adjustwin(void (*drawscreen) ()) {
#ifdef X11

    XEvent report;
    int corner, xold, yold, x[2], y[2];

    corner = 0;
    xold = -1;
    yold = -1; /* Don't need to init yold, but stops compiler warning. */

    while (corner < 2) {
        XNextEvent(x11_state.display, &report);
        switch (report.type) {
            case Expose:
                x11_handle_expose(report, drawscreen);
                if (report.xexpose.window == x11_state.toplevel) {
                    xold = -1; /* No rubber band on screen */
                }
                break;
            case ConfigureNotify:
                x11_handle_configure_notify(report, drawscreen);
                break;
            case ButtonPress:
#ifdef VERBOSE
                printf("Got a buttonpress.\n");
                printf("Window ID is: %ld.\n", report.xbutton.window);
                printf("Location (%d, %d).\n", report.xbutton.x,
                    report.xbutton.y);
#endif
                if (report.xbutton.window != x11_state.toplevel) break;
                x[corner] = report.xbutton.x;
                y[corner] = report.xbutton.y;
                if (corner == 0) {
                    /*	XSelectInput (x11_state.display, x11_state.toplevel, ExposureMask |
                            StructureNotifyMask | ButtonPressMask | PointerMotionMask); */
                } else {
                    update_win(x, y, drawscreen);
                }
                corner++;
                break;
            case MotionNotify:
                if (corner) {
#ifdef VERBOSE
                    printf("Got a MotionNotify Event.\n");
                    printf("x: %d    y: %d\n", report.xmotion.x, report.xmotion.y);
#endif
                    if (xold >= 0) { /* xold set -ve before we draw first box */
                        // Erase prior box.
                        set_draw_mode(DRAW_XOR);
                        XDrawRectangle(x11_state.display, x11_state.toplevel, x11_state.gc_xor,
                            min(x[0], xold), min(y[0], yold), abs(x[0] - xold), abs(y[0] - yold));
                        set_draw_mode(DRAW_NORMAL);
                    }
                    /* Don't allow user to window under menu region */
                    xold = min(report.xmotion.x, trans_coord.top_width - 1 - MWIDTH);
                    yold = report.xmotion.y;
                    set_draw_mode(DRAW_XOR);

                    setlinewidth(1);
                    setlinestyle(DASHED);
                    setcolor(gl_state.background_color);

                    // Draw rubber band box.
                    XDrawRectangle(x11_state.display, x11_state.toplevel, x11_state.gc_xor, min(x[0], xold),
                        min(y[0], yold), abs(x[0] - xold), abs(y[0] - yold));
                    set_draw_mode(DRAW_NORMAL);
                }
                break;

            default:
                break;  // Other event type: ignore it.
        }
    }

#else /* Win32 */
    /* Implemented as WM_LB... events */
    /* Begin window adjust */
    if (win32_state.windowAdjustFlag == WINDOW_DEACTIVATED) {
        win32_state.windowAdjustFlag = WAITING_FOR_FIRST_CORNER_POINT;
    }
	(void) drawscreen; // Suppress unused parameter warnings for Win32
#endif
}

static void
postscript(void (*drawscreen) ()) {
    /* Takes a snapshot of the screen and stores it in pic?.ps.  The *
     * first picture goes in pic1.ps, the second in pic2.ps, etc.    */

    int piccount = 1;
    int success;
    char fname[BUFSIZE];


    /*
     * Find a filename which does not exist
     */
    while(true) {
        sprintf(fname, "pic%d.ps", piccount);

        FILE* f = fopen(fname, "r");
        if(f) {
            //File exists, try next number
            fclose(f);
            ++piccount;
        } else {
            //File doesn't exist, use this filename
            break;
        }
    }

    printf("Writing postscript output to file %s\n", fname);
    success = init_postscript(fname);

    if (success) {
        drawscreen();
        close_postscript();
    } else {
        printf("Error initializing for postscript output.\n");
#ifdef WIN32
        MessageBoxW(win32_state.hMainWnd, L"Error initializing postscript output.", NULL, MB_OK);
#endif
    }
}

static void
proceed(void (*drawscreen) ()) {
    (void) drawscreen; // Suppress unused parameter warnings for Win32
    gl_state.ProceedPressed = true;
}

static void
quit(void (*drawscreen) ()) {
    (void) drawscreen; // Suppress unused parameter warnings for Win32
    close_graphics();
    exit(0);
}

/* Release all my drawing structures (through the X server) and *
 * close down the connection.                                   */
void
close_graphics() {
    if (!gl_state.initialized)
        return;

    gl_state.font_info.clear();

    for (int i = 0; i < button_state.num_buttons; ++i) {
        unmap_button(i);
    }
    free(button_state.button);
    button_state.button = nullptr;
    button_state.num_buttons = 0;

#ifdef X11
    XFreeGC(x11_state.display, x11_state.gc_normal);
    XFreeGC(x11_state.display, x11_state.gc_xor);
    XFreeGC(x11_state.display, x11_state.gc_menus);

    XftDrawDestroy(x11_state.toplevel_draw);
    XftDrawDestroy(x11_state.menu_draw);
    XftDrawDestroy(x11_state.textarea_draw);
    XftDrawDestroy(x11_state.draw_buffer_draw);
    XFreePixmap(x11_state.display, x11_state.draw_buffer);

    x11_state.colormap_to_use = -1; // is free()'d by XCloseDisplay
    memset(&x11_state.visual_info, 0, sizeof (x11_state.visual_info)); // dont need to free this

    XCloseDisplay(x11_state.display);

	// Destroy cairo things
	cairo_destroy(x11_state.ctx);
	cairo_surface_destroy(x11_state.cairo_surface);
	x11_state.ctx = nullptr;      // Important to NULL these pointers in case init_cairo is called again
	x11_state.cairo_surface = nullptr;
#elif defined WIN32
    // Destroy the window
    if (!DestroyWindow(win32_state.hMainWnd))
        WIN32_DRAW_ERROR();

    // free the window class (type information held by MS Windows)
    // for each of the four window types we created.  Otherwise a
    // later call to init_graphics to open the graphics window up again
    // will fail.
    if (!UnregisterClassW(szAppName, GetModuleHandle(NULL)))
        WIN32_DRAW_ERROR();
    if (!UnregisterClassW(szGraphicsName, GetModuleHandle(NULL)))
        WIN32_DRAW_ERROR();
    if (!UnregisterClassW(szStatusName, GetModuleHandle(NULL)))
        WIN32_DRAW_ERROR();
    if (!UnregisterClassW(szButtonsName, GetModuleHandle(NULL)))
        WIN32_DRAW_ERROR();
#endif

    gl_state.initialized = false;
}

/* Opens a file for PostScript output.  The header information,  *
 * clipping path, etc. are all dumped out.  If the file could    *
 * not be opened, the routine returns 0; otherwise it returns 1. */
int init_postscript(const char *fname) {
    gl_state.ps = fopen(fname, "w");
    if (gl_state.ps == nullptr) {
        printf("Error: could not open %s for PostScript output.\n", fname);
        printf("Drawing to screen instead.\n");
        return (0);
    }
    gl_state.disp_type = POSTSCRIPT; /* Graphics go to postscript file now. */

    /* Header for minimal conformance with the Adobe structuring convention */
    fprintf(gl_state.ps, "%%!PS-Adobe-1.0\n");
    fprintf(gl_state.ps, "%%%%DocumentFonts: Helvetica\n");
    fprintf(gl_state.ps, "%%%%Pages: 1\n");
    /* Set up postscript transformation macros and page boundaries */
    update_ps_transform();
    /* Bottom margin is at ps_bot - 15. to leave room for the on-screen message. */
    fprintf(gl_state.ps, "%%%%HiResBoundingBox: %.2f %.2f %.2f %.2f\n",
        trans_coord.ps_left, trans_coord.ps_bot - 15.,
        trans_coord.ps_right, trans_coord.ps_top);
    fprintf(gl_state.ps, "%%%%EndComments\n");

    fprintf(gl_state.ps, "/censhow   %%draw a centered string\n");
    fprintf(gl_state.ps, " { moveto               %% move to proper spot\n");
    fprintf(gl_state.ps, "   dup stringwidth pop  %% get x length of string\n");
    fprintf(gl_state.ps, "   -2 div               %% Proper left start\n");
    fprintf(gl_state.ps, "   yoff rmoveto         %% Move left that much and down half font height\n");
    fprintf(gl_state.ps, "   show newpath } def   %% show the string\n\n");

    fprintf(gl_state.ps, "/rcenshow  %%draw a centered string\n"
        " { rmoveto              %% move to proper spot\n"
        "   dup stringwidth pop  %% get x length of string\n"
        "   -2 div               %% Proper left start\n"
        "   yoff rmoveto         %% Move left that much and down half font height\n"
        "   show newpath } def   %% show the string\n");

    fprintf(gl_state.ps, "/setfontsize     %% set font to desired size and compute "
        "centering yoff\n");
    fprintf(gl_state.ps, " { /Helvetica findfont\n");
    fprintf(gl_state.ps, "   exch scalefont\n");
    fprintf(gl_state.ps, "   setfont         %% Font size set ...\n\n");
    fprintf(gl_state.ps, "   0 0 moveto      %% Get vertical centering offset\n");
    fprintf(gl_state.ps, "   (Xg) true charpath\n");
    fprintf(gl_state.ps, "   flattenpath pathbbox\n");
    fprintf(gl_state.ps, "   /ascent exch def pop -1 mul /descent exch def pop\n");
    fprintf(gl_state.ps, "   newpath\n");
    fprintf(gl_state.ps, "   descent ascent sub 2 div /yoff exch def } def\n\n");

    fprintf(gl_state.ps, "%% Next two lines for debugging only.\n");
    fprintf(gl_state.ps, "/str 20 string def\n");
    fprintf(gl_state.ps, "/pnum {str cvs print (  ) print} def\n");

    fprintf(gl_state.ps, "/drawline      %% draw a line from (x2,y2) to (x1,y1)\n");
    fprintf(gl_state.ps, " { moveto lineto stroke } def\n\n");

    fprintf(gl_state.ps, "/rect          %% outline a rectangle \n");
    fprintf(gl_state.ps, " { /y2 exch def /x2 exch def /y1 exch def /x1 exch def\n");
    fprintf(gl_state.ps, "   x1 y1 moveto\n");
    fprintf(gl_state.ps, "   x2 y1 lineto\n");
    fprintf(gl_state.ps, "   x2 y2 lineto\n");
    fprintf(gl_state.ps, "   x1 y2 lineto\n");
    fprintf(gl_state.ps, "   closepath } def\n\n");

    fprintf(gl_state.ps, "/drawrect      %% draw outline of a rectanagle\n");
    fprintf(gl_state.ps, " { rect stroke } def\n\n");

    fprintf(gl_state.ps, "/fillrect      %% fill in a rectanagle\n");
    fprintf(gl_state.ps, " { rect fill } def\n\n");

    fprintf(gl_state.ps, "/drawarc { arc stroke } def           %% draw an arc\n");
    fprintf(gl_state.ps, "/drawarcn { arcn stroke } def "
        "        %% draw an arc in the opposite direction\n\n");

    fprintf(gl_state.ps, "%%Fill a counterclockwise or clockwise arc sector, "
        "respectively.\n");
    fprintf(gl_state.ps, "/fillarc { moveto currentpoint 5 2 roll arc closepath fill } "
        "def\n");
    fprintf(gl_state.ps, "/fillarcn { moveto currentpoint 5 2 roll arcn closepath fill } "
        "def\n\n");

    fprintf(gl_state.ps, "/fillpoly { 3 1 roll moveto         %% move to first point\n"
        "   2 exch 1 exch {pop lineto} for   %% line to all other points\n"
        "   closepath fill } def\n\n");

    fprintf(gl_state.ps, "%%Color Definitions:\n");
    fprintf(gl_state.ps, "/white { 1 setgray } def\n");
    fprintf(gl_state.ps, "/black { 0 setgray } def\n");
    fprintf(gl_state.ps, "/grey55 { .55 setgray } def\n");
    fprintf(gl_state.ps, "/grey75 { .75 setgray } def\n");
    fprintf(gl_state.ps, "/red { 1 0 0 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/orange { 1 0.65 0 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/yellow { 1 1 0 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/green { 0 1 0 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/cyan { 0 1 1 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/blue { 0 0 1 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/purple { 0.63 0.13 0.94 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/pink { 1 0.75 0.8 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/lightpink { 1 0.71 0.76 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/darkgreen { 0 0.5 0 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/magenta { 1 0 1 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/bisque { 1 0.89 0.77 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/lightskyblue { 0.53 0.81 0.98 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/thistle { 0.85 0.75 0.85 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/plum { 0.87 0.63 0.87 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/khaki { 0.94 0.9 0.55 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/coral { 1 0.5 0.31 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/turquoise { 0.25 0.88 0.82 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/mediumpurple { 0.58 0.44 0.86 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/darkslateblue { 0.28 0.24 0.55 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/darkkhaki { 0.74 0.72 0.42 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/lightmediumblue { 0.33 0.33 1.00 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/saddlebrown { 0.55 0.27 0.07 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/firebrick { 0.70 0.13 0.13 setrgbcolor } def\n");
    fprintf(gl_state.ps, "/limegreen { 0.20 0.80 0.20 setrgbcolor } def\n");

    fprintf(gl_state.ps, "\n%%Solid and dashed line definitions:\n");
    fprintf(gl_state.ps, "/linesolid {[] 0 setdash} def\n");
    fprintf(gl_state.ps, "/linedashed {[3 3] 0 setdash} def\n");

    fprintf(gl_state.ps, "\n%%%%EndProlog\n");
    fprintf(gl_state.ps, "%%%%Page: 1 1\n\n");

    /* Set up PostScript graphics state to match current one. */
    force_setcolor(gl_state.foreground_color);
    force_setlinestyle(gl_state.currentlinestyle);
    force_setlinewidth(gl_state.currentlinewidth);
    force_settextattrs(gl_state.currentfontsize, gl_state.currentfontrotation);

    /* Draw this in the bottom margin -- must do before the clippath is set */
    draw_message();

    /* Set clipping on page. */
    fprintf(gl_state.ps, "%.2f %.2f %.2f %.2f rect ", trans_coord.ps_left, trans_coord.ps_bot,
        trans_coord.ps_right, trans_coord.ps_top);
    fprintf(gl_state.ps, "clip newpath\n\n");

    return (1);
}

/* Properly ends postscript output and redirects output to screen. */
void close_postscript() {

    fprintf(gl_state.ps, "showpage\n");
    fprintf(gl_state.ps, "\n%%%%Trailer\n");
    fclose(gl_state.ps);
    gl_state.disp_type = SCREEN;
    update_transform(); /* Ensure screen world reflects any changes      *
	* made while printing.                          */

    /* Need to make sure that we really set up the graphics context.
     * The current font set indicates the last font used in a postscript call,
     * etc., *NOT* the font set in the X11 or Win32 graphics context.  Force the
     * current font, colour etc. to be applied to the graphics context, so
     * subsequent drawing commands work properly.
     */

    force_setcolor(gl_state.foreground_color);
    force_setlinestyle(gl_state.currentlinestyle);
    force_setlinewidth(gl_state.currentlinewidth);
    force_settextattrs(gl_state.currentfontsize, gl_state.currentfontrotation);
}

/* Sets up the default menu buttons on the right hand side of the window. */
static void
build_default_menu() {
    int i, xcen, x1, y1, bwid, bheight, space;
    const int NUM_ARROW_BUTTONS = 4, NUM_STANDARD_BUTTONS = 12, SEPARATOR_BUTTON_INDEX = 8;

#ifdef X11
    unsigned long valuemask;
    XSetWindowAttributes menu_attributes;

    x11_state.menu = XCreateSimpleWindow(
        x11_state.display, x11_state.toplevel,
        trans_coord.top_width - MWIDTH, 0, MWIDTH,
        trans_coord.display_height, 0,
        x11_convert_to_xcolor(t_color::predef_colors[BLACK]),
        x11_convert_to_xcolor(t_color::predef_colors[LIGHTGREY])
        );

    x11_state.menu_draw = XftDrawCreate(
        x11_state.display,
        x11_state.menu,
        x11_state.visual_info.visual,
        x11_state.colormap_to_use
        );
    menu_attributes.event_mask = ExposureMask;
//    menu_attributes.event_mask = 0;
    /* Ignore button presses on the menu background. */
    menu_attributes.do_not_propagate_mask = ButtonPressMask;
    /* Keep menu on top right */
    menu_attributes.win_gravity = NorthEastGravity;
    valuemask = CWWinGravity | CWEventMask | CWDontPropagate;
    XChangeWindowAttributes(x11_state.display, x11_state.menu, valuemask, &menu_attributes);
    XMapWindow(x11_state.display, x11_state.menu);
#endif

    button_state.button = static_cast<t_button *>(my_malloc(NUM_STANDARD_BUTTONS * sizeof (t_button)));

    /* Now do the arrow buttons */
    bwid = 28;
    space = 3;
    y1 = 10;
    xcen = 51;
    x1 = xcen - bwid / 2;
    button_state.button[0].xleft = x1;
    button_state.button[0].ytop = y1;
#ifdef X11
    setpoly(0, bwid / 2, bwid / 2, bwid / 3, -PI / 2.); /* Up */
#else
    button_state.button[0].type = BUTTON_TEXT;
#endif
    strcpy(button_state.button[0].text, "U");
    button_state.button[0].fcn = translate_up;

    y1 += bwid + space;
    x1 = xcen - 3 * bwid / 2 - space;
    button_state.button[1].xleft = x1;
    button_state.button[1].ytop = y1;
#ifdef X11
    setpoly(1, bwid / 2, bwid / 2, bwid / 3, PI); /* Left */
#else
    button_state.button[1].type = BUTTON_TEXT;
#endif
    strcpy(button_state.button[1].text, "L");
    button_state.button[1].fcn = translate_left;

    x1 = xcen + bwid / 2 + space;
    button_state.button[2].xleft = x1;
    button_state.button[2].ytop = y1;
#ifdef X11
    setpoly(2, bwid / 2, bwid / 2, bwid / 3, 0); /* Right */
#else
    button_state.button[2].type = BUTTON_TEXT;
#endif
    strcpy(button_state.button[2].text, "R");
    button_state.button[2].fcn = translate_right;

    y1 += bwid + space;
    x1 = xcen - bwid / 2;
    button_state.button[3].xleft = x1;
    button_state.button[3].ytop = y1;
#ifdef X11
    setpoly(3, bwid / 2, bwid / 2, bwid / 3, +PI / 2.); /* Down */
#else
    button_state.button[3].type = BUTTON_TEXT;
#endif
    strcpy(button_state.button[3].text, "D");
    button_state.button[3].fcn = translate_down;

    for (i = 0; i < NUM_ARROW_BUTTONS; i++) {
        button_state.button[i].width = bwid;
        button_state.button[i].height = bwid;
        button_state.button[i].enabled = true;
    }

    /* Rectangular buttons */

    y1 += bwid + space + 6;
    space = 8;
    bwid = 90;
    bheight = 26;
    x1 = xcen - bwid / 2;
    for (i = NUM_ARROW_BUTTONS; i < NUM_STANDARD_BUTTONS; i++) {
        button_state.button[i].xleft = x1;
        button_state.button[i].ytop = y1;
        button_state.button[i].type = BUTTON_TEXT;
        button_state.button[i].width = bwid;
        button_state.button[i].enabled = true;
        if (i != SEPARATOR_BUTTON_INDEX) {
            button_state.button[i].height = bheight;
            y1 += bheight + space;
        } else {
            button_state.button[i].height = 2;
            button_state.button[i].type = BUTTON_SEPARATOR;
            y1 += 2 + space;
        }
    }

    strcpy(button_state.button[4].text, "Zoom In");
    strcpy(button_state.button[5].text, "Zoom Out");
    strcpy(button_state.button[6].text, "Zoom Fit");
    strcpy(button_state.button[7].text, "Window");
    strcpy(button_state.button[8].text, "---1");
    strcpy(button_state.button[9].text, "PostScript");
    strcpy(button_state.button[10].text, "Proceed");
    strcpy(button_state.button[11].text, "Exit");

    button_state.button[4].fcn = zoom_in;
    button_state.button[5].fcn = zoom_out;
    button_state.button[6].fcn = zoom_fit;
    button_state.button[7].fcn = adjustwin; // see 'adjustButton' below in WIN32 section
    button_state.button[8].fcn = nullptr;
    button_state.button[9].fcn = postscript;
    button_state.button[10].fcn = proceed;
    button_state.button[11].fcn = quit;

    for (i = 0; i < NUM_STANDARD_BUTTONS; i++)
        map_button(i);
    button_state.num_buttons = NUM_STANDARD_BUTTONS;

#ifdef WIN32
    win32_state.adjustButton = 7;
    if (!InvalidateRect(win32_state.hButtonsWnd, NULL, TRUE))
        WIN32_DRAW_ERROR();
    if (!UpdateWindow(win32_state.hButtonsWnd))
        WIN32_DRAW_ERROR();
#endif
}

/* Return information useful for debugging.
 * Used to return the top-level window object too, but that made graphics.h
 * export all windows and X11 headers to the client program, so VB deleted
 * that object (mainwnd) from this structure.
 */
void get_report_structure(t_report *report) {
    report->xmult = trans_coord.wtos_xmult;
    report->ymult = trans_coord.wtos_ymult;
    report->xleft = trans_coord.xleft;
    report->xright = trans_coord.xright;
    report->ytop = trans_coord.ytop;
    report->ybot = trans_coord.ybot;
    report->ps_xmult = trans_coord.ps_xmult;
    report->ps_ymult = trans_coord.ps_ymult;
    report->top_width = trans_coord.top_width;
    report->top_height = trans_coord.top_height;
}

void set_mouse_move_input(bool enable) {
    gl_state.get_mouse_move_input = enable;
}

void set_keypress_input(bool enable) {
    gl_state.get_keypress_input = enable;
}

void enable_or_disable_button(int ibutton, bool enabled) {

    if (button_state.button[ibutton].type != BUTTON_SEPARATOR) {
        button_state.button[ibutton].enabled = enabled;
#ifdef WIN32
        EnableWindow(button_state.button[ibutton].hwnd, button_state.button[ibutton].enabled);
#else  // X11
        x11_drawbut(ibutton);
        XFlush(x11_state.display);
#endif
    }
}

void set_draw_mode(enum e_draw_mode draw_mode) {
    /* Set normal (overwrite) or xor (useful for rubber-banding)
     * drawing mode.
     */

    if (draw_mode == DRAW_NORMAL) {
#ifdef X11
        x11_state.current_gc = x11_state.gc_normal;
#else
        if (!SetROP2(win32_state.hGraphicsDC, R2_COPYPEN))
            WIN32_SELECT_ERROR();
#endif
    } else { // DRAW_XOR
#ifdef X11
        x11_state.current_gc = x11_state.gc_xor;
#else
        if (!SetROP2(win32_state.hGraphicsDC, R2_XORPEN))
            WIN32_SELECT_ERROR();
#endif
    }
    // We've changed which graphics context is active. Make sure the
    // current graphics drawing state is applied to the active context.
    force_setcolor(gl_state.foreground_color);
    force_setlinestyle(gl_state.currentlinestyle, gl_state.currentlinecap);
    force_setlinewidth(gl_state.currentlinewidth);
    gl_state.current_draw_mode = draw_mode;
}

void change_button_text(const char *button_name, const char *new_button_text) {
    /* Change the text on a button with button_name to new_button_text.
     * Not a strictly necessary function, since you could intead just
     * destroy button_name and make a new buton.
     */
    int i, bnum;

    bnum = -1;

    for (i = 4; i < button_state.num_buttons; i++) {
        if (button_state.button[i].type == BUTTON_TEXT &&
            strcmp(button_state.button[i].text, button_name) == 0) {
            bnum = i;
            break;
        }
    }

    if (bnum != -1) {
        strncpy(button_state.button[i].text, new_button_text, BUTTON_TEXT_LEN);
        button_state.button[i].text[BUTTON_TEXT_LEN-1] = '\0'; //Ensure null terimination
#ifdef X11
        x11_drawbut(i);
#else // Win32
        wchar_t* WIN32_wchar_button_text = new wchar_t[BUTTON_TEXT_LEN];
        MultiByteToWideChar(CP_UTF8, 0, new_button_text, -1,
            WIN32_wchar_button_text, BUTTON_TEXT_LEN);

        SetWindowTextW(button_state.button[bnum].hwnd, WIN32_wchar_button_text);

        delete[] WIN32_wchar_button_text;
#endif
    }
}


/***********************************************
 * begin offscreen buffer function definitions *
 ***********************************************/

void set_drawing_buffer(t_draw_to draw_mode) {
#ifdef X11
    if (draw_mode == ON_SCREEN) {
        x11_state.draw_area = &(x11_state.toplevel);
        x11_state.draw_area_draw = x11_state.toplevel_draw;
        init_cairo();
    }
    else if (draw_mode == OFF_SCREEN) {
        x11_state.draw_area = &(x11_state.draw_buffer);
        x11_state.draw_area_draw = x11_state.draw_buffer_draw;
        init_cairo();
    }
    else {
        cerr << "New draw mode not yet supported in set_drawing_buffer" << endl;
    }
    gl_state.current_draw_to = draw_mode;
#endif /* X11 */

#ifdef WIN32	// https://www.gamedev.net/topic/411559-win32-double-buffering/, http://stackoverflow.com/questions/14153387/double-buffering-win32-c, http://stackoverflow.com/questions/3895305/winapi-double-buffering
	static HDC bufDC = CreateCompatibleDC(win32_state.hGraphicsDC);
	HBITMAP bufBMP = CreateCompatibleBitmap(win32_state.hGraphicsDC, trans_coord.top_width, trans_coord.top_height);
	if (draw_mode == ON_SCREEN)
	{
		if (win32_state.hGraphicsDC == bufDC)
		{
			SelectObject(win32_state.hGraphicsDCPassive, win32_state.hGraphicsPassive);
			// Swap and select draw buffer
			win32_state.hGraphicsDC = win32_state.hGraphicsDCPassive;
			win32_state.hGraphicsDCPassive = bufDC;
		}
	}
	else if (draw_mode == OFF_SCREEN)
	{
		if (win32_state.hGraphicsDC != bufDC)
		{
			// Swap and select draw buffer
			win32_state.hGraphicsDCPassive = win32_state.hGraphicsDC;
			win32_state.hGraphicsDC = bufDC;
			win32_state.hGraphicsPassive = SelectObject(bufDC, bufBMP);
		}
	}

#endif /* WIN32 */
}

void copy_off_screen_buffer_to_screen() {
#ifdef X11
    if (x11_state.draw_area != &x11_state.draw_buffer) return;

    XCopyArea(x11_state.display, x11_state.draw_buffer, x11_state.toplevel, x11_state.current_gc,
            0, 0, x11_state.attributes.width, x11_state.attributes.height, 0, 0);

    cairo_xlib_surface_set_size(
            x11_state.cairo_surface,
            x11_state.attributes.width,
            x11_state.attributes.height);

    XFlush(x11_state.display);
#endif /* X11 */

#ifdef WIN32
	BitBlt(win32_state.hGraphicsDCPassive, 0, 0, trans_coord.top_width, trans_coord.top_height, win32_state.hGraphicsDC, 0, 0, SRCCOPY);
#endif	// <Addition/Mod: Charles>
}

/*************************************************
 * begin loading and drawing from file functions *
 *************************************************/
#ifndef WIN32
Surface load_png_from_file(const char* file_path) {
    return Surface(file_path);
}

void draw_surface(const Surface& surface, float x, float y) {
    cairo_surface_t* cairo_surface = surface.impl_->getSurface();
    if (cairo_surface != nullptr) {
        cairo_set_source_surface(x11_state.ctx, cairo_surface,
                xworld_to_scrn(x), yworld_to_scrn(y));
        cairo_paint(x11_state.ctx);
    }
    else {
        cerr << "Surface was not initialized" << endl;
    }
}

void draw_surface(const Surface& surface, t_point upper_left) {
    draw_surface (surface, upper_left.x, upper_left.y);
}

/***********************************************
 * begin cairo functions                       *
 ***********************************************/

static void init_cairo() {
#ifdef X11
    // Destroy old cairo things
    cairo_destroy(x11_state.ctx);
    cairo_surface_destroy(x11_state.cairo_surface);

    // Create new cairo things and set attributes
    x11_state.cairo_surface = cairo_xlib_surface_create(
            x11_state.display,
            *x11_state.draw_area,
            x11_state.visual_info.visual,
            x11_state.attributes.width, x11_state.attributes.height);
    cairo_xlib_surface_set_size(x11_state.cairo_surface, x11_state.attributes.width, x11_state.attributes.height);
    x11_state.ctx = cairo_create(x11_state.cairo_surface);
    cairo_set_antialias(x11_state.ctx, CAIRO_ANTIALIAS_NONE); // Turn off anti-aliasing
#endif // X11
}
#endif // !WIN32 <Modification>

/*
 * Functions that are helpful for automarking below. Call before the student
 * could possibly call event_loop
 */

void set_disable_event_loop (bool new_setting) {
    gl_state.disable_event_loop = new_setting;
}


void set_redirect_to_postscript (bool new_setting) {
    gl_state.redirect_to_postscript = new_setting;
}


/**********************************
 * X-Windows Specific Definitions *
 *********************************/
#ifdef X11

/* Helper function called by init_graphics(). Not visible to client program. */
static void x11_init_graphics(const char *window_name) {
    char *display_name = nullptr;
    int x, y; /* window position */
    unsigned int border_width = 2; /* ignored by OpenWindows */
    XTextProperty windowName;

    unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
    XGCValues values;
    XEvent event;

    /* connect to X server */
    if ((x11_state.display = XOpenDisplay(display_name)) == nullptr) {
        fprintf(stderr, "Cannot connect to X server %s\n",
            XDisplayName(display_name));
        exit(-1);
    }

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"  // Old style casts in these macros.
    /* get screen size from display structure macro */
    x11_state.screen_num = DefaultScreen(x11_state.display);
    trans_coord.display_width = DisplayWidth(x11_state.display, x11_state.screen_num);
    trans_coord.display_height = DisplayHeight(x11_state.display, x11_state.screen_num);
#pragma GCC diagnostic pop

    x = 0;
    y = 0;

    // Initial window will take 80% of the screen width & height (change if desired)
    trans_coord.top_width = 4 * trans_coord.display_width / 5;
    trans_coord.top_height = 4 * trans_coord.display_height / 5;

    // select a 24 bit TrueColor visual. Note that setting this visual
    // for the top level window will make all children inherit it.
    if (XMatchVisualInfo(
        x11_state.display,
        x11_state.screen_num,
        24, TrueColor,
        &x11_state.visual_info) == 0) {
        fprintf(stderr, "Warning failed to find 24-bit TrueColor visual\n");
        fprintf(stderr, "  Graphics may not draw correctly\n");
    }

    Window root_window = XDefaultRootWindow(x11_state.display);

    x11_state.colormap_to_use = XCreateColormap(
        x11_state.display,
        root_window,
        x11_state.visual_info.visual,
        AllocNone
        );

    XSetWindowAttributes attrs;
    attrs.colormap = x11_state.colormap_to_use;
    attrs.border_pixel = x11_convert_to_xcolor(t_color::predef_colors[BLACK]);
    attrs.background_pixel = x11_convert_to_xcolor(gl_state.background_color);

    x11_state.toplevel = XCreateWindow(
        x11_state.display,
        root_window,
        x, y,
        trans_coord.top_width, trans_coord.top_height,
        border_width,
        x11_state.visual_info.depth,
        InputOutput,
        x11_state.visual_info.visual,
        CWBackPixel | CWColormap | CWBorderPixel,
        &attrs
        );

    x11_state.toplevel_draw = XftDrawCreate(
        x11_state.display,
        x11_state.toplevel,
        x11_state.visual_info.visual,
        x11_state.colormap_to_use
        );

    XRenderColor xr_textcolor;
    xr_textcolor.red = 0x0;
    xr_textcolor.green = 0x0;
    xr_textcolor.blue = 0x0;
    xr_textcolor.alpha = 0xffff;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"  // Old style casts in these macros.
    XftColorAllocValue(
        x11_state.display,
        DefaultVisual(x11_state.display, x11_state.screen_num),
        DefaultColormap(x11_state.display, x11_state.screen_num),
        &xr_textcolor,
        &x11_state.xft_menutextcolor
        );
#pragma GCC diagnostic pop

    XSelectInput(x11_state.display, x11_state.toplevel, ExposureMask | StructureNotifyMask |
        ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
        KeyPressMask);

    /* Create default Graphics Contexts.  valuemask = 0 -> use defaults. */
    x11_state.current_gc = x11_state.gc_normal = XCreateGC(x11_state.display, x11_state.toplevel,
        valuemask, &values);
    x11_state.gc_menus = XCreateGC(x11_state.display, x11_state.toplevel, valuemask, &values);

    /* Create XOR graphics context for Rubber Banding */
    values.function = GXxor;
    values.foreground = x11_convert_to_xcolor(gl_state.background_color);
    x11_state.gc_xor = XCreateGC(x11_state.display, x11_state.toplevel, (GCFunction | GCForeground),
        &values);

    /* Initialize draw_buffer for XDraw calls and XftDraw calls */
    // get window attributes
    XGetWindowAttributes(x11_state.display, x11_state.toplevel, &(x11_state.attributes));
    x11_state.draw_buffer = XCreatePixmap(x11_state.display, x11_state.toplevel,
        x11_state.attributes.width, x11_state.attributes.height, x11_state.attributes.depth);
    x11_state.draw_buffer_draw = XftDrawCreate(
        x11_state.display,
        x11_state.draw_buffer,
        x11_state.visual_info.visual,
        x11_state.colormap_to_use
    );

    // initialize draw_area to screen
    set_drawing_buffer(ON_SCREEN);

    /* Set drawing defaults for user-drawable area.  Use whatever the *
     * initial values of the current stuff was set to.                */
    force_settextattrs(gl_state.currentfontsize, gl_state.currentfontrotation);
    force_setcolor(gl_state.foreground_color);
    force_setlinestyle(gl_state.currentlinestyle);
    force_setlinewidth(gl_state.currentlinewidth);

    // Need a non-const name to pass to XStringListTo...
    // (even though X11 won't change it).
    char *window_name_copy = static_cast<char *>(my_malloc(BUFSIZE * sizeof (char)));
    strncpy(window_name_copy, window_name, BUFSIZE);
    XStringListToTextProperty(&window_name_copy, 1, &windowName);
    free(window_name_copy);
    window_name_copy = nullptr;

    XSetWMName(x11_state.display, x11_state.toplevel, &windowName);
    /* XSetWMIconName (x11_state.display, x11_state.toplevel, &windowName); */

    /* XStringListToTextProperty copies the window_name string into            *
     * windowName.value.  Free this memory now.                                */

    free(windowName.value);

    XMapWindow(x11_state.display, x11_state.toplevel);
    x11_build_textarea();
    build_default_menu();

    /* The following is completely unnecessary if the user is using the       *
     * interactive (event_loop) graphics.  It waits for the first Expose      *
     * event before returning so that I can tell the window manager has got   *
     * the top-level window up and running.  Thus the user can start drawing  *
     * into this window immediately, and there's no danger of the window not  *
     * being ready and output being lost.                                     */
    XPeekIfEvent(x11_state.display, &event, x11_test_if_exposed, nullptr);
    force_settextattrs(gl_state.currentfontsize, gl_state.currentfontrotation);
}

/* Helper function called by event_loop(). Not visible to client program. */
static void
x11_event_loop(void (*act_on_mousebutton)(float x, float y, t_event_buttonPressed button_info),
    void (*act_on_mousemove)(float x, float y),
    void (*act_on_keypress)(char key_pressed, int keysym),
    void (*drawscreen) ()) {
    XEvent report;
    unsigned int last_skipped_button_press_button = -1;
    int bnum;
    float x, y;

    Atom wmDeleteMessage = XInternAtom(x11_state.display, "WM_DELETE_WINDOW", false);
    XSetWMProtocols(x11_state.display, x11_state.toplevel, &wmDeleteMessage, 1);

#define OFF 1
#define ON 0

    x11_turn_on_off(ON);
    while (true) {

        XSync(x11_state.display, false);
        XNextEvent(x11_state.display, &report);
#ifdef VERBOSE
        cout << "Got an event of type: " << report.type << endl;
#endif

        if (x11_drop_redundant_panning (report, last_skipped_button_press_button))
            continue;  // Drop this event

        switch (report.type) {
            case Expose:
#ifdef VERBOSE
                cout << "Got an Expose event with xexpose.count = " << report.xexpose.count << endl;
#endif
                x11_handle_expose(report, drawscreen);
                break;
            case ConfigureNotify:
#ifdef VERBOSE
                cout << "Got a ConfigureNotify event\n";
#endif
                x11_handle_configure_notify(report, drawscreen);
                break;
            case ButtonPress:
#ifdef VERBOSE
                printf("Got a ButtonPress.\n");
                printf("Window ID is: %ld.\n", report.xbutton.window);
                printf("Button pressed is: %d.\n(left click is 1; right click is 3; "
                    "scroll wheel click is 2; scroll wheel forward rotate is 4; "
                    "scroll wheel backward is 5.)\n", report.xbutton.button);
                printf("Mask is: %d.\n", report.xbutton.state);
#endif
                if (report.xbutton.window == x11_state.toplevel) {
                    x = xscrn_to_world(report.xbutton.x);
                    y = yscrn_to_world(report.xbutton.y);

                    t_event_buttonPressed button_info;
                    /* t_event_buttonPressed is used as a structure for storing information about a	  *
                     * button press event. This information can be passed back to and used by a client*
                     * program.                                                                      */
                    x11_handle_button_info(&button_info, report.xbutton.button, report.xbutton.state);
#ifdef VERBOSE
                    if (button_info.shift_pressed == true) {
                        printf("Shift is pressed at button press.\n");
                    }
                    if (button_info.ctrl_pressed == true) {
                        printf("Ctrl is pressed at button press.\n");
                    }
#endif
                    switch (report.xbutton.button) {
                        case Button1: /* Left mouse click; pass back to client program */
                        case Button3: /* Right mouse click; pass back to client program */
                            /* Pass information about the button press to client program */
                            if (act_on_mousebutton != nullptr) // If callback was set
                                act_on_mousebutton(x, y, button_info);
                            break;
                        case Button2: /* Scroll wheel pressed; start panning */
                            panning_on(report.xbutton.x, report.xbutton.y);
                            break;
                        case Button4: /* Scroll wheel rotated forward; screen does zoom_in */
                            // note, this is also called in the skipping logic
                            handle_zoom_in(x, y, drawscreen);
                            break;
                        case Button5: /* Scroll wheel rotated backward; screen does zoom_out */
                            // note, this is also called in the skipping logic
                            handle_zoom_out(x, y, drawscreen);
                            break;
                        default:
                            break;  // Unknown button: ignore.
                    }
                } else { /* A menu button was pressed. */
                    bnum = x11_which_button(report.xbutton.window);
#ifdef VERBOSE
                    printf("Button number is %d\n", bnum);
#endif
                    if (button_state.button[bnum].enabled) {
                        button_state.button[bnum].ispressed = true;
                        x11_drawbut(bnum);
                        XFlush(x11_state.display); /* Flash the button */
                        button_state.button[bnum].fcn(drawscreen);
                        button_state.button[bnum].ispressed = false;
                        x11_drawbut(bnum);
                        if (button_state.button[bnum].fcn == proceed) {
                            x11_turn_on_off(OFF);
                            flushinput();
                            return; /* Rather clumsy way of returning *
						* control to the simulator       */
                        }
                    }
                }
                break;
            case ButtonRelease:
#ifdef VERBOSE
                printf("Got a ButtonRelease.\n");
                printf("Window ID is: %ld.\n", report.xbutton.window);
                printf("Button released is: %d.\n(left click is 1; right click is 3; "
                    "scroll wheel click is 2; scroll wheel forward rotate is 4; "
                    "scroll wheel backward is 5.)\n", report.xbutton.button);
                printf("Mask is: %d.\n", report.xbutton.state);
#endif
                switch (report.xbutton.button) {
                    case Button2: /* Scroll wheel released; stop panning */
                        panning_off();
                        break;
                    default:
                        break;
                }
                break;
            case MotionNotify:
#ifdef VERBOSE
//                printf("Got a MotionNotify Event.\n");
//                printf("x: %d    y: %d\n", report.xmotion.x, report.xmotion.y);
#endif
                if (pan_state.panning_enabled)
                    panning_execute(report.xmotion.x, report.xmotion.y, drawscreen);
                else if (gl_state.get_mouse_move_input &&
                        act_on_mousemove != nullptr &&
                        report.xmotion.x <= trans_coord.top_width - MWIDTH &&
                        report.xmotion.y <= trans_coord.top_height - T_AREA_HEIGHT)
                    act_on_mousemove(xscrn_to_world(report.xmotion.x), yscrn_to_world(report.xmotion.y));
                break;
            case KeyPress:
#ifdef VERBOSE
                printf("Got a KeyPress Event.\n");
#endif
                if (gl_state.get_keypress_input) {
                    char keyb_buffer[20];
                    XComposeStatus composestatus;
                    KeySym keysym;
                    int length, max_bytes;

                    max_bytes = 1;

                    length = XLookupString(&report.xkey, keyb_buffer, max_bytes, &keysym,
                        &composestatus);
#ifdef VERBOSE
                    cout << "char: " << keyb_buffer[0] << " char as int: " << (int) keyb_buffer[0]
                                      << " keysym: " << keysym << endl;
#endif

                    keyb_buffer[length] = '\0'; /* terminating NULL */
                    if (act_on_keypress != nullptr)
                        act_on_keypress(keyb_buffer[0], keysym);
                }

                break;
            case ClientMessage:
                if (static_cast<int>(report.xclient.data.l[0]) == static_cast<int>(wmDeleteMessage)) {
                    // Close button has been clicked
#ifdef VERBOSE
                    std::cout << "Window close requested" << std::endl;
#endif
                    gl_state.ProceedPressed = true;
                    flushinput();
                    return;
                }
                break;

            default:
                break;  // Ignore other events
        }
    }
}


// X11 drop redundant panning event explanation:
// When the user holds down the middle mouse button and pans, or scrolls
// using the scroll wheel, we can get events faster than we can redraw.
// This routine will drop events which match is_droppable_event(...), and are
// followed by another event which matches is_droppable_event(...).
// There are appropriate calls to XSync to make sure that this application
// has all of it's pending events in its queue. In X11, scrolls are
// like button presses - they have press *and release* events. There is
// logic to ignore the release event in the case where it's already dropped
// the press one.
// If this routine returns true, the event loop should drop an event (not
// process the event passed into this routine). If this routine returns false,
// the calling routine should process the event in report.
static bool x11_drop_redundant_panning (const XEvent& report,
               unsigned int& last_skipped_button_press_button) {

   if (is_droppable_event(&report) && XQLength(x11_state.display) > 0) {
        if (report.type == ButtonPress) {
            last_skipped_button_press_button = report.xbutton.button;
        }
        // if the current event is droppable, and there are more events
        // in the queue, check to see if the next event is droppable too.
        XEvent next_event;
        XPeekEvent(x11_state.display, &next_event);
        // if the next event is a matching ButtonRelease, then drop
        // it too, but only if the queue has more events still.
        if (next_event.type == ButtonRelease
            && next_event.xbutton.button == last_skipped_button_press_button
            && XQLength(x11_state.display) > 1) {

            XSync(x11_state.display, false);
            XNextEvent(x11_state.display, &next_event);
            XPeekEvent(x11_state.display, &next_event);
            last_skipped_button_press_button = -1;
        }
        if (is_droppable_event(&next_event)) {
            // if so, skip this event.
            if (report.type == ButtonPress) {
                float x = xscrn_to_world(report.xbutton.x);
                float y = yscrn_to_world(report.xbutton.y);
                switch (report.xbutton.button) {
                    case Button4:
                        handle_zoom_in(x, y, nullptr); // (same function as normal event logic)
                        break;
                    case Button5:
                        handle_zoom_out(x, y, nullptr); // (same function as normal event logic)
                        break;
                    default:
                        // do nothing, also should be impossible
                        // (we don't want to skip mouse presses)
                        break;
                }
            }
            return (true);  // Calling routine should drop the event in report.
        }
    }
    return (false);  // Calling routine should process the event in report.
}


/* Creates a small window at the top of the graphics area for text messages */
static void x11_build_textarea() {
    XSetWindowAttributes menu_attributes;
    unsigned long valuemask;

    x11_state.textarea = XCreateSimpleWindow(x11_state.display, x11_state.toplevel, 0,
        trans_coord.top_height - T_AREA_HEIGHT, trans_coord.display_width - MWIDTH,
        T_AREA_HEIGHT, 0, x11_convert_to_xcolor(t_color::predef_colors[BLACK]),
        x11_convert_to_xcolor(t_color::predef_colors[LIGHTGREY]));

    x11_state.textarea_draw = XftDrawCreate(
        x11_state.display,
        x11_state.textarea,
        x11_state.visual_info.visual,
        x11_state.colormap_to_use
        );

    menu_attributes.event_mask = ExposureMask;
//    menu_attributes.event_mask = 0;
    /* ButtonPresses in this area are ignored. */
    menu_attributes.do_not_propagate_mask = ButtonPressMask;
    /* Keep text area on bottom left */
    menu_attributes.win_gravity = SouthWestGravity;
    valuemask = CWWinGravity | CWEventMask | CWDontPropagate;
    XChangeWindowAttributes(x11_state.display, x11_state.textarea, valuemask, &menu_attributes);
    XMapWindow(x11_state.display, x11_state.textarea);
}

/* Returns True if the event passed in is an exposure event. Note that
 * the bool type returned by this function is defined in Xlib.h.
 */
static Bool x11_test_if_exposed(Display *disp, XEvent *event_ptr, XPointer dummy) {
    (void) disp; // suppress unused warning
    (void) dummy; // suppress unused warning
    if (event_ptr->type == Expose) {
        return (True);
    }

    return (False);
}

/* draws UTF-8 text center at xc, yc -- used only by menu and button drawing stuff */
static void menutext(XftDraw* draw, int xc, int yc, const char *text) {
    int len, width;

    font_ptr menu_font = gl_state.font_info.get_font_info(MENU_FONT_SIZE, 0);

    len = strlen(text);
    XGlyphInfo extents;
    XftTextExtentsUtf8(
        x11_state.display,
        menu_font,
        reinterpret_cast<const FcChar8*>(text),
        len,
        &extents
        );
    width = extents.width;

    XftDrawStringUtf8(
        draw,
        &x11_state.xft_menutextcolor,
        menu_font,
        xc - width / 2,
        yc + (menu_font->ascent
        - menu_font->descent) / 2,
        reinterpret_cast<const FcChar8*>(text),
        len
        );
}

/* Draws button bnum in either its pressed or unpressed state.    */
static void x11_drawbut(int bnum) {
    int width, height, thick, i, ispressed;
    XPoint mypoly[6];

    width = button_state.button[bnum].width;
    height = button_state.button[bnum].height;

    if (button_state.button[bnum].type == BUTTON_SEPARATOR) {
        int x, y;

        x = button_state.button[bnum].xleft;
        y = button_state.button[bnum].ytop;
        XSetForeground(x11_state.display, x11_state.gc_menus,
                  x11_convert_to_xcolor(t_color::predef_colors[WHITE]));
        XDrawLine(x11_state.display, x11_state.menu, x11_state.gc_menus, x, y + 1, x + width, y + 1);
        XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[BLACK]) );
        XDrawLine(x11_state.display, x11_state.menu, x11_state.gc_menus, x, y, x + width, y);
        return;
    }

    ispressed = button_state.button[bnum].ispressed;
    thick = 2;
    /* Draw top and left edges of 3D box. */
    if (ispressed) {
        XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[BLACK]));
    } else {
        XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[WHITE]));
    }

    /* Note:  X Windows doesn't appear to draw the bottom pixel of *
     * a polygon with XFillPolygon, so I make this 1 pixel thicker *
     * to compensate.                                              */
    mypoly[0].x = 0;
    mypoly[0].y = height;
    mypoly[1].x = 0;
    mypoly[1].y = 0;
    mypoly[2].x = width;
    mypoly[2].y = 0;
    mypoly[3].x = width - thick;
    mypoly[3].y = thick;
    mypoly[4].x = thick;
    mypoly[4].y = thick;
    mypoly[5].x = thick;
    mypoly[5].y = height - thick;
    XFillPolygon(x11_state.display, button_state.button[bnum].win, x11_state.gc_menus, mypoly, 6, Convex,
        CoordModeOrigin);

    /* Draw bottom and right edges of 3D box. */
    if (ispressed) {
        XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[WHITE]));
    } else {
        XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[BLACK]));
    }
    mypoly[0].x = 0;
    mypoly[0].y = height;
    mypoly[1].x = width;
    mypoly[1].y = height;
    mypoly[2].x = width;
    mypoly[2].y = 0;
    mypoly[3].x = width - thick;
    mypoly[3].y = thick;
    mypoly[4].x = width - thick;
    mypoly[4].y = height - thick;
    mypoly[5].x = thick;
    mypoly[5].y = height - thick;
    XFillPolygon(x11_state.display, button_state.button[bnum].win, x11_state.gc_menus, mypoly, 6, Convex,
        CoordModeOrigin);

    /* Draw background */
    if (ispressed) {
        XSetForeground(x11_state.display, x11_state.gc_menus,
            x11_convert_to_xcolor(t_color::predef_colors[DARKGREY])
            );
    } else {
        XSetForeground(x11_state.display, x11_state.gc_menus,
            x11_convert_to_xcolor(t_color::predef_colors[LIGHTGREY])
            );
    }

    /* Give x,y of top corner and width and height */
    XFillRectangle(x11_state.display, button_state.button[bnum].win, x11_state.gc_menus, thick, thick,
        width - 2 * thick, height - 2 * thick);

    /* Draw polygon, if there is one */
    if (button_state.button[bnum].type == BUTTON_POLY) {
        for (i = 0; i < 3; i++) {
            mypoly[i].x = button_state.button[bnum].poly[i][0];
            mypoly[i].y = button_state.button[bnum].poly[i][1];
        }
        XSetForeground(x11_state.display, x11_state.gc_menus,
            x11_convert_to_xcolor(t_color::predef_colors[BLACK])
            );
        XFillPolygon(x11_state.display, button_state.button[bnum].win,
            x11_state.gc_menus, mypoly, 3, Convex, CoordModeOrigin);
    }

    /* Draw text, if there is any */
    if (button_state.button[bnum].type == BUTTON_TEXT) {
        if (button_state.button[bnum].enabled) {
            XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[BLACK])
                );
        } else {
            XSetForeground(x11_state.display, x11_state.gc_menus,
                x11_convert_to_xcolor(t_color::predef_colors[DARKGREY])
                );
        }
        menutext(button_state.button[bnum].draw, button_state.button[bnum].width / 2,
            button_state.button[bnum].height / 2, button_state.button[bnum].text);
    }
}

static int x11_which_button(Window win) {
    int i;

    for (i = 0; i < button_state.num_buttons; i++) {
        if (button_state.button[i].win == win)
            return (i);
    }
    printf("Error:  Unknown button ID in which_button.\n");
    return (0);
}

/* Shows when the menu is active or inactive by colouring the
 * buttons.
 */
static void x11_turn_on_off(int pressed) {
    int i;

    for (i = 0; i < button_state.num_buttons; i++) {
        button_state.button[i].ispressed = pressed;
        x11_drawbut(i);
    }
}

static void x11_drawmenu() {
    int i;

    XClearWindow(x11_state.display, x11_state.menu);
    XSetForeground(x11_state.display, x11_state.gc_menus,
            x11_convert_to_xcolor(t_color::predef_colors[WHITE]) );
    XDrawRectangle(x11_state.display, x11_state.menu, x11_state.gc_menus, 0, 0, MWIDTH,
        trans_coord.top_height);
    XSetForeground(x11_state.display, x11_state.gc_menus,
            x11_convert_to_xcolor(t_color::predef_colors[BLACK]) );
    XDrawLine(x11_state.display, x11_state.menu, x11_state.gc_menus, 0, trans_coord.top_height - 1,
        MWIDTH, trans_coord.top_height - 1);
    XDrawLine(x11_state.display, x11_state.menu, x11_state.gc_menus, MWIDTH - 1,
        trans_coord.top_height, MWIDTH - 1, 0);

    for (i = 0; i < button_state.num_buttons; i++) {
        x11_drawbut(i);
    }
}

static void x11_handle_expose(const XEvent& report, void (*drawscreen) ()) {
#ifdef VERBOSE
    printf("Got an expose event.\n");
    printf("Count is: %d.\n", report.xexpose.count);
    printf("Window ID is: %ld.\n", report.xexpose.window);
#endif

    if (report.xexpose.count != 0)
        return;  // More exposes coming.

    gl_state.redraw_needed = true;  // We will have to redraw eventually.
    x11_redraw_all_if_needed (drawscreen);
}


static void x11_redraw_all_if_needed (void (*drawscreen) ()) {
    // Only redraw if this is (the last Expose or ConfigureNotify
    // in a series (we sometimes get a lot for a window expose or size
    // change, and some have a count of 0). We redraw everything for all
    // exposes; trying to redraw only subwindows is problematic when we're
    // dropping expose events.
    if (XQLength(x11_state.display) > 0) {
        // Check if we have events waiting, and peek at them only if we do
        // XPeekEvent blocks if there are no events, and we don't want that.
        XEvent next_event;
        XPeekEvent(x11_state.display, &next_event);
        if (next_event.type == Expose || next_event.type == ConfigureNotify)
          return;
    }

    // We could get here via a code path that doesn't need a redraw (no expose yet).
    if (!gl_state.redraw_needed)
        return;


#ifdef VERBOSE
    cout << "Redrawing everything\n";
#endif

    // resize window attributes
    XGetWindowAttributes(x11_state.display, x11_state.toplevel, &(x11_state.attributes));
    // resize draw_buffer
    XFreePixmap(x11_state.display, x11_state.draw_buffer);
    XftDrawDestroy(x11_state.draw_buffer_draw);
    x11_state.draw_buffer = XCreatePixmap(x11_state.display, x11_state.toplevel,
            x11_state.attributes.width, x11_state.attributes.height, x11_state.attributes.depth);
    x11_state.draw_buffer_draw = XftDrawCreate(
            x11_state.display,
            x11_state.draw_buffer,
            x11_state.visual_info.visual,
            x11_state.colormap_to_use
        );
    // Update the pointers in the current drawing state to the new buffers and
    // init_cairo again.
    set_drawing_buffer(gl_state.current_draw_to);

    drawscreen();
    x11_drawmenu();
    draw_message();
    gl_state.redraw_needed = false;
}


static void x11_handle_configure_notify(const XEvent& report, void (*drawscreen) ()) {
    trans_coord.top_width = report.xconfigure.width;
    trans_coord.top_height = report.xconfigure.height;
    update_transform();

#ifdef VERBOSE
    printf("Got a ConfigureNotify.\n");
    printf("New width: %d  New height: %d.\n", trans_coord.top_width, trans_coord.top_height);
#endif

    x11_redraw_all_if_needed (drawscreen);
}

static void x11_handle_button_info(t_event_buttonPressed *button_info,
    int buttonNumber, int Xbutton_state) {

    button_info->button = buttonNumber;

    if (Xbutton_state & 1)
        button_info->shift_pressed = true;
    else
        button_info->shift_pressed = false;

    if (Xbutton_state & 4)
        button_info->ctrl_pressed = true;
    else
        button_info->ctrl_pressed = false;
}


static unsigned long x11_convert_to_xcolor (t_color rgb_color) {
    unsigned long xcolor = 0;
    uint_fast8_t red = rgb_color.red;
    uint_fast8_t green = rgb_color.green;
    uint_fast8_t blue = rgb_color.blue;
    //Some x11 machines return incorrect x11_state.visual_info.bits_per_rgb
    //(e.g. return 11 bits, but use 8 bit masks), so do all the conversions
    //based on the actual masks
    xcolor = shift_merge_based_on_mask(xcolor, red, x11_state.visual_info.red_mask);
    xcolor = shift_merge_based_on_mask(xcolor, green, x11_state.visual_info.green_mask);
    xcolor = shift_merge_based_on_mask(xcolor, blue, x11_state.visual_info.blue_mask);

    return (xcolor);
}

static unsigned long shift_merge_based_on_mask(unsigned long orig_value, unsigned long new_value, unsigned long new_mask) {
    //Shift the new value so it is aligned with the mask
    unsigned long new_shifted_value = new_value << find_first_set(new_mask);

    //Merge the shifted value in based on the mask
    return (orig_value & ~new_mask) | (new_shifted_value & new_mask);
}

static unsigned long find_first_set(unsigned long mask) {
    assert(mask != 0);

    //Naive algorithm, linear in the number of unset least significant bits
    //There are more efficient algorithms...
    unsigned long pos = 0;
    while (!(mask & 1)) { //bit is zero
        mask >>= 1;
        ++pos;
    }
    return pos;
}

#endif /* X-Windows Specific Definitions */


/*************************************************
 * Microsoft Windows (WIN32) Specific Definitions *
 *************************************************/
#ifdef WIN32

static void
win32_init_graphics(const char *window_name) {
    WNDCLASSW wndclass;
    HINSTANCE hInstance = GetModuleHandle(NULL);
    int x, y;
    LOGBRUSH lb;
    lb.lbStyle = BS_SOLID;
    lb.lbColor = convert_to_win_color(gl_state.foreground_color);
    lb.lbHatch = (LONG) NULL;
    x = 0;
    y = 0;

    /* get screen size from display structure macro */
    trans_coord.display_width = GetSystemMetrics(SM_CXSCREEN);
    if (!(trans_coord.display_width))
        WIN32_CREATE_ERROR();
    trans_coord.display_height = GetSystemMetrics(SM_CYSCREEN);
    if (!(trans_coord.display_height))
        WIN32_CREATE_ERROR();
    trans_coord.top_width = 2 * trans_coord.display_width / 3;
    trans_coord.top_height = 4 * trans_coord.display_height / 5;

    /* Copy the Application name */
    int text_byte_length = strlen(window_name);
    MultiByteToWideChar(CP_UTF8, 0, window_name, -1,
        szAppName, text_byte_length);

    win32_state.hGraphicsPen = ExtCreatePen(
        PS_GEOMETRIC | win32_line_styles[gl_state.currentlinestyle] | PS_ENDCAP_FLAT,
        1,
        &lb,
        (LONG) NULL,
        NULL
        );

    if (!win32_state.hGraphicsPen)
        WIN32_CREATE_ERROR();
    win32_state.hGraphicsBrush = CreateSolidBrush(convert_to_win_color(t_color::predef_colors[DARKGREY]));
    if (!win32_state.hGraphicsBrush)
        WIN32_CREATE_ERROR();
    win32_state.hGrayBrush = CreateSolidBrush(convert_to_win_color(t_color::predef_colors[LIGHTGREY]));
    if (!win32_state.hGrayBrush)
        WIN32_CREATE_ERROR();

    /* Register the Main Window class */
    wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wndclass.lpfnWndProc = WIN32_MainWND;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) CreateSolidBrush(
        convert_to_win_color(gl_state.background_color)
        );
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClassW(&wndclass)) {
        printf("Error code: %lu\n", GetLastError());
        MessageBoxW(NULL, L"Initialization of Windows graphics (init_graphics) failed.",
            szAppName, MB_ICONERROR);
        exit(-1);
    }

    /* Register the Graphics Window class */
    wndclass.lpfnWndProc = WIN32_GraphicsWND;
    wndclass.hIcon = NULL;
    wndclass.lpszClassName = szGraphicsName;

    if (!RegisterClassW(&wndclass))
        WIN32_DRAW_ERROR();

    /* Register the Status Window class */
    wndclass.lpfnWndProc = WIN32_StatusWND;
    wndclass.hIcon = NULL;
    wndclass.lpszClassName = szStatusName;
    wndclass.hbrBackground = win32_state.hGrayBrush;

    if (!RegisterClassW(&wndclass))
        WIN32_DRAW_ERROR();

    /* Register the Buttons Window class */
    wndclass.lpfnWndProc = WIN32_ButtonsWND;
    wndclass.hIcon = NULL;
    wndclass.lpszClassName = szButtonsName;
    wndclass.hbrBackground = win32_state.hGrayBrush;

    if (!RegisterClassW(&wndclass))
        WIN32_DRAW_ERROR();

    win32_state.hMainWnd = CreateWindowW(
        szAppName, szAppName,
        WS_OVERLAPPEDWINDOW, x, y, trans_coord.top_width,
        trans_coord.top_height, NULL, NULL, hInstance, NULL);

    if (!win32_state.hMainWnd)
        WIN32_DRAW_ERROR();

	/* Set drawing defaults for user-drawable area.  Use whatever the *
     * initial values of the current stuff was set to.                */
	if (ShowWindow(win32_state.hMainWnd, SW_SHOWNORMAL)) // Show if Window is not visible
		WIN32_DRAW_ERROR();
    build_default_menu();
    if (!UpdateWindow(win32_state.hMainWnd))
        WIN32_DRAW_ERROR();
    win32_drain_message_queue();
}

static LRESULT CALLBACK
WIN32_MainWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    MINMAXINFO FAR *lpMinMaxInfo;

    switch (message) {
        case WM_CREATE:
            win32_state.hStatusWnd = CreateWindowW(szStatusName, NULL, WS_CHILDWINDOW | WS_VISIBLE,
                0, 0, 0, 0, hwnd, (HMENU) 102, (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
            win32_state.hButtonsWnd = CreateWindowW(szButtonsName, NULL, WS_CHILDWINDOW | WS_VISIBLE,
                0, 0, 0, 0, hwnd, (HMENU) 103, (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
            win32_state.hGraphicsWnd = CreateWindowW(szGraphicsName, NULL, WS_CHILDWINDOW | WS_VISIBLE,
                0, 0, 0, 0, hwnd, (HMENU) 101, (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
            return 0;

        case WM_SIZE:
            /* Window has been resized.  Save the new client dimensions */
            trans_coord.top_width = LOWORD(lParam);
            trans_coord.top_height = HIWORD(lParam);

            /* Resize the children windows */
            if (!MoveWindow(win32_state.hGraphicsWnd, 1, 1, trans_coord.top_width - MWIDTH - 1,
                trans_coord.top_height - T_AREA_HEIGHT - 1, TRUE))
                WIN32_DRAW_ERROR();
            if (!MoveWindow(win32_state.hStatusWnd, 0, trans_coord.top_height - T_AREA_HEIGHT,
                trans_coord.top_width - MWIDTH, T_AREA_HEIGHT, TRUE))
                WIN32_DRAW_ERROR();
            if (!MoveWindow(win32_state.hButtonsWnd, trans_coord.top_width - MWIDTH, 0, MWIDTH,
                trans_coord.top_height, TRUE))
                WIN32_DRAW_ERROR();
            return 0;

            // WC : added to solve window resizing problem
        case WM_GETMINMAXINFO:
            // set the MINMAXINFO structure pointer
            lpMinMaxInfo = (MINMAXINFO FAR *) lParam;
            lpMinMaxInfo->ptMinTrackSize.x = trans_coord.display_width / 2;
            lpMinMaxInfo->ptMinTrackSize.y = trans_coord.display_height / 2;

            return 0;

        case WM_DESTROY:
            if (!DeleteObject(win32_state.hGrayBrush))
                WIN32_DELETE_ERROR();
            PostQuitMessage(0);
            return 0;

		case WM_CHAR:
        case WM_KEYDOWN:
            if (gl_state.get_keypress_input && win32_keypress_ptr != NULL)
                win32_keypress_ptr((char) wParam, 0);  // TODO: add extended (keysym) codes
            return 0;

            // Controls graphics: does zoom in or zoom out depending on direction of mousewheel scrolling.
            // Only the window with the input focus will receive this message. In our case, the top-level
            // window has the input focus, thus the code will not work if put in WIN32_GraphicsWND.
        case WM_MOUSEWHEEL:
            // t_event_buttonPressed is used as a structure for storing information about a mouse
            // button press event. This information can be passed back to and used by a client
            // program.
            t_event_buttonPressed button_info;
            win32_handle_button_info(button_info, message, wParam);
            win32_handle_mousewheel_zooming(wParam, lParam, true);
            return 0;

        case WM_TIMER:
            win32_drawscreen_ptr();
            // fall out.

		default: {} // For compiler warnings
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

static LRESULT CALLBACK
WIN32_GraphicsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
//    static TEXTMETRIC tm; /* Commented out as it was unused */

    PAINTSTRUCT ps;
    static RECT oldAdjustRect;
    static HPEN hDotPen = 0;
    static int X, Y;

    switch (message) {
        case WM_CREATE:

            /* Get the text metrics once upon creation (system font cannot change) */
            win32_state.hGraphicsDC = GetDC(hwnd);
            if (!win32_state.hGraphicsDC)
                WIN32_DRAW_ERROR();

            if (!SetBkMode(win32_state.hGraphicsDC, TRANSPARENT))
                WIN32_DRAW_ERROR();

            /* Setup the pens, etc */
            gl_state.currentlinestyle = SOLID;
            gl_state.foreground_color = t_color::predef_colors[BLACK];
            gl_state.currentlinewidth = 1;
            gl_state.currentfontsize = 12;
            return 0;

        case WM_PAINT:
            win32_GraphicsWND_handle_WM_PAINT(hwnd, ps, hDotPen, oldAdjustRect);
            return 0;

        case WM_SIZE:
            /* Window has been resized.  New client area dimensions can be retrieved from
             * lParam using LOWORD() and HIWORD() macros. */
            update_transform();
            return 0;

        case WM_DESTROY:
            if (!DeleteObject(win32_state.hGraphicsPen))
                WIN32_DELETE_ERROR();
            if (!DeleteObject(win32_state.hGraphicsBrush))
                WIN32_DELETE_ERROR();
            if (win32_state.hGraphicsFont != NULL && !DeleteObject(win32_state.hGraphicsFont))
                WIN32_DELETE_ERROR();
            PostQuitMessage(0);
            return 0;

            // left click and right click have the same functionality
        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
            win32_GraphicsWND_handle_WM_LRBUTTONDOWN(message, wParam, lParam, X, Y, oldAdjustRect);
            return 0;

            // If the mouse device has a scroll wheel, then this is a click of the wheel.
            // Enable panning by holding down the mouse wheel and drag.
        case WM_MBUTTONDOWN:
            win32_GraphicsWND_handle_WM_MBUTTONDOWN(hwnd, message, wParam, lParam);
            return 0;

            // Release the middle mouse button (mouse wheel) to stop panning
        case WM_MBUTTONUP:
            // turn off panning_enabled
            panning_off();

            /* Stops the mouse capturing started by SetCapture(). */
            ReleaseCapture();
            return 0;

        case WM_MOUSEMOVE:
            win32_GraphicsWND_handle_WM_MOUSEMOVE(lParam, X, Y, oldAdjustRect);
            return 0;

		default: {} // For compiler warnings
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

static void
win32_GraphicsWND_handle_WM_PAINT(HWND hwnd, PAINTSTRUCT &ps, HPEN &hDotPen, RECT &oldAdjustRect) {
    // was in xor mode, but got a general redraw.
    // switch to normal drawing so we repaint properly.
    if (gl_state.current_draw_mode == DRAW_XOR) {
        set_draw_mode(DRAW_NORMAL);
        win32_invalidate_screen();
        return;
    }
    BeginPaint(hwnd, &ps);
    if (!win32_state.hGraphicsDC)
        WIN32_DRAW_ERROR();

    if (win32_state.InEventLoop) {
        // if program was still executing the "Window" command and drawing rubber band

        if (win32_state.windowAdjustFlag == WAITING_FOR_SECOND_CORNER_POINT) {
            /* ps.rcPaint specifies the screen coordinates of the window's client area
             * in which drawing is requested. This information is used to indicate that
             * the application window has been minimized and then restored. If so, need
             * to redraw the screen before drawing new rubber band.
             */
            if (ps.rcPaint.right == (trans_coord.top_width - MWIDTH - 1)
                && ps.rcPaint.bottom == (trans_coord.top_height - T_AREA_HEIGHT - 1))
                win32_drawscreen_ptr();

            // Create pen for rubber band drawing
            hDotPen = CreatePen(PS_DASH, 1, convert_to_win_color(gl_state.background_color));
            if (!hDotPen)
                WIN32_CREATE_ERROR();
			// The "Passive" buffer should show the rubber band rectangle drawing
            if (!SetROP2(win32_state.hGraphicsDCPassive, R2_XORPEN))
                WIN32_SELECT_ERROR();
            if (!SelectObject(win32_state.hGraphicsDCPassive, GetStockObject(NULL_BRUSH)))
                WIN32_SELECT_ERROR();
            if (!SelectObject(win32_state.hGraphicsDCPassive, hDotPen))
                WIN32_SELECT_ERROR();

            // Don't need to erase old rubber band if the window has been minimized and
            // restored, because previous drawings were invalidated when the window was
            // minimized.
            if (ps.rcPaint.right != (trans_coord.top_width - MWIDTH - 1)
                || ps.rcPaint.bottom != (trans_coord.top_height - T_AREA_HEIGHT - 1)) {
                // Erase old rubber band before drawing a new one
                if (!Rectangle(win32_state.hGraphicsDCPassive, oldAdjustRect.left, oldAdjustRect.top,
                    oldAdjustRect.right, oldAdjustRect.bottom))
                    WIN32_DRAW_ERROR();
            }

            // Draw new rubber band
            if (!Rectangle(win32_state.hGraphicsDCPassive, win32_state.adjustRect.left,
                win32_state.adjustRect.top, win32_state.adjustRect.right,
                win32_state.adjustRect.bottom))
                WIN32_DRAW_ERROR();
            oldAdjustRect = win32_state.adjustRect;
            if (!SetROP2(win32_state.hGraphicsDC, R2_COPYPEN))
                WIN32_SELECT_ERROR();
            if (!SelectObject(win32_state.hGraphicsDC, GetStockObject(NULL_PEN)))
                WIN32_SELECT_ERROR();
            if (!DeleteObject(hDotPen))
                WIN32_DELETE_ERROR();
        } else {
            win32_drawscreen_ptr();
        }
    }
    EndPaint(hwnd, &ps);

    /* Crash hard if called at wrong time */
    /* win32_state.hGraphicsDC = NULL;*/
}

static void win32_GraphicsWND_handle_WM_LRBUTTONDOWN(UINT message, WPARAM wParam, LPARAM lParam,
    int &X, int &Y, RECT &oldAdjustRect) {
    // t_event_buttonPressed is used as a structure for storing information about a mouse
    // button press event. This information can be passed back to and used by a client
    // program.
    t_event_buttonPressed button_info;
    win32_handle_button_info(button_info, message, wParam);

    if (win32_state.windowAdjustFlag == WINDOW_DEACTIVATED) {
        // Call function in client program if the callback was set
        if (win32_mouseclick_ptr != NULL)
            win32_mouseclick_ptr(xscrn_to_world(LOWORD(lParam)), yscrn_to_world(HIWORD(lParam)),
                                button_info);
    } else {
        // Special handling for the "Window" command, which takes multiple clicks.
        // First you push the button, then you click for one corner, then you click for the other
        // corner.
        if (win32_state.windowAdjustFlag == WAITING_FOR_FIRST_CORNER_POINT) {
			win32_state.windowAdjustFlag = WAITING_FOR_SECOND_CORNER_POINT;
            X = win32_state.adjustRect.left = win32_state.adjustRect.right = LOWORD(lParam);
            Y = win32_state.adjustRect.top = win32_state.adjustRect.bottom = HIWORD(lParam);
            oldAdjustRect = win32_state.adjustRect;
        } else {
            int i;
            int adjustx[2], adjusty[2];
			win32_state.windowAdjustFlag = WINDOW_DEACTIVATED;
            button_state.button[win32_state.adjustButton].ispressed = 0;
            SendMessage(button_state.button[win32_state.adjustButton].hwnd, BM_SETSTATE, 0, 0);

            for (i = 0; i < button_state.num_buttons; i++) {
                if (button_state.button[i].type != BUTTON_SEPARATOR
                    && button_state.button[i].enabled) {
                    if (!EnableWindow(button_state.button[i].hwnd, TRUE))
                        WIN32_DRAW_ERROR();
                }
            }
            adjustx[0] = win32_state.adjustRect.left;
            adjustx[1] = win32_state.adjustRect.right;
            adjusty[0] = win32_state.adjustRect.top;
            adjusty[1] = win32_state.adjustRect.bottom;

            update_win(adjustx, adjusty, win32_invalidate_screen);
        }
    }
}

static void
win32_GraphicsWND_handle_WM_MBUTTONDOWN(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    // t_event_buttonPressed is used as a structure for storing information about a mouse
    // button press event. This information can be passed back to and used by a client
    // program.
    t_event_buttonPressed button_info;
    win32_handle_button_info(button_info, message, wParam);

    // get x- and y- coordinates of the cursor. Do not use LOWORD or HIWORD macros
    // to extract the coordinates because these macros can return incorrect results
    // on systems with multiple monitors.
    int xPos, yPos;
    xPos = GET_X_LPARAM(lParam);
    yPos = GET_Y_LPARAM(lParam);

    // turn on panning_enabled
    panning_on(xPos, yPos);

    /* Windows function specifically designed for mouse click and drag.
     * This function sends all mouse message to hGraphicsWnd, even if
     * the cursor is outside the client program's top-level window.
     */
    SetCapture(hwnd);
}

static void
win32_GraphicsWND_handle_WM_MOUSEMOVE(LPARAM lParam, int &X, int &Y, RECT &oldAdjustRect) {
#ifdef VERBOSE
    printf("Got a MotionNotify Event.\n");
    printf("x: %d    y: %d\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
#endif
    if (win32_state.windowAdjustFlag == WAITING_FOR_FIRST_CORNER_POINT) {
        return;
    } else if (win32_state.windowAdjustFlag == WAITING_FOR_SECOND_CORNER_POINT) {
        if (X > LOWORD(lParam)) {
            win32_state.adjustRect.left = LOWORD(lParam);
            win32_state.adjustRect.right = X;
        } else {
            win32_state.adjustRect.left = X;
            win32_state.adjustRect.right = LOWORD(lParam);
        }
        if (Y > HIWORD(lParam)) {
            win32_state.adjustRect.top = HIWORD(lParam);
            win32_state.adjustRect.bottom = Y;
        } else {
            win32_state.adjustRect.top = Y;
            win32_state.adjustRect.bottom = HIWORD(lParam);
        }
        if (!InvalidateRect(win32_state.hGraphicsWnd, &oldAdjustRect, FALSE))
            WIN32_DRAW_ERROR();
        if (!InvalidateRect(win32_state.hGraphicsWnd, &win32_state.adjustRect, FALSE))
            WIN32_DRAW_ERROR();
        if (!UpdateWindow(win32_state.hGraphicsWnd))
            WIN32_DRAW_ERROR();

        return;
    } else if (pan_state.panning_enabled) {
        // get x- and y- coordinates of the cursor. Do not use LOWORD or HIWORD macros
        // to extract the coordinates because these macros can return incorrect results
        // on systems with multiple monitors.
        int xPos, yPos;
        xPos = GET_X_LPARAM(lParam);
        yPos = GET_Y_LPARAM(lParam);
        panning_execute(xPos, yPos, win32_drawscreen_ptr);
    } else if (gl_state.get_mouse_move_input && win32_mousemove_ptr != NULL) {
        win32_mousemove_ptr(xscrn_to_world(LOWORD(lParam)), yscrn_to_world(HIWORD(lParam)));
    }
}

static LRESULT CALLBACK
WIN32_StatusWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;

    switch (message) {
        case WM_CREATE:
            hdc = GetDC(hwnd);
            if (!hdc)
                WIN32_DRAW_ERROR();
            if (!SetBkMode(hdc, TRANSPARENT))
                WIN32_DRAW_ERROR();
            if (!ReleaseDC(hwnd, hdc))
                WIN32_DRAW_ERROR();
            return 0;

        case WM_PAINT:
        {
            hdc = BeginPaint(hwnd, &ps);
            if (!hdc)
                WIN32_DRAW_ERROR();

            if (!GetClientRect(hwnd, &rect))
                WIN32_DRAW_ERROR();

            if (!SelectObject(hdc, GetStockObject(NULL_BRUSH)))
                WIN32_SELECT_ERROR();
            if (!SelectObject(hdc, GetStockObject(WHITE_PEN)))
                WIN32_SELECT_ERROR();
            if (!Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom))
                WIN32_DRAW_ERROR();
            if (!SelectObject(hdc, GetStockObject(BLACK_PEN)))
                WIN32_SELECT_ERROR();
            if (!MoveToEx(hdc, rect.left, rect.bottom - 1, NULL))
                WIN32_DRAW_ERROR();
            if (!LineTo(hdc, rect.right - 1, rect.bottom - 1))
                WIN32_DRAW_ERROR();
            if (!LineTo(hdc, rect.right - 1, rect.top))
                WIN32_DRAW_ERROR();

            int text_byte_length = strlen(gl_state.statusMessage);
            wchar_t* WIN32_wchar_text = new wchar_t[text_byte_length];
            size_t WIN32_wchar_text_len =
                MultiByteToWideChar(
                CP_UTF8, 0,
                gl_state.statusMessage, text_byte_length,
                WIN32_wchar_text, text_byte_length
                );

            if (!DrawTextW(hdc, WIN32_wchar_text, WIN32_wchar_text_len, &rect,
                DT_CENTER | DT_VCENTER | DT_SINGLELINE))
                WIN32_DRAW_ERROR();

            delete[] WIN32_wchar_text;

            if (!EndPaint(hwnd, &ps))
                WIN32_DRAW_ERROR();
            return 0;

        }
        case WM_SIZE:
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

		default: {} // For compiler warnings
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

static LRESULT CALLBACK
WIN32_ButtonsWND(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
    static HBRUSH hBrush;
    int i;

    switch (message) {
        case WM_COMMAND:
            if (win32_state.windowAdjustFlag == WINDOW_DEACTIVATED) {
                button_state.button[LOWORD(wParam) - 200].fcn(win32_invalidate_screen);
                if (win32_state.windowAdjustFlag != WINDOW_DEACTIVATED) {
                    win32_state.adjustButton = LOWORD(wParam) - 200;
                    button_state.button[win32_state.adjustButton].ispressed = 1;
                    for (i = 0; i < button_state.num_buttons; i++) {
                        EnableWindow(button_state.button[i].hwnd, FALSE);
                        SendMessage(button_state.button[i].hwnd, BM_SETSTATE,
                            button_state.button[i].ispressed, 0);
                    }
                }
            }
            SetFocus(win32_state.hMainWnd);
            return 0;

        case WM_CREATE:
            hdc = GetDC(hwnd);
            if (!hdc)
                WIN32_DRAW_ERROR();
            hBrush = CreateSolidBrush(convert_to_win_color(t_color::predef_colors[LIGHTGREY]));
            if (!hBrush)
                WIN32_CREATE_ERROR();
            if (!SelectObject(hdc, hBrush))
                WIN32_SELECT_ERROR();
            if (!SetBkMode(hdc, TRANSPARENT))
                WIN32_DRAW_ERROR();
            if (!ReleaseDC(hwnd, hdc))
                WIN32_DRAW_ERROR();

            return 0;

        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            if (!hdc)
                WIN32_DRAW_ERROR();

            if (!GetClientRect(hwnd, &rect))
                WIN32_DRAW_ERROR();

            if (!SelectObject(hdc, GetStockObject(NULL_BRUSH)))
                WIN32_SELECT_ERROR();
            if (!SelectObject(hdc, GetStockObject(WHITE_PEN)))
                WIN32_SELECT_ERROR();
            if (!Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom))
                WIN32_DRAW_ERROR();
            if (!SelectObject(hdc, GetStockObject(BLACK_PEN)))
                WIN32_SELECT_ERROR();
            if (!MoveToEx(hdc, rect.left, rect.bottom - 1, NULL))
                WIN32_DRAW_ERROR();
            if (!LineTo(hdc, rect.right - 1, rect.bottom - 1))
                WIN32_DRAW_ERROR();
            if (!LineTo(hdc, rect.right - 1, rect.top))
                WIN32_DRAW_ERROR();

            for (i = 0; i < button_state.num_buttons; i++) {
                if (button_state.button[i].type == BUTTON_SEPARATOR) {
                    int x, y, w;

                    x = button_state.button[i].xleft;
                    y = button_state.button[i].ytop;
                    w = button_state.button[i].width;

                    if (!MoveToEx(hdc, x, y, NULL))
                        WIN32_DRAW_ERROR();
                    if (!LineTo(hdc, x + w, y))
                        WIN32_DRAW_ERROR();
                    if (!SelectObject(hdc, GetStockObject(WHITE_PEN)))
                        WIN32_SELECT_ERROR();
                    if (!MoveToEx(hdc, x, y + 1, NULL))
                        WIN32_DRAW_ERROR();
                    if (!LineTo(hdc, x + w, y + 1))
                        WIN32_DRAW_ERROR();
                    if (!SelectObject(hdc, GetStockObject(BLACK_PEN)))
                        WIN32_SELECT_ERROR();
                }
            }
            if (!EndPaint(hwnd, &ps))
                WIN32_DRAW_ERROR();
            return 0;

        case WM_DESTROY:
            for (i = 0; i < button_state.num_buttons; i++) {
            }
            if (!DeleteObject(hBrush))
                WIN32_DELETE_ERROR();
            PostQuitMessage(0);
            return 0;

		default: {} // For compiler warnings
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

static void WIN32_SELECT_ERROR() {
    wchar_t msg[BUFSIZE];
	wsprintf((char *) msg, "Error %i: Couldn't select graphics object on line %d of graphics.c\n",
        GetLastError(),	__LINE__);

    wprintf(msg);
    MessageBoxW(NULL, msg, NULL, MB_OK);
    exit(-1);
}

void WIN32_DELETE_ERROR() {
    wchar_t msg[BUFSIZE];
    wsprintf((char *) msg, "Error %i: Couldn't delete graphics object on line %d of graphics.c\n",
        GetLastError(),	__LINE__);

    wprintf(msg);
    MessageBoxW(NULL, msg, NULL, MB_OK);
    exit(-1);
}

static void WIN32_CREATE_ERROR() {
    wchar_t msg[BUFSIZE];
    wsprintf((char *) msg, "Error %i: Couldn't create graphics object on line %d of graphics.c\n",
        GetLastError(),	__LINE__);

    wprintf(msg);
    MessageBoxW(NULL, msg, NULL, MB_OK);
    exit(-1);
}

static void WIN32_DRAW_ERROR() {
    wchar_t msg[BUFSIZE];
    wsprintf((char *) msg, "Error %i: Couldn't draw graphics object on line %d of graphics.c\n",
        GetLastError(),	__LINE__);

    wprintf(msg);
    MessageBoxW(NULL, msg, NULL, MB_OK);
    exit(-1);
}

static void win32_invalidate_screen(void) {
    /* Tells the graphics engine to redraw the graphics display since information has changed */

    if (!InvalidateRect(win32_state.hGraphicsWnd, NULL, FALSE))
        WIN32_DRAW_ERROR();
    if (!UpdateWindow(win32_state.hGraphicsWnd))
        WIN32_DRAW_ERROR();
}

static void win32_reset_state() {
    // Not sure exactly what needs to be reset to NULL etc.
    // Resetting everthing to be safe.
    win32_state.hGraphicsPen = 0;
    win32_state.hGraphicsBrush = 0;
    win32_state.hGrayBrush = 0;
    win32_state.hGraphicsDC = 0;
	win32_state.hGraphicsDCPassive = 0;	// <Addition/Mod: Charles>
    win32_state.hGraphicsFont = 0;

    /* These are used for the "Window" graphics button. They keep track of whether we're entering
     * the window rectangle to zoom to, etc.
     */
    win32_state.windowAdjustFlag = WINDOW_DEACTIVATED;
    win32_state.adjustButton = -1;
    win32_state.InEventLoop = false;
}

static void win32_drain_message_queue() {
    // Drain the message queue, so we don't have a quit message lying around
    // that will stop us from re-opening a window later if desired.
    MSG msg;
    while (PeekMessage(&msg, win32_state.hMainWnd, 0, 0, PM_REMOVE)) {
        if (msg.message == WM_QUIT) {
            printf("Got the quit message.\n");
        }
    }
}

static void win32_handle_mousewheel_zooming(WPARAM wParam, LPARAM lParam, bool draw_screen) {
    // zDelta indicates the distance which the mouse wheel is rotated.
    // The value for zDelta is a multiple of WHEEL_DELTA, which is 120.
    // WHEEL_DELTA is the value for scrolling the mouse wheel by one increment.
    short zDelta;
    zDelta = GET_WHEEL_DELTA_WPARAM(wParam);

    // roll_detent captures how many increments the mouse wheel has been scrolled by.
    int roll_detent;
    roll_detent = zDelta / WHEEL_DELTA;
    // roll_detent will be negative if wheel was roatated backward, toward the user.
    if (roll_detent < 0)
        roll_detent *= -1;

    // get x- and y- coordinates of the cursor. WM_MOUSEWHEEL receives coordinates of
    // the cursor relative to the upper-left corner of the screen instead of the client
    // program. Therefore, call ScreenToClient() to convert.
    POINT mousePos;
    mousePos.x = GET_X_LPARAM(lParam);
    mousePos.y = GET_Y_LPARAM(lParam);
    ScreenToClient(win32_state.hMainWnd, &mousePos);


    for (int i = 1; i <= roll_detent; i++) {
        // Positive value for zDelta indicates that the wheel was rotated forward, which
        // will trigger zoom_in. Otherwise, zoom_out is called.
        // Also, only redraw the screen on the last one.
        if (zDelta > 0)
            handle_zoom_in(xscrn_to_world(mousePos.x), yscrn_to_world(mousePos.y),
            (draw_screen && (i == roll_detent)) ? win32_drawscreen_ptr : NULL);
        else
            handle_zoom_out(xscrn_to_world(mousePos.x), yscrn_to_world(mousePos.y),
            (draw_screen && (i == roll_detent)) ? win32_drawscreen_ptr : NULL);
    }
}

static void win32_handle_button_info(t_event_buttonPressed &button_info,
    UINT message, WPARAM wParam) {
    /* The parameter "wParam" is an unsigned int. In this case, it contains information indicating *
     * whether various virtual keys (ie. modifier keys) are held during a mouse button press       *
     * event.																					   */
    if (wParam & MK_SHIFT)
        button_info.shift_pressed = true;
    else
        button_info.shift_pressed = false;

    if (wParam & MK_CONTROL)
        button_info.ctrl_pressed = true;
    else
        button_info.ctrl_pressed = false;

    /* Parameter "message" indicates what button is pressed: pass 1 for left click,
     * 3 for right click, 2 for scroll wheel click, 4 for scroll wheel forward rotate,
     * and 5 for scroll wheel backward rotate.
     * We follow this convention in order to be consistent for both X11 and WIN32.
     */
    switch (message) {
        case (WM_LBUTTONDOWN):
            button_info.button = 1;
            break;
        case (WM_RBUTTONDOWN):
            button_info.button = 3;
            break;
        case (WM_MBUTTONDOWN):
            button_info.button = 2;
            break;
        case (WM_MOUSEWHEEL):
            short zDelta;
            zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
            // Positive value for zDelta indicates that the wheel was rotated forward,
            // away from user, and negative value indicates wheel rotated backward.
            if (zDelta > 0)
                button_info.button = 4;
            else
                button_info.button = 5;
            break;
		default:
			break;
    }

#ifdef VERBOSE
    printf("Button pressed is: %d.\n(left click is 1; right click is 3; "
        "scroll wheel click is 2; scroll wheel forward rotate is 4; "
        "scroll wheel backward is 5.)\n", button_info.button);
    if (button_info.shift_pressed == true)
        printf("Shift is pressed at button press.\n");
    if (button_info.ctrl_pressed == true)
        printf("Ctrl is pressed at button press.\n");
#endif
}

static void _drawcurve(t_point *points, int npoints, int fill) {
    /* Draw a beizer curve.
     * Must have 3I+1 points, since each Beizer curve needs 3 points and we also
     * need an initial starting point
     */
    float xmin, ymin, xmax, ymax;
    int i;

#define MAXPTS 300

    if ((npoints - 1) % 3 != 0 || npoints > MAXPTS)
        WIN32_DRAW_ERROR();

    /* Conservative (but fast) clip test -- check containing rectangle of *
     * polygon.                                                           */

    xmin = xmax = points[0].x;
    ymin = ymax = points[0].y;

    for (i = 1; i < npoints; i++) {
        xmin = min(xmin, points[i].x);
        xmax = max(xmax, points[i].x);
        ymin = min(ymin, points[i].y);
        ymax = max(ymax, points[i].y);
    }

    if (rect_off_screen(xmin, ymin, xmax, ymax))
        return;

    if (gl_state.disp_type == SCREEN) {
#ifdef X11
        /* implement X11 version here */
#else /* Win32 */
        // create POINT array
        HPEN hOldPen = CreatePen(PS_NULL, 0, RGB(0,0,0));
        POINT pts[MAXPTS];

        for (i = 0; i < npoints; i++) {
            pts[i].x = xworld_to_scrn(points[i].x);
            pts[i].y = yworld_to_scrn(points[i].y);
        }

        if (fill) {
            /* NULL_PEN is a Windows stock object which does not draw anything. Set current *
             * pen to NULL_PEN in order to fill the curve without drawing the outline.      */
            hOldPen = (HPEN) SelectObject(win32_state.hGraphicsDC, GetStockObject(NULL_PEN));
            if (!(hOldPen))
                WIN32_SELECT_ERROR();
        }

        if (!BeginPath(win32_state.hGraphicsDC))
            WIN32_DRAW_ERROR();
        if (!PolyBezier(win32_state.hGraphicsDC, pts, npoints))
            WIN32_DRAW_ERROR();
        if (!EndPath(win32_state.hGraphicsDC))
            WIN32_DRAW_ERROR();

        if (!fill) {
            if (!StrokePath(win32_state.hGraphicsDC))
                WIN32_DRAW_ERROR();
        } else {
            if (!FillPath(win32_state.hGraphicsDC))
                WIN32_DRAW_ERROR();
        }

        if (fill) {
            /* Need to restore the original pen into the device context after filling. */
            if (!SelectObject(win32_state.hGraphicsDC, hOldPen))
                WIN32_SELECT_ERROR();
        }
#endif
    } else {

        fprintf(gl_state.ps, "newpath\n");
        fprintf(gl_state.ps, "%.2f %.2f moveto\n", x_to_post(points[0].x),
            y_to_post(points[0].y));
        for (i = 1; i < npoints; i += 3)
            fprintf(gl_state.ps, "%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
            x_to_post(points[i].x), y_to_post(points[i].y),
            x_to_post(points[i + 1].x), y_to_post(points[i + 1].y),
            x_to_post(points[i + 2].x), y_to_post(points[i + 2].y));
        if (!fill)
            fprintf(gl_state.ps, "stroke\n");
        else
            fprintf(gl_state.ps, "fill\n");
    }
}

void win32_drawcurve(t_point *points,
    int npoints) {
    _drawcurve(points, npoints, 0);
}

void win32_fillcurve(t_point *points,
    int npoints) {
    _drawcurve(points, npoints, 1);
}

#endif /******** Win32 Specific Definitions ********************/


#else  /***** NO_GRAPHICS *******/
/* No graphics at all. Stub everything out so calling program doesn't have to change
 * but of course graphics won't do anything.
 */

#include "graphics.h"

void event_loop(void (* /*act_on_mousebutton*/) (float x, float y, t_event_buttonPressed button_info),
    void (* /*act_on_mousemove*/) (float x, float y),
    void (* /*act_on_keypress*/) (char key_pressed, int keysym),
    void (* /*drawscreen*/) (void)) { }

void init_graphics(const std::string& /*window_name*/, int /*cindex*/) { }

void init_graphics(const std::string& /*window_name*/, const t_color& /*background*/) { }

void close_graphics(void) { }

void update_message(const std::string& /*msg*/) { }

void draw_message(void) { }

void set_visible_world(float /*xl*/, float /*yt*/, float /*xr*/, float /*yb*/) { }

void set_visible_world(const t_bound_box& /*bounds*/) { }

void flushinput(void) { }

void setcolor(int /*cindex*/) { }

void setcolor(const t_color& /*c*/) { }

void setcolor(uint_fast8_t /*r*/, uint_fast8_t /*g*/, uint_fast8_t /*b*/, uint_fast8_t /*a*/) { }

void setcolor_by_name(std::string /*cname*/) { }

t_color getcolor(void) {
    return t_color(0, 0, 0);
}

void setlinewidth(int /*linewidth*/) { }

void setfontsize(int /*pointsize*/) { }

int getfontsize() {
    return 0;
}

void settextrotation(int /*degrees*/) { }

int gettextrotation() {
    return 0;
}

void settextattrs(int /*pointsize*/, int /*degrees*/) { }

void drawline(const t_point& /*p1*/, const t_point& /*p2*/) { }

void drawline(float /*x1*/, float /*y1*/, float /*x2*/, float /*y2*/) { }

void drawrect(const t_bound_box& /*rect*/) { }

void drawrect(const t_point& /*bottomleft*/, const t_point& /*upperright*/) { }

void drawrect(float /*x1*/, float /*y1*/, float /*x2*/, float /*y2*/) { }

void fillrect(const t_bound_box& /*rect*/) { }

void fillrect(const t_point& /*bottomleft*/, const t_point& /*upperright*/) { }

void fillrect(float /*x1*/, float /*y1*/, float /*x2*/, float /*y2*/) { }

void fillpoly(t_point* /*points*/, int /*npoints*/) { }

void drawarc(float /*xcen*/, float /*ycen*/, float /*rad*/, float /*startang*/,
    float /*angextent*/) { }

void drawellipticarc(
    const t_point& /*center*/, float /*radx*/, float /*rady*/, float /*startang*/, float /*angextent*/) { }

void drawellipticarc(float /*xc*/, float /*yc*/, float /*radx*/, float /*rady*/,
    float /*startang*/, float /*angextent*/) { }

void fillarc(const t_point& /*center*/, float /*rad*/, float /*startang*/, float /*angextent*/) { }

void fillarc(float /*xcen*/, float /*ycen*/, float /*rad*/, float /*startang*/,
    float /*angextent*/) { }

void fillellipticarc(
    const t_point& /*center*/, float /*radx*/, float /*rady*/, float /*startang*/, float /*angextent*/) { }

void fillellipticarc(float /*xc*/, float /*yc*/, float /*radx*/, float /*rady*/,
    float /*startang*/, float /*angextent*/) { }

void drawtext_in(const t_bound_box& /*bbox*/, const std::string& /*text*/) { }

void drawtext_in(const t_bound_box& /*bbox*/, const std::string& /*text*/, float /*tolerance*/) { }

void drawtext(const t_point& /*text_center*/, const std::string& /*text*/, const t_bound_box& /*bounds*/) { }

void drawtext(const t_point& /*text_center*/, const std::string& /*text*/, const t_bound_box& /*bounds*/, float /*tolerance*/) { }

void drawtext(const t_point& /*text_center*/, const std::string& /*text*/, float /*boundx*/, float /*boundy*/) { }

void drawtext(float /*xc*/, float /*yc*/, const std::string& /*text*/, float /*boundx*/, float /*boundy*/) { }

void clearscreen(void) { }

t_bound_box get_visible_world() {
    return t_bound_box(0, 0, 0, 0);
}

t_bound_box get_visible_screen() {
    return (t_bound_box(0, 0, 0, 0));
}

void create_button(const char* /*prev_button_text*/, const char* /*button_text*/,
    void (* /*button_func*/) (void (*drawscreen) (void))) { }

void destroy_button(const char* /*button_text*/) { }

int init_postscript(const char* /*fname*/) {
    return (1);
}

void close_postscript(void) { }

void get_report_structure(t_report*) { }

void set_mouse_move_input(bool) { }

void set_keypress_input(bool) { }

void set_draw_mode(enum e_draw_mode /*draw_mode*/) { }

void enable_or_disable_button(int /*ibutton*/, bool /*enabled*/) { }

void change_button_text(const char* /*button_text*/, const char* /*new_button_text*/) { }


t_point world_to_scrn(const t_point& /*point*/) {
    return t_point();
}

t_bound_box world_to_scrn(const t_bound_box& /*box*/) {
    return t_bound_box();
}

t_point scrn_to_world(const t_point& /*point*/) {
    return t_point();
}

t_bound_box scrn_to_world(const t_bound_box& /*box*/) {
    return t_bound_box();
}

bool LOD_screen_area_test(t_bound_box /*test*/, float /*screen_area_threshold*/) {
    return true;
}

void setlinestyle(int /*linestyle*/, int /*capstyle*/) { }
void set_drawing_buffer(t_draw_to /*draw_mode*/) { }
void copy_off_screen_buffer_to_screen() { }
void set_coordinate_system(t_coordinate_system /*coord*/) { }

#ifdef WIN32

void win32_drawcurve(t_point* /*points*/, int npoints) {
}

void win32_fillcurve(t_point* points, int npoints) {
}


#endif  // WIN32 (subset of commands)

#endif  // NO_GRAPHICS


#ifdef WIN32

COLORREF convert_to_win_color(const t_color& src) {
    return RGB(src.red, src.green, src.blue);
}
#endif /* WIN32 */


