//========================================================================
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2014 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>
// Copyright (C) 2014 Adrian Johnson <ajohnson@redneon.com>
//
// 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 <windowsx.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, int 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, (HMENU)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, int 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, (HMENU)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, int 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, (HMENU)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;
}

HWND createPageScaleComboBox(HWND parent, HINSTANCE hinstance, int 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, (HMENU)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, 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, 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, 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, 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, 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
