/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003 Takuro Ashie
 *  Copyright (C) 2004 Hiroyuki Ikezoe
 *
 *  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, 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 "kz-print-dialog.h"

#include <glib/gi18n.h>

#include "kz-window.h"
#include "kz-icons.h"

enum {
	PROP_0,
	PROP_PARENT_WINDOW
};


typedef struct _KzPrintDialogPrivate	KzPrintDialogPrivate;
struct _KzPrintDialogPrivate
{
	GtkWidget     *to_file;
	GtkWidget     *filename;
	GtkWidget     *saveas;
	GtkWidget     *all_pages;
	GtkWidget     *specified_pages;
	GtkWidget     *selection;
	GtkWidget     *from_page;
	GtkWidget     *to_page;
	GtkWidget     *printer_list;
};
#define KZ_PRINT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KZ_TYPE_PRINT_DIALOG, KzPrintDialogPrivate))

static GObject *constructor        (GType           type,
				    guint           n_props,
				    GObjectConstructParam *props);
static void     dispose            (GObject        *object);
static void     set_property       (GObject       *object,
				    guint          prop_id,
				    const GValue  *value,
				    GParamSpec    *pspec);
static void     get_property       (GObject       *object,
				    guint          prop_id,
				    GValue        *value,
				    GParamSpec    *pspec);

static void     cb_print_to_file_toggled           (GtkToggleButton *button,
						    KzPrintDialog   *print);
static void     cb_print_pages_toggled             (GtkToggleButton *button,
						    KzPrintDialog   *print);
static void     cb_save_as_button_clicked          (GtkWidget       *widget,
						    KzPrintDialog   *print);

G_DEFINE_TYPE(KzPrintDialog, kz_print_dialog, GTK_TYPE_DIALOG)

static void
free_print_info (KzPrintDialog *print)
{
	if (print->info)
	{
		if (print->info->printer)
			g_free(print->info->printer);
		print->info->printer = NULL;

		g_free(print->info);
		print->info = NULL;
	}
}

static void
kz_print_dialog_class_init (KzPrintDialogClass *klass)
{
	GObjectClass *gobject_class;

	gobject_class = G_OBJECT_CLASS(klass);

	gobject_class->constructor  = constructor;
	gobject_class->dispose      = dispose;
	gobject_class->set_property = set_property;
	gobject_class->get_property = get_property;

	g_object_class_install_property
		(gobject_class,
		 PROP_PARENT_WINDOW,
		 g_param_spec_object("parent-window",
				     _("ParentWindow"),
				     _("The parent kazehakase window"),
				     GTK_TYPE_WINDOW,
				     G_PARAM_READWRITE |
				     G_PARAM_CONSTRUCT_ONLY));
	g_type_class_add_private (gobject_class, sizeof(KzPrintDialogPrivate));
}


static void
kz_print_dialog_init (KzPrintDialog *print)
{
	GtkWidget *main_vbox, *hbox, *vbox, *frame;
	GtkWidget *entry, *radio1, *radio2, *radio3;
	GtkWidget *label, *spin, *button;
	GtkWidget *combo_box;
	GtkAdjustment *adj;
	gchar *default_filename;
	KzPrintDialogPrivate *priv = KZ_PRINT_DIALOG_GET_PRIVATE (print);

	default_filename = g_build_filename(g_get_current_dir(), 
					    "file.ps", NULL);
	
	print->parent_window = NULL;
	
	main_vbox = GTK_DIALOG(print)->vbox;
	gtk_box_set_spacing(GTK_BOX(main_vbox), 4);
	gtk_window_set_default_size(GTK_WINDOW(print), 600, 450);
	gtk_window_set_icon(GTK_WINDOW(print), kz_icon);
	gtk_window_set_destroy_with_parent(GTK_WINDOW(print), TRUE);

	gtk_dialog_add_buttons(GTK_DIALOG(print),
			       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			       GTK_STOCK_PRINT,  GTK_RESPONSE_ACCEPT,
			       NULL);

	/* printer */
	frame = gtk_frame_new(_("Print to"));
	gtk_frame_set_label_align(GTK_FRAME(frame), 0.03, 0.5);
	gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
	gtk_box_pack_start(GTK_BOX(main_vbox), frame, FALSE, FALSE, 2);
	gtk_widget_show(frame);

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
	gtk_container_add(GTK_CONTAINER(frame), vbox);
	gtk_widget_show(vbox);
	
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
	gtk_container_add(GTK_CONTAINER(vbox), hbox);
	gtk_widget_show(hbox);
	
	radio1 = gtk_radio_button_new_with_mnemonic(NULL,
						  _("Printer"));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio1), TRUE);
	gtk_box_pack_start(GTK_BOX(hbox), radio1, FALSE, FALSE, 2);

	priv->printer_list = combo_box = gtk_combo_box_new_text();
	gtk_box_pack_start(GTK_BOX(hbox), combo_box,
			   FALSE, FALSE, 0);
	gtk_widget_show(combo_box);
	
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
	gtk_container_add(GTK_CONTAINER(vbox), hbox);
	gtk_widget_show(hbox);
	priv->to_file = radio2 =
		gtk_radio_button_new_with_mnemonic_from_widget(
		 	GTK_RADIO_BUTTON(radio1),
			_("File"));
	gtk_box_pack_start(GTK_BOX(hbox), radio2, FALSE, FALSE, 2);

	priv->filename = entry = gtk_entry_new();
	gtk_entry_set_text(GTK_ENTRY(entry), default_filename);
	gtk_widget_show(entry);
	gtk_widget_set_sensitive(entry, FALSE);
	priv->saveas = button = 
			gtk_button_new_from_stock(GTK_STOCK_SAVE_AS);
	g_signal_connect(button, "clicked",
			 G_CALLBACK(cb_save_as_button_clicked), print);
	gtk_widget_show(button);
	gtk_widget_set_sensitive(button, FALSE);
	gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 2);
	gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 2);
	
	g_signal_connect(radio2, "toggled",
			 G_CALLBACK(cb_print_to_file_toggled), print);
	
	gtk_widget_show(radio1);
	gtk_widget_show(radio2);
	
	/* print range */
	frame = gtk_frame_new(_("Print Range"));
	gtk_frame_set_label_align(GTK_FRAME(frame), 0.03, 0.5);
	gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
	gtk_box_pack_start(GTK_BOX(main_vbox), frame, FALSE, FALSE, 2);
	gtk_widget_show(frame);

	vbox = gtk_vbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
	gtk_container_add(GTK_CONTAINER(frame), vbox);
	gtk_widget_show(vbox);
	
	priv->all_pages = radio1 = 
		gtk_radio_button_new_with_mnemonic(NULL,
						  _("All Pages"));
	gtk_box_pack_start(GTK_BOX(vbox), radio1, TRUE, TRUE, 2);
	
	priv->specified_pages = radio2 =
		gtk_radio_button_new_with_mnemonic_from_widget(
		 	GTK_RADIO_BUTTON(radio1),
			_("Pages"));
	hbox = gtk_hbox_new(FALSE, 0);	
	gtk_box_pack_start(GTK_BOX(hbox), radio2, FALSE, FALSE, 0);
	label = gtk_label_new(_("from"));
	gtk_widget_show(label);
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);	
	
	priv->from_page = spin =
			gtk_spin_button_new_with_range(0, 1000, 1);
	adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
	gtk_widget_show(spin);
	gtk_adjustment_set_value(adj, 1);
	gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 2);	
	gtk_widget_set_sensitive(spin, FALSE);
	label = gtk_label_new(_("to"));
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);	
	gtk_widget_show(label);
	priv->to_page = spin =
			gtk_spin_button_new_with_range(0, 1000, 1);
	adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(spin));
	gtk_widget_show(spin);
	gtk_adjustment_set_value(adj, 1);
	gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 2);	
	gtk_widget_set_sensitive(spin, FALSE);

	gtk_widget_show(hbox);
	gtk_box_pack_start(GTK_BOX(vbox), hbox,   TRUE, TRUE, 2);
	
	priv->selection = radio3 =
		gtk_radio_button_new_with_mnemonic_from_widget(
		 	GTK_RADIO_BUTTON(radio1),
			_("Selection"));
	gtk_box_pack_start(GTK_BOX(vbox), radio3, TRUE, TRUE, 2);
	

	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio1), TRUE);
	g_signal_connect(radio2, "toggled",
			 G_CALLBACK(cb_print_pages_toggled), print);
	gtk_widget_show(radio1);
	gtk_widget_show(radio2);
	gtk_widget_show(radio3);
	
	g_free(default_filename);
}


static GObject*
constructor (GType                  type,
	     guint                  n_props,
	     GObjectConstructParam *props)
{
	GtkWidget *widget;
	KzWeb *web;
	KzPrintDialog *print;
	GObject *object;
	GObjectClass *klass = G_OBJECT_CLASS(kz_print_dialog_parent_class);
	KzPrintDialogPrivate *priv;

	object = klass->constructor(type, n_props, props);

	print = KZ_PRINT_DIALOG(object);
	priv = KZ_PRINT_DIALOG_GET_PRIVATE(print);
	widget = GTK_WIDGET(print);

	gtk_window_set_title(GTK_WINDOW(print), _("Print"));
	gtk_window_set_transient_for(GTK_WINDOW(print), GTK_WINDOW(print->parent_window));

	web = KZ_WINDOW_CURRENT_WEB(KZ_WINDOW(print->parent_window));

	if (web)
	{
		GList *printer_list, *node;

		printer_list = kz_web_get_printer_list(web);

		for (node = g_list_first(printer_list); node; node = g_list_next(node))
		{
			gtk_combo_box_append_text(GTK_COMBO_BOX(priv->printer_list),
						  node->data);	
		}

		gtk_combo_box_set_active(GTK_COMBO_BOX(priv->printer_list),
					 0);

		if (printer_list)
			g_list_free(printer_list);
	}

	return object;
}


static void
dispose (GObject *object)
{
	KzPrintDialog *print = KZ_PRINT_DIALOG(object);

	if (print->parent_window)
	{
		g_object_unref(print->parent_window);
		print->parent_window = NULL;
	}

	free_print_info (print);

	if (G_OBJECT_CLASS (kz_print_dialog_parent_class)->dispose)
		G_OBJECT_CLASS (kz_print_dialog_parent_class)->dispose(object);
}


static void
set_property (GObject         *object,
	      guint            prop_id,
	      const GValue    *value,
	      GParamSpec      *pspec)
{
	KzPrintDialog *print = KZ_PRINT_DIALOG(object);
  
	switch (prop_id)
	{
	case PROP_PARENT_WINDOW:
		print->parent_window = g_object_ref(g_value_get_object(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


static void
get_property (GObject         *object,
	      guint            prop_id,
	      GValue          *value,
	      GParamSpec      *pspec)
{
	KzPrintDialog *print = KZ_PRINT_DIALOG(object);

	switch (prop_id)
	{
	case PROP_PARENT_WINDOW:
		g_value_set_object(value, print->parent_window);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


GtkWidget *
kz_print_dialog_new (GtkWindow *parent_window)
{
	GtkWidget *widget;

	widget = GTK_WIDGET(g_object_new(KZ_TYPE_PRINT_DIALOG,
					 "parent-window", parent_window,
					 NULL));

	return widget;
}


static void
cb_save_as_button_clicked (GtkWidget *widget, KzPrintDialog *print)
{
	GtkWidget *file_dialog;
	gchar *selected_filename = NULL;
	gint result;
	KzPrintDialogPrivate *priv = KZ_PRINT_DIALOG_GET_PRIVATE (print);
	
	g_return_if_fail (KZ_IS_PRINT_DIALOG(print));

	/* open file chooser dialog */
	file_dialog = gtk_file_chooser_dialog_new(_("Save file"),
						  GTK_WINDOW(print),
						  GTK_FILE_CHOOSER_ACTION_SAVE,
						  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
						  GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
						  NULL);
	gtk_dialog_set_default_response(GTK_DIALOG(file_dialog),
					GTK_RESPONSE_ACCEPT);
	result = gtk_dialog_run(GTK_DIALOG(file_dialog));
	
	switch (result)
	{
	 case GTK_RESPONSE_ACCEPT:
		selected_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_dialog));
		gtk_entry_set_text(GTK_ENTRY(priv->filename),
				   selected_filename);
		break;
	 default:
		break;
	}

	if (selected_filename)
		g_free(selected_filename);

	gtk_widget_destroy(file_dialog);
}

static void
cb_print_to_file_toggled (GtkToggleButton *button, KzPrintDialog *print)
{
	KzPrintDialogPrivate *priv = KZ_PRINT_DIALOG_GET_PRIVATE (print);
	gboolean active = gtk_toggle_button_get_active(button);

	gtk_widget_set_sensitive(priv->filename, active);
	gtk_widget_set_sensitive(priv->saveas, active);
	gtk_widget_set_sensitive(priv->printer_list, !active);
}

static void
cb_print_pages_toggled (GtkToggleButton *button, KzPrintDialog *print)
{
	KzPrintDialogPrivate *priv = KZ_PRINT_DIALOG_GET_PRIVATE (print);
	gboolean active = gtk_toggle_button_get_active(button);

	gtk_widget_set_sensitive(priv->to_page, active);
	gtk_widget_set_sensitive(priv->from_page, active);
}

PrintInfo *
kz_print_dialog_get_print_info (KzPrintDialog *print)
{
	PrintInfo *info;
	gboolean active;
  	GtkTreeIter iter;
	gchar *text = NULL;
	KzPrintDialogPrivate *priv = KZ_PRINT_DIALOG_GET_PRIVATE (print);

	info = g_new0(PrintInfo, 1);

  	if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(priv->printer_list),
	      				  &iter))
	{
		GtkTreeModel *model;
		model = gtk_combo_box_get_model(GTK_COMBO_BOX(priv->printer_list));
		gtk_tree_model_get (model, &iter, 
				    0, &text, -1);
	}

	info->printer = text;

	info->to_file   = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(priv->to_file));
	info->filename  = gtk_entry_get_text(
				GTK_ENTRY(priv->filename)); 
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(priv->all_pages));
	if (active)
		info->range = KZ_PRINT_RANGE_ALL_PAGES;
	
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(priv->specified_pages));
	if (active)
		info->range = KZ_PRINT_RANGE_SPECIFIED_PAGES;
	
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(priv->selection));
	if (active)
		info->range = KZ_PRINT_RANGE_SELECTION;
	
	info->from_page = gtk_spin_button_get_value_as_int(
				GTK_SPIN_BUTTON(priv->from_page));
	info->to_page   = gtk_spin_button_get_value_as_int(
				GTK_SPIN_BUTTON(priv->to_page));

	free_print_info (print);

	print->info = info;

	return info;
}

