//========================================================================
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2014 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
// Copyright (C) 2014, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2017 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <cairo.h>
#ifdef CAIRO_HAS_WIN32_SURFACE

#include <cairo-win32.h>

#include "parseargs.h"
#include "pdftocairo-win32.h"

#include <dlgs.h>
#include <commctrl.h>
#include <commdlg.h>
#include <windowsx.h>
#include <winspool.h>

static HDC hdc;
static HGLOBAL hDevmode = 0;
static HGLOBAL hDevnames = 0;
static DEVMODEA *devmode;
static char *printerName;

struct Win32Option
{
  const char *name;
  int value;
};

static const Win32Option win32PaperSource[] =
{
  {"upper", DMBIN_UPPER},
  {"onlyone", DMBIN_ONLYONE},
  {"lower", DMBIN_LOWER},
  {"middle", DMBIN_MIDDLE},
  {"manual", DMBIN_MANUAL},
  {"envelope", DMBIN_ENVELOPE},
  {"envmanual", DMBIN_ENVMANUAL},
  {"auto", DMBIN_AUTO},
  {"tractor", DMBIN_TRACTOR},
  {"smallfmt", DMBIN_SMALLFMT},
  {"largefmt", DMBIN_LARGEFMT},
  {"largecapacity", DMBIN_LARGECAPACITY},
  {"formsource", DMBIN_FORMSOURCE},
  {NULL, 0}
};

static void parseSource(GooString *source)
{
  const Win32Option *option = win32PaperSource;
  while (option->name) {
    if (source->cmp(option->name) == 0) {
      devmode->dmDefaultSource = option->value;
      devmode->dmFields |= DM_DEFAULTSOURCE;
      return;
    }
    option++;
  }
  fprintf(stderr, "Warning: Unknown paper source \"%s\"\n", source->getCString());
}

static const Win32Option win32DuplexMode[] =
{
  {"off", DMDUP_SIMPLEX},
  {"short", DMDUP_HORIZONTAL},
  {"long", DMDUP_VERTICAL},
  {NULL, 0}
};

static void parseDuplex(GooString *mode)
{
  const Win32Option *option = win32DuplexMode;
  while (option->name) {
    if (mode->cmp(option->name) == 0) {
      devmode->dmDuplex = option->value;
      devmode->dmFields |= DM_DUPLEX;
      return;
    }
    option++;
  }
  fprintf(stderr, "Warning: Unknown duplex mode \"%s\"\n", mode->getCString());
}

static void fillCommonPrinterOptions(GBool duplex)
{
  if (duplex) {
    devmode->dmDuplex = DMDUP_HORIZONTAL;
    devmode->dmFields |= DM_DUPLEX;
  }
}

static void fillPagePrinterOptions(double w, double h)
{
  w *= 254.0 / 72.0; // units are 0.1mm
  h *= 254.0 / 72.0;
  if (w > h) {
    devmode->dmOrientation = DMORIENT_LANDSCAPE;
    devmode->dmPaperWidth = h;
    devmode->dmPaperLength = w;
  } else {
    devmode->dmOrientation = DMORIENT_PORTRAIT;
    devmode->dmPaperWidth = w;
    devmode->dmPaperLength = h;
  }
  devmode->dmPaperSize = 0;
  devmode->dmFields |= DM_ORIENTATION | DM_PAPERWIDTH | DM_PAPERLENGTH;
}


static void fillPrinterOptions(GBool duplex, GooString *printOpt)
{
  //printOpt format is: <opt1>=<val1>,<opt2>=<val2>,...
  const char *nextOpt = printOpt->getCString();
  while (nextOpt && *nextOpt)
  {
    const char *comma = strchr(nextOpt, ',');
    GooString opt;
    if (comma) {
      opt.Set(nextOpt, comma - nextOpt);
      nextOpt = comma + 1;
    } else {
      opt.Set(nextOpt);
      nextOpt = NULL;
    }
    //here opt is "<optN>=<valN> "
    const char *equal = strchr(opt.getCString(), '=');
    if (!equal) {
      fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.getCString());
      continue;
    }
    int iequal = equal - opt.getCString();
    GooString value(&opt, iequal + 1, opt.getLength() - iequal - 1);
    opt.del(iequal, opt.getLength() - iequal);
    //here opt is "<optN>" and value is "<valN>"

    if (opt.cmp("source") == 0) {
      parseSource(&value);
    } else if (opt.cmp("duplex") == 0) {
      if (duplex)
	fprintf(stderr, "Warning: duplex mode is specified both as standalone and printer options\n");
      else
	parseDuplex( &value);
    } else {
      fprintf(stderr, "Warning: unknown printer option \"%s\"\n", opt.getCString());
    }
  }
}

static void getLocalPos(HWND wind, HWND dlg, RECT *rect)
{
  GetClientRect(wind, rect);
  MapWindowPoints(wind, dlg, (LPPOINT)rect, 2);
}

static HWND createGroupBox(HWND parent, HINSTANCE hInstance, HMENU id, const char *label, RECT *rect)
{
  HWND hwnd = CreateWindowA(WC_BUTTONA,
			    label,
			    WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
			    rect->left, rect->top,
			    rect->right - rect->left,
			    rect->bottom - rect->top,
			    parent, id,
			    hInstance, NULL);
  HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
  if (hFont)
    SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
  return hwnd;
}

static HWND createCheckBox(HWND parent, HINSTANCE hInstance, HMENU id, const char *label, RECT *rect)
{
  HWND hwnd = CreateWindowA(WC_BUTTONA,
			    label,
			    WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP,
			    rect->left, rect->top,
			    rect->right - rect->left,
			    rect->bottom - rect->top,
			    parent, id,
			    hInstance, NULL);
  HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
  if (hFont)
    SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
  return hwnd;
}

static HWND createStaticText(HWND parent, HINSTANCE hinstance, HMENU id, const char *text, RECT *rect)
{
  HWND hwnd = CreateWindowA(WC_STATICA,
			    text,
			    WS_CHILD | WS_VISIBLE | SS_LEFT,
			    rect->left, rect->top,
			    rect->right - rect->left,
			    rect->bottom - rect->top,
			    parent, id,
			    hinstance, NULL);
  HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
  if (hFont)
    SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
  return hwnd;
}

static HWND createPageScaleComboBox(HWND parent, HINSTANCE hinstance, HMENU id, RECT *rect)
{
  HWND hwnd = CreateWindowA(WC_COMBOBOX,
			    "",
			    WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP |
			    CBS_DROPDOWNLIST,
			    rect->left, rect->top,
			    rect->right - rect->left,
			    rect->bottom - rect->top,
			    parent, id,
			    hinstance, NULL);
  HFONT hFont = (HFONT)SendMessage(parent, WM_GETFONT, (WPARAM)0, (LPARAM)0);
  if (hFont)
    SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
  ComboBox_AddString(hwnd, "None");
  ComboBox_AddString(hwnd, "Shrink to Printable Area");
  ComboBox_AddString(hwnd, "Fit to Printable Area");
  return hwnd;
}

enum PageScale { NONE = 0, SHRINK = 1, FIT = 2 };

// used to set/get option values in printDialogHookProc
static PageScale pageScale;
static GBool centerPage;
static GBool useOrigPageSize;

// PrintDlg callback to customize the print dialog with additional controls.
static UINT_PTR CALLBACK printDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
  if (uiMsg == WM_INITDIALOG) {
    // Get the extant controls. See dlgs.h and prnsetup.dlg for the PrintDlg control ids.
    HWND printerGroupWind = GetDlgItem(hdlg, grp4);
    HWND printerComboWind = GetDlgItem(hdlg, cmb4);
    HWND nameLabelWind = GetDlgItem(hdlg, stc6);
    HWND statusLabelWind = GetDlgItem(hdlg, stc8);
    HWND printRangeGroupWind = GetDlgItem(hdlg, grp1);
    HWND radio1Wind = GetDlgItem(hdlg, rad1);
    HWND radio2Wind = GetDlgItem(hdlg, rad3);
    HWND copiesGroupWind = GetDlgItem(hdlg, grp2);
    HWND okWind = GetDlgItem(hdlg, IDOK);
    HWND cancelWind = GetDlgItem(hdlg, IDCANCEL);
    if (!printerGroupWind || !printerComboWind || !nameLabelWind || !statusLabelWind ||
	!printRangeGroupWind || !radio1Wind || !radio2Wind || !copiesGroupWind ||
	!okWind || !cancelWind)
      return 0;

    // Get the size and position of the above controls relative to the
    // print dialog window
    RECT printerGroupRect;
    RECT printerComboRect;
    RECT nameLabelRect;
    RECT statusLabelRect;
    RECT printRangeGroupRect;
    RECT radio1Rect, radio2Rect;
    RECT copiesGroupRect;
    RECT okRect, cancelRect;
    getLocalPos(printerGroupWind, hdlg, &printerGroupRect);
    getLocalPos(printerComboWind, hdlg, &printerComboRect);
    getLocalPos(nameLabelWind, hdlg, &nameLabelRect);
    getLocalPos(statusLabelWind, hdlg, &statusLabelRect);
    getLocalPos(printRangeGroupWind, hdlg, &printRangeGroupRect);
    getLocalPos(radio1Wind, hdlg, &radio1Rect);
    getLocalPos(radio2Wind, hdlg, &radio2Rect);
    getLocalPos(copiesGroupWind, hdlg, &copiesGroupRect);
    getLocalPos(okWind, hdlg, &okRect);
    getLocalPos(cancelWind, hdlg, &cancelRect);

    // Calc space required for new group
    int interGroupSpace = printRangeGroupRect.top - printerGroupRect.bottom;
    int groupHeight = statusLabelRect.top - printerGroupRect.top +
      printRangeGroupRect.bottom - radio1Rect.bottom;

    // Increase dialog size
    RECT dlgRect;
    GetWindowRect(hdlg, &dlgRect);
    SetWindowPos(hdlg, NULL,
		 dlgRect.left, dlgRect.top,
		 dlgRect.right - dlgRect.left,
		 dlgRect.bottom - dlgRect.top + interGroupSpace + groupHeight,
		 SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER);

    // Add new group and controls
    HINSTANCE hinstance = (HINSTANCE)GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
    RECT pdfGroupBoxRect;
    pdfGroupBoxRect.left = printRangeGroupRect.left;
    pdfGroupBoxRect.right = copiesGroupRect.right;
    pdfGroupBoxRect.top = printRangeGroupRect.bottom + interGroupSpace;
    pdfGroupBoxRect.bottom = pdfGroupBoxRect.top + groupHeight;
    createGroupBox(hdlg, hinstance, (HMENU)grp3, "PDF Print Options", &pdfGroupBoxRect);

    RECT textRect;
    textRect.left = nameLabelRect.left;
    textRect.right = nameLabelRect.left + 1.8*(printerComboRect.left - nameLabelRect.left);
    textRect.top = pdfGroupBoxRect.top + nameLabelRect.top - printerGroupRect.top;
    textRect.bottom = textRect.top + nameLabelRect.bottom - nameLabelRect.top;
    createStaticText(hdlg, hinstance, (HMENU)stc1, "Page Scaling:", &textRect);

    RECT comboBoxRect;
    comboBoxRect.left = textRect.right;
    comboBoxRect.right = comboBoxRect.left + printerComboRect.right - printerComboRect.left;;
    comboBoxRect.top = pdfGroupBoxRect.top + printerComboRect.top - printerGroupRect.top;
    comboBoxRect.bottom = textRect.top + 4*(printerComboRect.bottom - printerComboRect.top);
    HWND comboBoxWind = createPageScaleComboBox(hdlg, hinstance, (HMENU)cmb1, &comboBoxRect);

    RECT checkBox1Rect;
    checkBox1Rect.left = radio1Rect.left;
    checkBox1Rect.right = pdfGroupBoxRect.right - 10;
    checkBox1Rect.top = pdfGroupBoxRect.top + statusLabelRect.top - printerGroupRect.top;
    checkBox1Rect.bottom = checkBox1Rect.top + radio1Rect.bottom - radio1Rect.top;
    HWND checkBox1Wind = createCheckBox(hdlg, hinstance, (HMENU)chx3, "Center", &checkBox1Rect);

    RECT checkBox2Rect;
    checkBox2Rect.left = radio1Rect.left;
    checkBox2Rect.right = pdfGroupBoxRect.right - 10;
    checkBox2Rect.top =  checkBox1Rect.top + radio2Rect.top - radio1Rect.top;
    checkBox2Rect.bottom = checkBox2Rect.top + radio1Rect.bottom - radio1Rect.top;
    HWND checkBox2Wind = createCheckBox(hdlg, hinstance, (HMENU)chx4, "Select page size using document page size", &checkBox2Rect);

    // Move OK and Cancel buttons down ensuring they are last in the Z order
    // so that the tab order is correct.
    SetWindowPos(okWind,
		 HWND_BOTTOM,
		 okRect.left,
		 okRect.top + interGroupSpace + groupHeight,
		 0, 0,
		 SWP_NOSIZE); // keep current size
    SetWindowPos(cancelWind,
		 HWND_BOTTOM,
		 cancelRect.left,
		 cancelRect.top + interGroupSpace + groupHeight,
		 0, 0,
		 SWP_NOSIZE); // keep current size

    // Initialize control values
    ComboBox_SetCurSel(comboBoxWind, pageScale);
    Button_SetCheck(checkBox1Wind, centerPage ? BST_CHECKED : BST_UNCHECKED);
    Button_SetCheck(checkBox2Wind, useOrigPageSize ? BST_CHECKED : BST_UNCHECKED);

  } else if (uiMsg == WM_COMMAND) {
    // Save settings
    UINT id = LOWORD(wParam);
    if (id == cmb1)
      pageScale = (PageScale)ComboBox_GetCurSel(GetDlgItem(hdlg, cmb1));
    if (id == chx3)
      centerPage = IsDlgButtonChecked(hdlg, chx3);
    if (id == chx4)
      useOrigPageSize = IsDlgButtonChecked(hdlg, chx4);
  }
  return 0;
}

void win32SetupPrinter(GooString *printer, GooString *printOpt,
		       GBool duplex, GBool setupdlg)
{
  if (printer->getCString()[0] == 0) {
    DWORD size = 0;
    GetDefaultPrinterA(NULL, &size);
    printerName = (char*)gmalloc(size);
    GetDefaultPrinterA(printerName, &size);
  } else {
    printerName = gstrndup(printer->getCString(), printer->getLength());
  }

  //Query the size of the DEVMODE struct
  LONG szProp = DocumentPropertiesA(NULL, NULL, printerName, NULL, NULL, 0);
  if (szProp < 0) {
    fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
    exit(99);
  }
  devmode = (DEVMODEA*)gmalloc(szProp);
  memset(devmode, 0, szProp);
  devmode->dmSize = sizeof(DEVMODEA);
  devmode->dmSpecVersion = DM_SPECVERSION;
  //Load the current default configuration for the printer into devmode
  if (DocumentPropertiesA(NULL, NULL, printerName, devmode, devmode, DM_OUT_BUFFER) < 0) {
    fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
    exit(99);
  }

  // Update devmode with selected print options
  fillCommonPrinterOptions(duplex);
  fillPrinterOptions(duplex, printOpt);

  // Call DocumentProperties again so the driver can update its private data
  // with the modified print options. This will also display the printer
  // properties dialog if setupdlg is true.
  int ret;
  DWORD mode = DM_IN_BUFFER | DM_OUT_BUFFER;
  if (setupdlg)
    mode |= DM_IN_PROMPT;
  ret = DocumentPropertiesA(NULL, NULL, printerName, devmode, devmode, mode);
  if (ret < 0) {
    fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
    exit(99);
  }
  if (setupdlg && ret == IDCANCEL)
    exit(0);

  hdc = CreateDCA(NULL, printerName, NULL, devmode);
  if (!hdc) {
    fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
    exit(99);
  }
}

void win32ShowPrintDialog(GBool *expand, GBool *noShrink, GBool *noCenter,
			  GBool *usePDFPageSize, GBool *allPages,
			  int *firstPage, int *lastPage, int maxPages)
{
  PRINTDLG pd;
  memset(&pd, 0, sizeof(PRINTDLG));
  pd.lStructSize = sizeof(PRINTDLG);
  pd.Flags = PD_NOSELECTION | PD_ENABLEPRINTHOOK | PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
  if (*allPages) {
    pd.nFromPage = 1;
    pd.nToPage = maxPages;
  } else {
    pd.Flags |= PD_PAGENUMS;
    pd.nFromPage = *firstPage;
    pd.nToPage = *lastPage;
  }
  pd.nCopies = 1;
  pd.nMinPage = 1;
  pd.nMaxPage = maxPages;
  pd.lpfnPrintHook = printDialogHookProc;
  if (!*expand && *noShrink)
    pageScale = NONE;
  else if (!*expand && !*noShrink)
    pageScale = SHRINK;
  else
    pageScale = FIT;
  centerPage = !*noCenter;
  useOrigPageSize = *usePDFPageSize;

  if (PrintDlgA(&pd)) {
    // Ok
    hDevnames = pd.hDevNames;
    DEVNAMES *devnames = (DEVNAMES*)GlobalLock(hDevnames);
    printerName = (char*)devnames + devnames->wDeviceOffset;
    hDevmode = pd.hDevMode;
    devmode = (DEVMODEA*)GlobalLock(hDevmode);
    hdc = pd.hDC;
    if (pd.Flags & PD_PAGENUMS) {
      *allPages = gFalse;
      *firstPage = pd.nFromPage;
      *lastPage = pd.nToPage;
    } else {
      *allPages = gTrue;
    }
    if (pageScale == NONE) {
      *expand = gFalse;
      *noShrink = gTrue;
    } else if (pageScale == SHRINK) {
      *expand = gFalse;
      *noShrink = gFalse;
    } else {
      *expand = gTrue;
      *noShrink = gFalse;
    }
    *noCenter = !centerPage;
    *usePDFPageSize = useOrigPageSize;
  } else {
    // Cancel
    exit(0);
  }
}

cairo_surface_t *win32BeginDocument(GooString *inputFileName, GooString *outputFileName)
{
  DOCINFOA docinfo;
  memset(&docinfo, 0, sizeof(docinfo));
  docinfo.cbSize = sizeof(docinfo);
  if (inputFileName->cmp("fd://0") == 0)
    docinfo.lpszDocName = "pdftocairo <stdin>";
  else
    docinfo.lpszDocName = inputFileName->getCString();
  if (outputFileName)
    docinfo.lpszOutput = outputFileName->getCString();
  if (StartDocA(hdc, &docinfo) <=0) {
    fprintf(stderr, "Error: StartDoc failed\n");
    exit(99);
  }

  return cairo_win32_printing_surface_create(hdc);
}

void win32BeginPage(double *w, double *h, GBool changePageSize, GBool useFullPage)
{
  if (changePageSize)
    fillPagePrinterOptions(*w, *h);
  if (DocumentPropertiesA(NULL, NULL, printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER) < 0) {
    fprintf(stderr, "Error: Printer \"%s\" not found\n", printerName);
    exit(99);
  }
  ResetDCA(hdc, devmode);

  // Get actual paper size or if useFullPage is false the printable area.
  // Transform the hdc scale to points to be consistent with other cairo backends
  int x_dpi = GetDeviceCaps (hdc, LOGPIXELSX);
  int y_dpi = GetDeviceCaps (hdc, LOGPIXELSY);
  int x_off = GetDeviceCaps (hdc, PHYSICALOFFSETX);
  int y_off = GetDeviceCaps (hdc, PHYSICALOFFSETY);
  if (useFullPage) {
    *w = GetDeviceCaps (hdc, PHYSICALWIDTH)*72.0/x_dpi;
    *h = GetDeviceCaps (hdc, PHYSICALHEIGHT)*72.0/y_dpi;
  } else {
    *w = GetDeviceCaps (hdc, HORZRES)*72.0/x_dpi;
    *h = GetDeviceCaps (hdc, VERTRES)*72.0/y_dpi;
  }
  XFORM xform;
  xform.eM11 = x_dpi/72.0;
  xform.eM12 = 0;
  xform.eM21 = 0;
  xform.eM22 = y_dpi/72.0;
  if (useFullPage) {
    xform.eDx = -x_off;
    xform.eDy = -y_off;
  } else {
    xform.eDx = 0;
    xform.eDy = 0;
  }
  SetGraphicsMode (hdc, GM_ADVANCED);
  SetWorldTransform (hdc, &xform);

  StartPage(hdc);
}

void win32EndPage(GooString *imageFileName)
{
  EndPage(hdc);
}

void win32EndDocument()
{
  EndDoc(hdc);
  DeleteDC(hdc);
  if (hDevmode) {
    GlobalUnlock(hDevmode);
    GlobalFree(hDevmode);
  } else {
    gfree(devmode);
  }
  if (hDevnames) {
    GlobalUnlock(hDevnames);
    GlobalFree(hDevnames);
  } else {
    gfree(printerName);
  }
}

#endif // CAIRO_HAS_WIN32_SURFACE
