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

/*
 *  Copyright (C) 2003 Takuro Ashie
 *  Copyright (C) 2004 Hiroyuki Ikzoe
 *
 *  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 "gobject-utils.h"

enum {
	PROP_0,
	PROP_KZ_WINDOW
};


struct _KzPrintDialogPriv
{
	GtkWidget     *to_file;
	GtkWidget     *filename;
	GtkWidget     *saveas;
	GtkWidget     *all_pages;
	GtkWidget     *specified_pages;
	GtkWidget     *selection;
	GtkWidget     *from_page;
	GtkWidget     *to_page;
};

static void     kz_print_dialog_class_init         (KzPrintDialogClass *klass);
static void     kz_print_dialog_init               (KzPrintDialog  *print);
static GObject *kz_print_dialog_constructor        (GType           type,
						    guint           n_props,
						    GObjectConstructParam *props);
static void     kz_print_dialog_dispose            (GObject        *object);
static void     kz_print_dialog_set_property       (GObject       *object,
						    guint          prop_id,
						    const GValue  *value,
						    GParamSpec    *pspec);
static void     kz_print_dialog_get_property       (GObject       *object,
						    guint          prop_id,
						    GValue        *value,
						    GParamSpec    *pspec);

static void     cb_parent_destroy                  (GtkWidget       *widget,
						    KzPrintDialog   *print);
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);

static GtkDialogClass *parent_class = NULL;


KZ_OBJECT_GET_TYPE(kz_print_dialog, "KzPrintDialog", KzPrintDialog,
		   kz_print_dialog_class_init, kz_print_dialog_init,
		   GTK_TYPE_DIALOG)

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

	parent_class = g_type_class_peek_parent (klass);

	gobject_class = (GObjectClass *) klass;

	/* GtkObject signals */
	gobject_class->constructor  = kz_print_dialog_constructor;
	gobject_class->dispose      = kz_print_dialog_dispose;
	gobject_class->set_property = kz_print_dialog_set_property;
	gobject_class->get_property = kz_print_dialog_get_property;

	g_object_class_install_property
		(gobject_class,
		 PROP_KZ_WINDOW,
		 g_param_spec_object("kz-window",
				      _("KzWindow"),
				     _("The parent kazehakase window"),
				     KZ_TYPE_WINDOW,
				     G_PARAM_READWRITE |
				     G_PARAM_CONSTRUCT_ONLY));
}


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

	default_filename = g_build_filename(g_get_current_dir(), 
					    "file.ps", NULL);
	
	print->kz = NULL;
	print->priv = g_new0(KzPrintDialogPriv, 1);
	

	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_dialog_add_buttons(GTK_DIALOG(print),
			       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			       GTK_STOCK_PRINT,  GTK_RESPONSE_ACCEPT,
			       NULL);

	/* printer */
	frame = gtk_frame_new(_("Printer"));
	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);

	hbox = gtk_hbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
	gtk_container_add(GTK_CONTAINER(frame), hbox);
	gtk_widget_show(hbox);
	
	label = gtk_label_new(_("Print to:"));
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);	
	gtk_widget_show(label);
	radio1 = gtk_radio_button_new_with_mnemonic(NULL,
						  _("Printer"));
	print->priv->to_file = radio2 =
		gtk_radio_button_new_with_mnemonic_from_widget(
		 	GTK_RADIO_BUTTON(radio1),
			_("File"));

	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio1), TRUE);
	
	gtk_box_pack_start(GTK_BOX(hbox), radio1, FALSE, FALSE, 2);
	gtk_box_pack_start(GTK_BOX(hbox), radio2, FALSE, FALSE, 2);
	print->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);
	print->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);
	
	print->priv->all_pages = radio1 = 
		gtk_radio_button_new_with_mnemonic(NULL,
						  _("All Pages"));
	gtk_box_pack_start(GTK_BOX(vbox), radio1, TRUE, TRUE, 2);
	
	print->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);	
	
	print->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);
	print->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);
	
	print->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*
kz_print_dialog_constructor (GType                  type,
			     guint                  n_props,
			     GObjectConstructParam *props)
{
	GtkWidget *widget;
	KzPrintDialog *print;
	GObject *object;
	GObjectClass *klass = G_OBJECT_CLASS(parent_class);

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

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

	g_signal_connect(print->kz, "destroy",
			 G_CALLBACK(cb_parent_destroy), print);

	gtk_window_set_title(GTK_WINDOW(print), _("Print"));

	return object;
}


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

	if (print->kz)
	{
		g_signal_handlers_disconnect_by_func
			(print->kz,
			 G_CALLBACK(cb_parent_destroy),
			 print);
		g_object_unref(print->kz);
		print->kz = NULL;
	}

	if (print->info)
	{
		g_free(print->info);
		print->info = NULL;
	}
	
	if (G_OBJECT_CLASS (parent_class)->dispose)
		G_OBJECT_CLASS (parent_class)->dispose(object);
}


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


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

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


GtkWidget *
kz_print_dialog_new (KzWindow *kz)
{
	GtkWidget *widget;

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

	gtk_window_set_transient_for(GTK_WINDOW(widget),
				     GTK_WINDOW(kz));
	return widget;
}


static void
cb_parent_destroy(GtkWidget *widget, KzPrintDialog *print)
{
	g_return_if_fail (KZ_IS_PRINT_DIALOG(print));
	gtk_widget_destroy(GTK_WIDGET(print));
}


static void
cb_save_as_button_clicked (GtkWidget *widget, KzPrintDialog *print)
{
	GtkFileSelection *file_selector;
	const gchar *selected_filename;
	gint result;
	
	g_return_if_fail (KZ_IS_PRINT_DIALOG(print));

	/* open file selector dialog */
	file_selector = GTK_FILE_SELECTION(gtk_file_selection_new (_("Save file")));
	/* gtk_file_selection_set_filename(file_selector, "defaultfilename"); */
	
	result = gtk_dialog_run(GTK_DIALOG(file_selector));
	
	switch (result)
	{
	 case GTK_RESPONSE_OK:
		selected_filename = gtk_file_selection_get_filename(file_selector);
		gtk_entry_set_text(GTK_ENTRY(print->priv->filename),
				   selected_filename);
		break;
	 default:
		break;
	}
	gtk_widget_destroy(GTK_WIDGET(file_selector));
}

static void
cb_print_to_file_toggled (GtkToggleButton *button, KzPrintDialog *print)
{
	gboolean active = gtk_toggle_button_get_active(button);
	gtk_widget_set_sensitive(print->priv->filename, active);
	gtk_widget_set_sensitive(print->priv->saveas, active);
}

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

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

PrintInfo *
kz_print_dialog_get_print_info (KzPrintDialog *print)
{
	PrintInfo *info;
	gboolean active;

	info = g_new0(PrintInfo, 1);
	info->to_file   = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(print->priv->to_file));
	info->filename  = gtk_entry_get_text(
				GTK_ENTRY(print->priv->filename)); 
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(print->priv->all_pages));
	if (active)
		info->range = KZ_PRINT_RANGE_ALL_PAGES;
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(print->priv->specified_pages));
	if (active)
		info->range = KZ_PRINT_RANGE_SPECIFIED_PAGES;
	active = gtk_toggle_button_get_active(
				GTK_TOGGLE_BUTTON(print->priv->selection));
	if (active)
		info->range = KZ_PRINT_RANGE_SELECTION;

	info->range     = 
	
	info->from_page = gtk_spin_button_get_value_as_int(
				GTK_SPIN_BUTTON(print->priv->from_page));
	info->to_page   = gtk_spin_button_get_value_as_int(
				GTK_SPIN_BUTTON(print->priv->to_page));
;

	print->info = info;

	return info;
}

