//========================================================================
//
// pdfseparate.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012-2014 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2013 Pino Toscano <pino@kde.org>
// Copyright (C) 2013 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
// Copyright (C) 2013 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
//
//========================================================================
#include "config.h"
#include <poppler-config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "parseargs.h"
#include "goo/GooString.h"
#include "PDFDoc.h"
#include "ErrorCodes.h"
#include "GlobalParams.h"
#include <ctype.h>

static int firstPage = 0;
static int lastPage = 0;
static GBool printVersion = gFalse;
static GBool printHelp = gFalse;

static const ArgDesc argDesc[] = {
  {"-f", argInt, &firstPage, 0,
   "first page to extract"},
  {"-l", argInt, &lastPage, 0,
   "last page to extract"},
  {"-v", argFlag, &printVersion, 0,
   "print copyright and version info"},
  {"-h", argFlag, &printHelp, 0,
   "print usage information"},
  {"-help", argFlag, &printHelp, 0,
   "print usage information"},
  {"--help", argFlag, &printHelp, 0,
   "print usage information"},
  {"-?", argFlag, &printHelp, 0,
   "print usage information"},
  {NULL}
};

bool extractPages (const char *srcFileName, const char *destFileName) {
  char pathName[4096];
  GooString *gfileName = new GooString (srcFileName);
  PDFDoc *doc = new PDFDoc (gfileName, NULL, NULL, NULL);

  if (!doc->isOk()) {
    error(errSyntaxError, -1, "Could not extract page(s) from damaged file ('{0:s}')", srcFileName);
    return false;
  }

  // destFileName can have multiple %% and one %d
  // We use auxDestFileName to replace all the valid % appearances
  // by 'A' (random char that is not %), if at the end of replacing
  // any of the valid appearances there is still any % around, the
  // pattern is wrong
  if (firstPage == 0 && lastPage == 0) {
    firstPage = 1;
    lastPage = doc->getNumPages();
  }
  if (lastPage == 0)
    lastPage = doc->getNumPages();
  if (firstPage == 0)
    firstPage = 1;
  if (lastPage < firstPage) {
    error(errCommandLine, -1,
          "Wrong page range given: the first page ({0:d}) can not be after the last page ({1:d}).",
          firstPage, lastPage);
    return false;
  }
  bool foundmatch = false;
  char *auxDestFileName = strdup(destFileName);
  char *p = strstr(auxDestFileName, "%d");
  if (p != NULL) {
    foundmatch = true;
    *p = 'A';
  } else {
    char pattern[5];
    for (int i = 2; i < 10; i++) {
      sprintf(pattern, "%%0%dd", i);
      p = strstr(auxDestFileName, pattern);
      if (p != NULL) {
       foundmatch = true;
       *p = 'A';
       break;
      }
    }
  }
  if (!foundmatch && firstPage != lastPage) {
    error(errSyntaxError, -1, "'{0:s}' must contain '%%d' if more than one page should be extracted", destFileName);
    free(auxDestFileName);
    return false;
  }

  // at this point auxDestFileName can only contain %%
  p = strstr(auxDestFileName, "%%");
  while (p != NULL) {
    *p = 'A';
    *(p + 1) = 'A';
    p = strstr(p, "%%"); 
  }

  // at this point any other % is wrong
  p = strstr(auxDestFileName, "%");
  if (p != NULL) {
    error(errSyntaxError, -1, "'{0:s}' can only contain one '%d' pattern", destFileName);
    free(auxDestFileName);
    return false;
  }
  free(auxDestFileName);
  
  for (int pageNo = firstPage; pageNo <= lastPage; pageNo++) {
    snprintf (pathName, sizeof (pathName) - 1, destFileName, pageNo);
    GooString *gpageName = new GooString (pathName);
    int errCode = doc->savePageAs(gpageName, pageNo);
    if ( errCode != errNone) {
      delete gpageName;
      delete gfileName;
      return false;
    }
    delete gpageName;
  }
  delete gfileName;
  return true;
}

int
main (int argc, char *argv[])
{
  Object info;
  GBool ok;
  int exitCode;

  exitCode = 99;

  // parse args
  ok = parseArgs (argDesc, &argc, argv);
  if (!ok || argc != 3 || printVersion || printHelp)
    {
      fprintf (stderr, "pdfseparate version %s\n", PACKAGE_VERSION);
      fprintf (stderr, "%s\n", popplerCopyright);
      fprintf (stderr, "%s\n", xpdfCopyright);
      if (!printVersion)
	{
	  printUsage ("pdfseparate", "<PDF-sourcefile> <PDF-pattern-destfile>",
		      argDesc);
	}
      if (printVersion || printHelp)
	exitCode = 0;
      goto err0;
    }
  globalParams = new GlobalParams();
  ok = extractPages (argv[1], argv[2]);
  if (ok) {
    exitCode = 0;
  }
  delete globalParams;

err0:

  return exitCode;
}
