/*
 * GkDebconf -- Help to configure packages with debconf
 * Copyleft (C) 2003 Agney Lopes Roth Ferraz <agney@users.sourceforge.net>
 *
 * 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 <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>

#include <gtk/gtk.h>

#include "../config.h"

#include "defines.h"
#include "debconf.h"
#include "interface.h"
#include "files.h"
#include "config.h"

#define TERMCMD "/usr/bin/x-terminal-emulator"
#define GKTERM "/bin/gkdebconf-term"
#define DEBCONFCMD "/usr/sbin/dpkg-reconfigure"
#define GKSU "/usr/bin/gksu"

extern GtkWidget *main_window;
extern GtkWidget *splash_label;
extern gint errno;


/* stores information about available front ends */
// Web frontend can work if any of web browsers is installed (www-browser virtual package)

dfrontend dfes[] = {{"gnome", FALSE, "libgnome2-perl", NULL},
			{"kde", FALSE, "libqt-perl", NULL}, 
		    {"dialog", TRUE, "dialog", "whiptail"}, 
		    {"readline", TRUE, "libterm-readline-gnu-perl", "libreadline4"},
		    {"editor", TRUE, NULL, NULL},
		    {"web", FALSE, NULL, NULL}, // virtual package "www-browser"
		    {NULL, FALSE}};

gchar *frontend;

			
/**
 * file_exists:
 *
 * @file: filename to check.
 *
 * Check if the file exits on the system.
 * 
 * Returns 0 if file exits. Anything else otherwise.
 */
			
int inline file_exists(char *file) 
			{ 
				struct stat st; 
					return stat(file, &st); 
			}

/**
 * check_missing:
 *
 * @fe: Frontend name.
 *
 * Check if the package is installed on the system.
 * 
	* Returns 0 if package is installed. Anything else otherwise.
 */
			
int check_missing (gchar *fe)
{
  char *file = NULL;
  gchar *msg;
  gint i;
  gint ret ;


  for (i = 0 ; strcmp (dfes[i].name, fe) ; i++);

  if (dfes[i].dep1 == NULL)
    return 0;

  msg = g_strdup_printf (_("Checking whether\n%s\nis installed"),
			 dfes[i].dep1);
  gtk_label_set_text (GTK_LABEL(splash_label), msg);
  while (gtk_events_pending())
    gtk_main_iteration(); 
  g_free (msg);
  file = g_strdup_printf ("/var/lib/dpkg/info/%s.list", dfes[i].dep1);
  ret = file_exists(file);
  if ( (ret != 0) && (dfes[i].dep2 != NULL) )
	{
	 msg = g_strdup_printf (_("Checking whether\n%s\nis installed"),
	                          dfes[i].dep2);
	 gtk_label_set_text (GTK_LABEL(splash_label), msg);
	 while (gtk_events_pending())
        	 gtk_main_iteration();
         g_free (msg);
  file = g_strdup_printf ("/var/lib/dpkg/info/%s.list", dfes[i].dep2);
  ret = file_exists(file);
	}
  g_free (file);
  return ret;
}


/**
 * get_frontends:
 *
 * @menu: Widget that contains menubar where frontends will be added.
 *
 *  Fills the Options menu with the available frontends
 */

void
get_frontends (GtkWidget *menu)
{
  GSList *group = NULL;
  GtkWidget *item;
  GtkTooltips *tooltips;
  gchar *message;
  GtkItemFactory *item_factory = gtk_item_factory_from_widget (menu);
  gchar *fe, *remember_fe, *str_item, *libgnome_alert;
  gint i;
	
	
  frontend = NULL;
  gboolean missing_active = FALSE;

  remember_fe = read_config ("remember_frontend"); 
  if (!strcmp (remember_fe, "yes"))
    {
      fe = read_config ("last_frontend");
      if (strcmp (fe, "none"))
		frontend = g_ascii_strdown (fe, -1);
	  g_free(fe);
    }

   /* first item is set active automaticaly
  * if no other item made active
 */

  if (!frontend)
	  frontend = g_ascii_strdown (dfes[0].name, -1);
		
  g_free (remember_fe);
  tooltips = gtk_tooltips_new ();
  for (i = 0 ; dfes[i].name != NULL ; i++)
    {
      str_item = g_strconcat(dfes[i].name, _(" frontend"), NULL);
      item = gtk_radio_menu_item_new_with_label (group, str_item);
      group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
      gtk_widget_show (item);
      gtk_container_add (GTK_CONTAINER (gtk_item_factory_get_widget (item_factory,
                                            _("/Options"))), item);
      gtk_tooltips_set_tip (tooltips, item, g_strconcat( _("Select "), str_item, NULL),
    					     NULL);
      g_free(str_item);
  
      if (check_missing(dfes[i].name) == 0){
	  g_signal_connect ((gpointer) item, "activate",
                    G_CALLBACK (fe_select), (gpointer) g_strdup(dfes[i].name));	

	  if (!strcmp(dfes[i].name, frontend) || missing_active){
	    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
	    missing_active = FALSE;
	  }
	}
      else
       {
	if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))) 
	    missing_active = TRUE;

/* If gnome or kde frontend not found displays warning, because 
   gkdebconf is graphical and should be used with a graphical frontend
*/
    libgnome_alert = read_config ("libgnome_alert");
    if ((g_ascii_strcasecmp(dfes[i].name, "gnome") == 0) && (strcmp(libgnome_alert,"no") != 0)){
      message = g_strdup_printf (_("You should install '%s' package if you need\nuser-friendly configuration tool."), 
						dfes[i].dep1);
      gk_dialog_for_gconf ("libgnome_alert",message);		
			
 	}
	gtk_widget_set_state(item,GTK_STATE_INSENSITIVE);
       }
    }
}

/**
 * get_frontends:
 *
 * @entry: GTK_ENTRY where frontend is.
 * @user_data: The frontend name.
 *
 *  Mostly a callback to the frontend selection menu items
 */

void
fe_select (GtkMenuItem *entry, gpointer user_data)
{
 
  strcpy (frontend, user_data);
  write_config ("last_frontend", frontend);
	
}

/**
 * run_config:
 *
 * @cf: Package name to reconfigure.
 *
 *  Run dpk-reconfigure.
 */

int
run_config (gchar *cf)
{
  gushort need_term = FALSE;
  gushort gk_ask_for_root = FALSE;
  gchar *call_command = NULL;
  gint i, cmdret;
  /*
    hides the main window immediately
 */

  gtk_widget_hide (main_window);

  while (gtk_events_pending())
    gtk_main_iteration();

  for (i = 0 ; strcmp(frontend, dfes[i].name) ; i++);
  need_term = dfes[i].need_term;
  
  if (getuid() != 0)
    gk_ask_for_root = TRUE;
  
  if (need_term == TRUE)
    {
      gchar gkterm[256];
      
      strcpy (gkterm, PREFIX);
      strcat (gkterm, GKTERM);
      
      call_command = g_strdup_printf ("%s -e %s %s %s",
				      TERMCMD, gkterm,
				      frontend, cf);
    }
  else
    {
      if (gk_ask_for_root)
	call_command = g_strdup_printf ("%s -u root '%s -f%s %s'",
					GKSU, DEBCONFCMD, frontend,
					cf);
      else
	call_command = g_strdup_printf ("%s -f%s %s",
					DEBCONFCMD, frontend,
					cf);
    }

  cmdret = system (call_command);

  gtk_widget_show (main_window);

  if (cmdret != 0)
    {
      gk_dialog (GTK_MESSAGE_ERROR,
		 _("The configuration script returned an\n"
		   "error status."));
    }

  if (call_command)
    g_free (call_command);

  return 0;
}
