/*                                                                         
 * 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) (void));
#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 = {NULL, 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(void);

/* Function declarations for button responses */
static void translate_up(void (*drawscreen) (void));
static void translate_left(void (*drawscreen) (void));
static void translate_right(void (*drawscreen) (void));
static void translate_down(void (*drawscreen) (void));
static void panning_execute(int x, int y, void (*drawscreen) (void));
static void panning_on(int start_x, int start_y);
static void panning_off(void);
static void zoom_in(void (*drawscreen) (void));
static void zoom_out(void (*drawscreen) (void));
static void handle_zoom_in(float x, float y, void (*drawscreen) (void));
static void handle_zoom_out(float x, float y, void (*drawscreen) (void));
static void zoom_fit(void (*drawscreen) (void));
static void adjustwin(void (*drawscreen) (void));
static void postscript(void (*drawscreen) (void));
static void proceed(void (*drawscreen) (void));
static void quit(void (*drawscreen) (void));
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) (void));

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) (void));
static Bool x11_test_if_exposed(Display *disp, XEvent *event_ptr,
    XPointer dummy);
static void x11_build_textarea(void);
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(void);
static void menutext(XftDraw* draw, int xc, int yc, const char *text);

static void x11_handle_expose(const XEvent& report, void (*drawscreen) (void));
static void x11_handle_configure_notify(const XEvent& report, void (*drawscreen) (void));
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 == NULL) {
        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 == NULL) {
        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 = 0;

    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) (void))) {
    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(void) {
    /* 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(void) {

    /* 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) (void)) {

    if (drawscreen == NULL) {
        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(void) {
    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.bottom()) + 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(void) {
    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(void) {
    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) (void)) {
    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) (void)) {
    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) (void)) {
    //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 != NULL) {
        drawscreen();
    }
}

/* Zooms out by a factor of ZOOM_FACTOR */
static void
handle_zoom_out(float x, float y, void (*drawscreen) (void)) {
    //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 != NULL) {
        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) (void)) {
    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) (void)) {
    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) (void)) {
    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) (void)) {

    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) (void)) {
    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) (void)) {
    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(void) {
    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)(void)) {
    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) (void)) {
#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) (void)) {
    /* 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)) {
    (void) drawscreen; // Suppress unused parameter warnings for Win32
    gl_state.ProceedPressed = true;
}

static void
quit(void (*drawscreen) (void)) {
    (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(void) {
    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 = NULL;
    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 = NULL;      // Important to NULL these pointers in case init_cairo is called again
	x11_state.cairo_surface = NULL;
#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 == NULL) {
        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(void) {

    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(void) {
    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 = 1;
    }

    /* 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 = 1;
        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 = NULL;
    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 != NULL) {
        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 = NULL;
    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)) == NULL) {
        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 = NULL;

    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, NULL);
    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) (void)) {
    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 != NULL) // 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 = 1;
                        x11_drawbut(bnum);
                        XFlush(x11_state.display); /* Flash the button */
                        button_state.button[bnum].fcn(drawscreen);
                        button_state.button[bnum].ispressed = 0;
                        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 != NULL && 
                        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 != NULL)
                        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, NULL); // (same function as normal event logic)
                        break;
                    case Button5:
                        handle_zoom_out(x, y, NULL); // (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(void) {
    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(void) {
    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) (void)) {
#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) (void)) {
    // 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) (void)) {
    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 */


