//========================================================================
//
// 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 "Win32Console.h"

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

static HDC hdc;
static HGLOBAL hDevmode = nullptr;
static HGLOBAL hDevnames = nullptr;
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},
  {nullptr, 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},
  {nullptr, 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, nullptr,
		 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(nullptr, &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(nullptr, nullptr, printerName, nullptr, nullptr, 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(nullptr, nullptr, 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(nullptr, nullptr, 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(nullptr, printerName, nullptr, 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(nullptr, nullptr, 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
