//========================================================================
//
// 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, 2018 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 = copyString(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
