#ifndef PDF_OR_PS_H
#define PDF_OR_PS_H

#include <FL/Fl_Paged_Device.H>

#if defined(_WIN32)
#include <windows.h>
#endif


#if 10*FL_MAJOR_VERSION + FL_MINOR_VERSION >= 14

#include <FL/Fl_PDF_File_Surface.H>

typedef Fl_PDF_File_Surface Fl_PDF_File_Device;

class PDF_or_PS_File_Device : public Fl_PDF_File_Surface {
public:
  int start_job(const char *fname, enum Fl_Paged_Device::Page_Format format,
                enum Fl_Paged_Device::Page_Layout layout = Fl_Paged_Device::PORTRAIT) {
    char *name = new char[strlen(fname) + 5];
    strcpy(name, fname);
    char *p = strrchr(name, '.');
    if (!p) p = name + strlen(name);
    strcpy(p, ".pdf");
    int retval = begin_job(name);
    delete[] name;
    return retval;
  }
  const char *outfname() {
    return pdf_filename();
  }
};

#else

#define NO_PDF 1

#ifdef NO_PDF

#include <FL/Fl_PostScript.H>
class PDF_or_PS_File_Device : public Fl_PostScript_File_Device {
  FILE *file;
  char *filename;
public:
  PDF_or_PS_File_Device() { file = NULL; }
  int begin_document(const char* fixedfilename, enum Fl_Paged_Device::Page_Format format=Fl_Paged_Device::A4,
         enum Fl_Paged_Device::Page_Layout layout=Fl_Paged_Device::PORTRAIT);
  int start_job(const char *defaultname, enum Fl_Paged_Device::Page_Format format=Fl_Paged_Device::A4,
    enum Fl_Paged_Device::Page_Layout layout=Fl_Paged_Device::PORTRAIT);
  Fl_Graphics_Driver *driver() {  return (Fl_Graphics_Driver*)Fl_PostScript_File_Device::driver(); }
  const char *outfname() {return filename; }
  ~PDF_or_PS_File_Device();
};

#else // NO_PDF

#include <pdflib.h>
#include <setjmp.h>
#include <FL/Fl_Device.H>

class PDF_Graphics_Driver : public Fl_Graphics_Driver {
private:
  int pdf_font;
  const char *encoding;
  bool in_page;
  int tr_x, tr_y;
public:
  PDF *pdf;
  PDF_Graphics_Driver();
  void rect(int x, int y, int w, int h);
  void rectf(int x, int y, int w, int h);
  void line_style(int style, int width, char *dashes=0);
  void line(int x1, int y1, int x2, int y2);
  void xyline(int x, int y, int x1);
  void xyline(int x, int y, int x1, int y2);
  void yxline(int x, int y, int y1);
  void yxline(int x, int y, int y1, int x2);
  void font(int f, int s);
  void draw(const char *str, int n, int x, int y);
  void draw(const char*, int, float, float) ;
  void draw(int, const char*, int, int, int) ;
  void rtl_draw(const char*, int, int, int) ;
  void color(uchar r, uchar g, uchar b);
  void color(Fl_Color c);
  void push_clip(int x, int y, int w, int h) ;
  void pop_clip();
  void draw_image(const uchar*, int, int, int, int, int, int) ;
  void draw_image_mono(const uchar*, int, int, int, int, int, int) ;
  void draw_image(void (*)(void*, int, int, int, uchar*), void*, int, int, int, int, int) ;
  void draw_image_mono(void (*)(void*, int, int, int, uchar*), void*, int, int, int, int, int) ;
  void draw(Fl_RGB_Image*, int, int, int, int, int, int) ;
  void draw(Fl_Pixmap*, int, int, int, int, int, int) ;
  void draw(Fl_Bitmap*, int, int, int, int, int, int) ;
  double width(const char*, int) ;
  int height() ;
  int descent() ;
  friend class Fl_PDF_File_Device;
};

class Fl_PDF_File_Device : public Fl_Paged_Device
{
  int width, height;
  Fl_Surface_Device *previous_surface;
  int left_margin, top_margin;
  char *filename;
public:
  Fl_PDF_File_Device();
  int start_job(const char *defaultname, enum Fl_Paged_Device::Page_Format format=Fl_Paged_Device::A4, 
		enum Fl_Paged_Device::Page_Layout layout=Fl_Paged_Device::PORTRAIT);
  int begin_document(const char* fixedfilename, enum Fl_Paged_Device::Page_Format format=Fl_Paged_Device::A4,
		     enum Fl_Paged_Device::Page_Layout layout=Fl_Paged_Device::PORTRAIT);
  int begin_custom(const char* fixedfilename, int pwidth, int pheight);
  int printable_rect(int *w, int *h);
  void margins(int *left, int *top, int *right, int *bottom);
  void origin(int x, int y);
  void origin (int *x, int *y);
  void translate(int x, int y);
  void untranslate();
  int start_page (void);
  int end_page (void);
  void end_job (void);
  void error_catch();
  int surface_catch();
  void surface_try(jmp_buf** b);
  void *pdf();
  const char *outfname() {return filename; }
  ~Fl_PDF_File_Device();
};
typedef Fl_PDF_File_Device PDF_or_PS_File_Device;

#endif // NO_PDF
#endif // FLTK < 1.4

#if defined(FLTK_COCOA_PLATFORM)
#include <ApplicationServices/ApplicationServices.h>
#undef check
#endif


#endif // PDF_OR_PS_H

