/*
  gyrus-report.c

  GYRUS -- GNOME Cyrus Administrator.

  Copyright (C) 2005 Alejandro Valdés <avaldes@utalca.cl>

 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, see <http://www.gnu.org/licenses/>.

*/

#include <config.h>

#include "gyrus-report.h"
#include "glib/gi18n.h"
#include <glib/gprintf.h>
#include "gyrus-admin-mailbox.h"
#include "gyrus-common.h"
#include <string.h>
#include <math.h>

#define HEADER_HEIGHT (10*72/25.4)
#define HEADER_GAP (3*72/25.4)
#define TITLE_HEIGHT (8*72/25.4)
#define TITLE_GAP (3*72/25.4)

typedef struct _GyrusReportData {
        GyrusAdmin *admin;

        gdouble n_percen;
	gint num_users;
	gchar *mailbox_temp;

	GtkWidget *button_print;
	GtkWidget *window_report;
        GtkWidget *spin_report;
        GtkTreeView *treeview_report;

	gdouble font_size;
	gint lines_per_page;
	gint num_pages;
	gint num_lines;
	gchar *title;
} GyrusReportData;

typedef enum {
	COLUMN_FOLDER = 0,
	COLUMN_MAILBOX,
	COLUMN_PERCENTAGE,
	COLUMN_QUOTA_LIMIT,
	COLUMN_QUOTA_USED,
	NUM_COLUMN
} GyrusReportColumn;

static void gyrus_report_on_button_cancel_clicked (GtkWidget *widget, GyrusReportData *report);
static void gyrus_report_on_button_update_clicked (GtkWidget *widget, GyrusReportData *report);
static gboolean gyrus_report_evaluate_quota (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
static GtkTreeView * gyrus_report_initialize_tree_view (GtkTreeView *treeview_report);
static void gyrus_report_on_delete_event_window_report (GtkWidget *widget, GdkEvent *event, GyrusReportData *report);
static void gyrus_report_on_button_print_clicked(GtkWidget *widget, GyrusReportData *report);

/* read glade file, connect signal and show window */
void
gyrus_report_show_report (GyrusAdmin *admin)
{
	GtkBuilder *builder;

	GtkWidget *button_cancel;
	GtkWidget *button_update;

	GyrusReportData *report;
	report = g_new0 (GyrusReportData,1);

	report->mailbox_temp = NULL;
	report->admin = admin;

	builder = gtk_builder_new ();
	gtk_builder_add_from_resource (builder, "/org/gnome/gyrus/report.xml", NULL);

	report->window_report = GTK_WIDGET (gtk_builder_get_object (builder, "window-report"));
	button_cancel = GTK_WIDGET (gtk_builder_get_object (builder, "button-cancel"));
	button_update = GTK_WIDGET (gtk_builder_get_object (builder, "button-update"));
	report->spin_report = GTK_WIDGET (gtk_builder_get_object (builder, "spinbutton-percentage"));
	report->treeview_report = GTK_TREE_VIEW (gtk_builder_get_object (builder,"treeview-report"));
	report->button_print = GTK_WIDGET (gtk_builder_get_object (builder, "button-print"));

	gtk_widget_set_sensitive (report->button_print, FALSE);

	/* set title */
	report->title = g_strdup_printf (_("Mailbox space usage report for %s"), 
					 gyrus_admin_get_current_session_name (admin));
	gtk_window_set_title (GTK_WINDOW (report->window_report), report->title);

	/* initialize treeview_report */
	report->treeview_report = gyrus_report_initialize_tree_view (report->treeview_report);

	/* signal */
	g_signal_connect (G_OBJECT (report->window_report), "delete_event",
                          G_CALLBACK (gyrus_report_on_delete_event_window_report),
                          report);
	
	g_signal_connect (G_OBJECT (button_cancel), "clicked",
                          G_CALLBACK (gyrus_report_on_button_cancel_clicked),
                          report);

	g_signal_connect (G_OBJECT (button_update), "clicked",
                          G_CALLBACK (gyrus_report_on_button_update_clicked),
                          report);

	g_signal_connect (G_OBJECT (report->button_print), "clicked",
                          G_CALLBACK (gyrus_report_on_button_print_clicked),
                          report);
	gtk_widget_show_all (report->window_report);

	g_object_unref (builder);
}


static void
gyrus_report_cell_data_func (GtkTreeViewColumn *tree_column,
			     GtkCellRenderer *renderer,
			     GtkTreeModel *tree_model,
			     GtkTreeIter *iter,
			     gpointer data)
{
	gdouble perc;
	gchar   buf[20];
	
	gtk_tree_model_get(tree_model, iter, 
			   COLUMN_PERCENTAGE, &perc,
			   -1);
	
	g_snprintf(buf, sizeof(buf), 
				"%.1f", perc);
	
	g_object_set(renderer, "text", 
		     buf, NULL);
}

/* initialize treeview report*/
static GtkTreeView *
gyrus_report_initialize_tree_view (GtkTreeView *treeview_report)
{
        GtkTreeViewColumn* column;
        GtkCellRenderer *renderer;
        GtkTreeModel *model;

	gtk_tree_view_set_reorderable  (treeview_report, FALSE);

	/* new column user and cell with pixbuf */
        column = gtk_tree_view_column_new ();
        gtk_tree_view_column_set_title (column, _("Users"));

        renderer = gtk_cell_renderer_pixbuf_new ();
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
	g_object_set (G_OBJECT (renderer),
	              "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR,
	              NULL);
        gtk_tree_view_column_set_attributes (column, renderer,
					     "icon-name", COLUMN_FOLDER,
					     NULL);
	
        renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
        gtk_tree_view_column_set_attributes (column, renderer,
					     "text", COLUMN_MAILBOX,
					     NULL);
	
	gtk_tree_view_append_column (treeview_report, column);

	/* new column quota */
        column = gtk_tree_view_column_new ();
        gtk_tree_view_column_set_title (column, _("Quota (%)"));
        
	renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
	gtk_tree_view_column_set_cell_data_func(column, renderer, 
						gyrus_report_cell_data_func, NULL, NULL);
        gtk_tree_view_column_set_attributes (column, renderer,
					     "text", COLUMN_PERCENTAGE,
					     NULL);
	gtk_tree_view_append_column (treeview_report, column);

	/* new column assigned */
        column = gtk_tree_view_column_new ();
        gtk_tree_view_column_set_title (column, _("Assigned (KB)"));
        
	renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
        gtk_tree_view_column_set_attributes (column, renderer,
					     "text", COLUMN_QUOTA_LIMIT,
					     NULL);
	gtk_tree_view_append_column (treeview_report, column);
	
	/* new column used */
        column = gtk_tree_view_column_new ();
        gtk_tree_view_column_set_title (column, _("Used (KB)"));
        
	renderer = gtk_cell_renderer_text_new ();
        gtk_tree_view_column_pack_start (column, renderer, FALSE);
        gtk_tree_view_column_set_attributes (column, renderer,
					     "text", COLUMN_QUOTA_USED,
					     NULL);
	gtk_tree_view_append_column (treeview_report, column);
	
	/* create model */
	model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLUMN,
						    G_TYPE_STRING,
						    G_TYPE_STRING,
						    G_TYPE_INT,
						    G_TYPE_INT,
						    G_TYPE_INT));
	
	gtk_tree_view_set_model (treeview_report, model); 

	return treeview_report;
}

/* close window */
static void
gyrus_report_on_delete_event_window_report (GtkWidget *widget, 
					    GdkEvent *event, 
					    GyrusReportData *report)
{
	gyrus_report_on_button_cancel_clicked (NULL,report);
}

/* close window */
static void
gyrus_report_on_button_cancel_clicked (GtkWidget *widget, 
				       GyrusReportData *report)
{
	gtk_widget_destroy (report->window_report);
	g_free (report->title);
	g_free (report);
}

/* compare each mailbox */
static void
gyrus_report_on_button_update_clicked (GtkWidget *widget, 
				       GyrusReportData *report)
{
	GtkListStore *store;
        GtkTreeViewColumn *column;
	GtkTreeView *treeview;
        gchar *msg;
	GyrusAdmin *admin;
	GtkTreeModel *model;

	admin = report->admin;

	/* get value */
	report->n_percen = gtk_spin_button_get_value (GTK_SPIN_BUTTON(report->spin_report));
	
	/* clear store */
	store = GTK_LIST_STORE (gtk_tree_view_get_model (report->treeview_report));
	gtk_list_store_clear (store);
		
	/* get model of treeview users */
	treeview = gyrus_admin_get_users_treeview (admin);
	model = gtk_tree_view_get_model (treeview);

	/* for each user */
	gtk_tree_model_foreach (model, gyrus_report_evaluate_quota, report);

        /* get the number of users in the tree */
        report->num_users = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(store), NULL);
        column = gtk_tree_view_get_column 
		(GTK_TREE_VIEW(report->treeview_report), 0);

        msg = g_strdup_printf (_("Users (%d)"), report->num_users);
        gtk_tree_view_column_set_title (column, msg);
	
	/* enable/disable button print */
	if (report->num_users > 0){
		gtk_widget_set_sensitive (report->button_print, TRUE);
	}else{
		gtk_widget_set_sensitive (report->button_print, FALSE);
	}
        
	g_free (msg);
	g_object_unref (treeview);
}

/* evaluate percentage */
static gboolean  
gyrus_report_evaluate_quota (GtkTreeModel *model, 
			     GtkTreePath *path, 
			     GtkTreeIter *iter, 
			     gpointer data)
{
	GyrusReportData *report = data;
	GyrusAdmin *admin = report->admin;	
	gchar *mailbox;
	gint quota_limit, quota_used;
	gint per_user;
	gchar *msg;
	gfloat temp_per;
	gchar **v_mailbox;
	
	GtkListStore *store;
	GtkTreeIter iter_new;	

	gint per = report->n_percen;
	gboolean passed = TRUE;

	store = GTK_LIST_STORE (gtk_tree_view_get_model (report->treeview_report));

	/* get mailbox */
        gtk_tree_model_get (model, iter, 
			    COL_MAILBOX_NAME, &mailbox, 
			    -1);
	
	/* get quota of mailbox */
	if (gyrus_admin_mailbox_get_quota (admin, mailbox, &quota_limit, 
					   &quota_used, &msg) && quota_limit > 0)
	{
#define ALEJANDRO_FILTER
#ifdef ALEJANDRO_FILTER

		/* filter for main folder */
		v_mailbox = g_strsplit (mailbox, gyrus_admin_get_separator_char (admin), 
					-1);
	
		/* first mailbox */
		if (report->mailbox_temp==NULL){
			report->mailbox_temp = v_mailbox[1];
			passed = TRUE;
		}else{
			/* same mailbox? */
			if (strcmp(report->mailbox_temp,v_mailbox[1])==0){
				passed = FALSE;
			}else{
				/* other mailbox */
				report->mailbox_temp = v_mailbox[1];
				passed = TRUE;
			}
		}
		if (passed){
			temp_per = ((quota_used * 100 )/ quota_limit);
			per_user = (gint) temp_per;
			
			if (per_user >= per){
				/* add user to treeview */
				gtk_list_store_append (store, &iter_new);
				gtk_list_store_set (store, &iter_new,
						    COLUMN_FOLDER, "folder",
						    COLUMN_MAILBOX, v_mailbox[1],
						    COLUMN_PERCENTAGE, per_user,
						    COLUMN_QUOTA_LIMIT, quota_limit,
						    COLUMN_QUOTA_USED, quota_used,
						    -1);
			}
		}
		g_strfreev (v_mailbox);
#else
		temp_per = ((quota_used * 100 )/ quota_limit);
		per_user = (gint) temp_per;

		if (per_user >= per){
			/* add user to treeview */
			gtk_list_store_append (store, &iter_new);
			gtk_list_store_set (store, &iter_new,
					    COLUMN_FOLDER, "folder",
					    COLUMN_MAILBOX, mailbox,
					    COLUMN_PERCENTAGE, per_user,
					    COLUMN_QUOTA_LIMIT, quota_limit,
					    COLUMN_QUOTA_USED, quota_used,
					    -1);
		}
#endif

	} else {
		g_free (msg);
	}
	g_free (mailbox);

	return FALSE;
}

static void
begin_print (GtkPrintOperation *operation,
	     GtkPrintContext   *context,
	     gpointer           user_data)
{
	GyrusReportData *report;
	double height;

	report = (GyrusReportData *) user_data;

	height = gtk_print_context_get_height (context) - HEADER_HEIGHT - HEADER_GAP - TITLE_HEIGHT - TITLE_GAP;
	report->lines_per_page = floor (height / report->font_size);
	report->num_pages = (report->num_users - 1) / report->lines_per_page + 1;
	gtk_print_operation_set_n_pages (operation, report->num_pages);
}

static void
draw_page (GtkPrintOperation *operation,
	   GtkPrintContext   *context,
	   gint page_nr,
	   gpointer user_data)
{
	cairo_t *cr;
	PangoLayout *layout;
	gint text_width, text_height;
	gdouble width;
	gint line, i;
	PangoFontDescription *desc;
	gchar *page_str;
	GyrusReportData *report;
	GtkTreeModel *model;
	GtkTreeIter iter;

	report = (GyrusReportData *)user_data;

	cr = gtk_print_context_get_cairo_context (context);
	width = gtk_print_context_get_width (context);

	cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);

	cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
	cairo_fill_preserve (cr);

	cairo_set_source_rgb (cr, 0, 0, 0);
	cairo_set_line_width (cr, 1);
	cairo_stroke (cr);

	layout = gtk_print_context_create_pango_layout (context);

	desc = pango_font_description_from_string ("sans 14");
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);

	pango_layout_set_text (layout, report->title, -1);
	pango_layout_get_pixel_size (layout, &text_width, &text_height);

	if (text_width > width)	{
		pango_layout_set_width (layout, width);
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
		pango_layout_get_pixel_size (layout, &text_width, &text_height);
	}

	cairo_move_to (cr, (width - text_width) / 2,  (HEADER_HEIGHT - text_height) / 2);
	pango_cairo_show_layout (cr, layout);

	/* Translators: this represents the number of pages being printed. */
	page_str = g_strdup_printf (_("%d/%d"), page_nr + 1, report->num_pages);
	pango_layout_set_text (layout, page_str, -1);
	g_free (page_str);

	pango_layout_set_width (layout, -1);
	pango_layout_get_pixel_size (layout, &text_width, &text_height);
	cairo_move_to (cr, width - text_width - 4, (HEADER_HEIGHT - text_height) / 2);
	pango_cairo_show_layout (cr, layout);

	g_object_unref (layout);

	layout = gtk_print_context_create_pango_layout (context);

	desc = pango_font_description_from_string ("sans");
	pango_font_description_set_size (desc, report->font_size * PANGO_SCALE);
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);

	model = gtk_tree_view_get_model (report->treeview_report);

	pango_layout_get_pixel_size (layout, &text_width, &text_height);
	cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP + (TITLE_HEIGHT - text_height)/2);

	pango_layout_set_text (layout, _("User"), -1);
	pango_cairo_show_layout (cr, layout);
	cairo_rel_move_to (cr, 130, 0);

	pango_layout_set_text (layout, _("Quota (%)"), -1);
	pango_cairo_show_layout (cr, layout);
	cairo_rel_move_to (cr, 120, 0);

	pango_layout_set_text (layout, _("Assigned (KB)"), -1);
	pango_cairo_show_layout (cr, layout);
	cairo_rel_move_to (cr, 120, 0);

	pango_layout_set_text (layout, _("Used (KB)"), -1);
	pango_cairo_show_layout (cr, layout);

	g_object_unref (layout);

	cairo_set_source_rgb (cr, 0, 0, 0);
	cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP + TITLE_HEIGHT);
	cairo_rel_line_to (cr, width, 0);
	cairo_set_line_width (cr, 1);
	cairo_stroke (cr);

	layout = gtk_print_context_create_pango_layout (context);

	desc = pango_font_description_from_string ("sans");
	pango_font_description_set_size (desc, report->font_size * PANGO_SCALE);
	pango_layout_set_font_description (layout, desc);
	pango_font_description_free (desc);

	pango_layout_get_pixel_size (layout, &text_width, &text_height);
	cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP + TITLE_HEIGHT + TITLE_GAP);

	gtk_tree_model_get_iter_first (model, &iter);

	line = page_nr * report->lines_per_page;

	for (i = 0; i < report->lines_per_page && line < report->num_users; i++) {
		gint quota;
		gint assigned;
		gint used;
		gchar *str;
		gchar *mailbox;

		gtk_tree_model_get (model, &iter,
				    COLUMN_MAILBOX, &mailbox,
				    COLUMN_PERCENTAGE, &quota,
				    COLUMN_QUOTA_LIMIT, &assigned,
				    COLUMN_QUOTA_USED, &used,
				    -1);

		pango_layout_set_text (layout, mailbox, -1);
		pango_cairo_show_layout (cr, layout);
		cairo_rel_move_to (cr, 130, 0);
		g_free (mailbox);

		str = g_strdup_printf ("%d", quota);
		pango_layout_set_text (layout, str, -1);
		g_free (str);
		pango_cairo_show_layout (cr, layout);
		cairo_rel_move_to (cr, 120, 0);

		str = g_strdup_printf ("%d", assigned);
		pango_layout_set_text (layout, str, -1);
		g_free (str);
		pango_cairo_show_layout (cr, layout);
		cairo_rel_move_to (cr, 120, 0);

		str = g_strdup_printf ("%d", used);
		pango_layout_set_text (layout, str, -1);
		g_free (str);
		pango_cairo_show_layout (cr, layout);

		cairo_rel_move_to (cr, -370, report->font_size);
		line++;
		gtk_tree_model_iter_next (model, &iter);
	}

	g_object_unref (layout);
}

/* show print dialog */
static void
gyrus_report_on_button_print_clicked(GtkWidget *widget, GyrusReportData *report)
{
	GtkPrintOperation *operation;
	GtkWidget *window;
	GtkWidget *dialog;
	GError *error = NULL;

	/* Create the objects */
	operation = gtk_print_operation_new ();
	window = gtk_widget_get_toplevel (widget);
	report->font_size = 12.0;

	g_signal_connect (G_OBJECT (operation), "begin-print",
			  G_CALLBACK (begin_print), report);
	g_signal_connect (G_OBJECT (operation), "draw-page",
			  G_CALLBACK (draw_page), report);
	/* g_signal_connect (G_OBJECT (operation), "end-print", */
	/* 		  G_CALLBACK (end_print), report); */

	gtk_print_operation_set_use_full_page (operation, FALSE);
	gtk_print_operation_set_unit (operation, GTK_UNIT_POINTS);

	gtk_print_operation_run (operation,
				 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
				 GTK_WINDOW (window),
				 &error);
	if (error) {
		dialog = gtk_message_dialog_new (GTK_WINDOW (window),
						 GTK_DIALOG_DESTROY_WITH_PARENT,
						 GTK_MESSAGE_ERROR,
						 GTK_BUTTONS_CLOSE,
						 "%s", error->message);
		g_error_free (error);

		gtk_dialog_run (GTK_DIALOG (dialog));
		gtk_widget_destroy (dialog);
	}
}
