/*
This file is part of Gnome Photo Printer.

    Gnome Photo Printer 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.

    Gnome Photo Printer 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 Gnome Photo Printer; 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 <gnome.h>
#include <glade/glade.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomeprint/gnome-print.h>
#include <libgnomeprint/gnome-print-job.h>
#include <libgnomeprintui/gnome-print-dialog.h>
#include "gpp_print.h"
#include "gpp_functions.h"
#include "gpp_widget.h"
#include "gpp_callbacks.h"
#include "gpp.h"

/* Prints the Pixbuf to the drawing area (Taken from libgnomeprint -> examples */
void
gpp_print_pixbuf (GdkPixbuf * pixbuf)
{
	guchar *raw_image;
	gboolean has_alpha;
	gint rowstride, height, width;

	raw_image = gdk_pixbuf_get_pixels (pixbuf);
	has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
	rowstride = gdk_pixbuf_get_rowstride (pixbuf);
	height = gdk_pixbuf_get_height (pixbuf);
	width = gdk_pixbuf_get_width (pixbuf);

	if (has_alpha)
		gnome_print_rgbaimage (gpp_context, (char *) raw_image, width,
				       height, rowstride);
	else
		gnome_print_rgbimage (gpp_context, (char *) raw_image, width,
				      height, rowstride);
}

/* Prints the Pictures */
void
gpp_print_pictures (char *name)
{
	GdkPixbuf *pixbuf;
	GError *error;
	gdouble scale_x,scale_y;

	/* Load the image into a pixbuf */
	error = NULL;
	pixbuf = gdk_pixbuf_new_from_file (name, &error);
	if (!pixbuf)
	{
		g_print ("Could not load %s.\n", &name);
		return;
	}

	/* Rotate if nescassary */
	if (((gpp_definition->layout_x < gpp_definition->layout_y)&&(gdk_pixbuf_get_width (pixbuf) > gdk_pixbuf_get_height (pixbuf)))
		||((gpp_definition->layout_x > gpp_definition->layout_y)&&(gdk_pixbuf_get_width (pixbuf) < gdk_pixbuf_get_height (pixbuf))))
			pixbuf = gpp_gdk_rotate_pixbuf_90 (pixbuf);
		
	/* Save the graphic context, scale, print the image and restore */
	gnome_print_gsave (gpp_context);

	/* Scale to requested Size */
	if(gpp_definition->image_scale_with_ratio)
	{
		scale_x=gdk_pixbuf_get_width(pixbuf)/gpp_definition->layout_x;
		scale_y=gdk_pixbuf_get_height(pixbuf)/gpp_definition->layout_y;
		if(scale_x>=scale_y)
			gnome_print_scale (gpp_context, gpp_definition->layout_x, gpp_definition->layout_y*(scale_y/scale_x));
				else gnome_print_scale (gpp_context, gpp_definition->layout_x*(scale_x/scale_y), gpp_definition->layout_y);
	} else {
		gnome_print_scale (gpp_context, gpp_definition->layout_x, gpp_definition->layout_y);
	}
	
	/* Print to graphic context */
	gpp_print_pixbuf (pixbuf);

	/* Restore the graphic context */
	gnome_print_grestore (gpp_context);
	g_object_unref (G_OBJECT (pixbuf));
}

/* Arranges the Pictures on a Page by given Layout */
void
gpp_arrange_pictures ()
{
	GtkTreeIter iter;
	GtkTreeModel *tree;
	gboolean valid;
	gint i, j, x, y, num_x, num_y, f = 0;
	gdouble space_x, space_y, pos_x = 0, pos_y = 0;

	tree=gpp_definition->file_names;
	valid = gtk_tree_model_get_iter_first (tree, &iter);
	
	gpp_calculate_rotate_pictures();
	
	space_x = gpp_calculate_space_between_pics (gpp_definition->paper_size_x, gpp_definition->layout_x);
	space_y = gpp_calculate_space_between_pics (gpp_definition->paper_size_y, gpp_definition->layout_y);
	
	num_x = gpp_calculate_fit_to_page (gpp_definition->paper_size_x, gpp_definition->layout_x);
	num_y = gpp_calculate_fit_to_page (gpp_definition->paper_size_y, gpp_definition->layout_y);

/* Just Debug Information to print on console 
	g_printf ("Space X: %f\n", space_x);
	g_printf ("Space Y: %f\n", space_y);
	g_printf ("Number of Pages: %d\n", gpp_calculate_number_of_sites ());
	g_printf ("Pics on page: %d\n", gpp_calculate_pics_on_page ());
*/

	/* Arrange the Pictures */
	for (i = 0; i < gpp_calculate_number_of_sites (); i++)
	{
		gnome_print_beginpage (gpp_context, NULL);

		for (y = 0; y < num_y; y++)
		{
			pos_y = pos_y + space_y;
			for (x = 0; x < num_x; x++)
			{
				f++;
				pos_x = pos_x + space_x;
/* Just for debugging 
				g_printf ("X: %f, Y: %f \n", pos_x, pos_y);
*/				
				if (valid)
				{
					gchar *str_data;
					
					gnome_print_translate (gpp_context,pos_x, pos_y);

      					gtk_tree_model_get (tree, &iter, FILE_COLUMN, &str_data,-1);
/* Just for debugging 					
      					g_printf("File Names to print: %s",str_data);
*/
      					gpp_print_pictures (str_data);
					
					g_free (str_data);
					valid = gtk_tree_model_iter_next (tree, &iter);
				}
				
				
				pos_y = 0;
				pos_x = 0;

				pos_x = pos_x + gpp_definition->layout_x;
			}

			pos_x = 0 - (f - 1) * gpp_definition->layout_x - f * space_x;
			pos_y = pos_y + gpp_definition->layout_y;
		}
		
		pos_x = 0;
		pos_y = 0;
		f = 0;
		gnome_print_showpage (gpp_context);
	}
	
}

/* Starts Printing.
   FIXME soon as libgnomeprint gets fixed! 
   Look at gpp_get_settings_from_libgnomeprint () for getting a clue */
void
gpp_start_printing ()
{
	gnome_print_job_print_to_file (gpp_job,gpp_definition->output_file_name);

/* Should look this way! 
	if (gpp_definition->to_file == TRUE)
	{
		g_printf ("Printing to File!\n");
		gnome_print_job_print_to_file (gpp_job,
					       gpp_definition->
					       output_file_name);
	}
	else
	{
		g_printf ("Printing to Printer!\n");
	}
*/

	gpp_start_printing_done ();
}

/* Finishes Printing */
void
gpp_start_printing_done ()
{
	gnome_print_job_close (gpp_job);
	gnome_print_job_print (gpp_job);
	g_object_unref (G_OBJECT (gpp_context));
	g_object_unref (G_OBJECT (gpp_job));
	g_object_unref (G_OBJECT (gpp_config));
}
