/*
 * Copyright (C) 2004  Stefan Kleine Stegemann
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include "poppler_cairo_img_renderer.h"
#include <PDFDoc.h>
#include <Page.h>
#include <goo/GooString.h>
#include <CairoOutputDevImage.h>

#define PDF_DOC(obj) static_cast<PDFDoc*>(obj)
#define PAGE(obj) static_cast<Page*>(obj)
#define CAIRO_DEV_IMG(obj) static_cast<CairoOutputDevImage*>(obj)

void* poppler_cairo_img_device_create(void)
{   
   return new CairoOutputDevImage();
}

void poppler_splash_device_start_doc(void* output_dev, void* poppler_document)
{
   if (!output_dev || !poppler_document)
   {
     return;
   }
    
   CAIRO_DEV_IMG(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef());
}

void poppler_cairo_img_device_start_doc(void* output_dev, void* poppler_document)
{
   if (!output_dev || !poppler_document)
   {
     return;
   }
    
   CAIRO_DEV_IMG(output_dev)->startDoc(PDF_DOC(poppler_document)->getXRef());
}

void poppler_cairo_img_device_destroy(void* output_dev)
{
   if (!output_dev)
   {
      return;
   }
   
   delete CAIRO_DEV_IMG(output_dev);
}

int poppler_cairo_img_device_display_slice(void* output_dev, void* poppler_page,
                                        void* poppler_document,
                                        float hDPI, float vDPI, int rotate,
                                        float sliceX, float sliceY,
                                        float sliceW, float sliceH)
{
   if (!output_dev || !poppler_page || !poppler_document)
   {
      return 0;
   }
    
   PAGE(poppler_page)->displaySlice(CAIRO_DEV_IMG(output_dev),
                                    (double)hDPI, (double)vDPI,
                                    rotate,
                                    gTrue, // Crop
                                    (int)sliceX, (int)sliceY,
                                    (int)sliceW, (int)sliceH,
                                    NULL, // Links
                                    PDF_DOC(poppler_document)->getCatalog());
                                     
  return 1;
}

int poppler_cairo_img_device_get_data(void* output_dev, unsigned char** data,
                                      int* width, int* height, int* rowstride)
{
   if (!output_dev)
   {
      return 0;
   }
   
   int cairo_width, cairo_height, cairo_rowstride;
   unsigned char* cairo_data = NULL;

   CAIRO_DEV_IMG(output_dev)->getBitmap(&cairo_data, &cairo_width, &cairo_height,
                                        &cairo_rowstride);
                                        
   if (!cairo_data)
   {
      return 0;
   }
   
   *data = cairo_data;
   *width = cairo_width;
   *height = cairo_height;
   *rowstride = cairo_rowstride;
   
   return 1;
}

int poppler_cairo_img_device_get_rgb(unsigned char* cairo_data, unsigned char** rgb_data,
                                     int width, int height, int rowstride)
{
   if (!cairo_data)
   {
      return 0;
   }

   unsigned char* rgb_data_ptr = *rgb_data;
   for (int row = 0; row < height; row++)
   {
      unsigned int *src;
      src = (unsigned int *) (cairo_data + row * rowstride);
      for (int col = 0; col < width; col++)
      {
         *rgb_data_ptr++ = (*src >> 16) & 0xff;
         *rgb_data_ptr++ = (*src >> 8) & 0xff;
         *rgb_data_ptr++ = (*src >> 0) & 0xff;
         src++;
      }
   }

   return 1;
}
