/* dvdrwformat.c
 * Copyright (C) 2005 Sylvain Cresto <scresto@gmail.com>
 *
 * This file is part of graveman!
 *
 * graveman! 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.
 * 
 * graveman! 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 program; see the file COPYING. If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA. 
 * 
 * URL: http://www.nongnu.org/graveman/
 *
 */

#include "graveman.h"

/* communication avec dvd+rw-format */

#define DVDRWFORMAT_MEDIA_ALREADYFORMAT "media is already formatted"
#define DVDRWFORMAT_MEDIA_BAD           "mounted media doesn't appear to be DVD"
#define DVDRWFORMAT_ILLEGAL_COMMAND     "illegal command-line option for this media"
#define DVDRWFORMAT_RESOURCE_UNAVAILABLE "Resource temporarily unavailable"

#define DVDRWFORMAT_FORMATTING          "formatting"
#define DVDRWFORMAT_BLANKING            "blanking"

/* callback formatage d'un dvd */
gboolean dvdrwformat_callback(GIOChannel *Astd, GIOCondition Acond, gpointer Adata)
{
  GIOStatus Lstatus;
  Tgrave *Lg = (Tgrave *)Adata;
  gint *Lcont = (gint *)sc_grave_get_data(Lg, "cont");
  GError **Lerreur = (GError **) sc_grave_get_data(Lg, "gerror"); /* pointeur erreur */
  GtkProgressBar *Lprogressbar = GTK_PROGRESS_BAR(sc_grave_get_data(Lg, "progress"));
  gchar *Lbuffer;
  gchar *s, *p;
  gdouble Lpct;
  gchar Lsbuf[100];

  if (Acond == G_IO_HUP || Acond == G_IO_ERR) {
    *Lcont = 1;
    return FALSE;
  }

  Lstatus = g_io_channel_read_line(Astd, &Lbuffer, NULL, NULL, NULL);  
  if (!Lbuffer) {
    return TRUE;
  }

  _DEB("===>%s", Lbuffer);

  if (strstr(Lbuffer, DVDRWFORMAT_MEDIA_ALREADYFORMAT)) {
    /* erreur media deja formate */
    g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_ALREADY_FORMAT, _("Media is already formatted!"));
    (*Lcont) = 1;
    return FALSE;
  } else if (strstr(Lbuffer, DVDRWFORMAT_MEDIA_BAD)) {
    (*Lcont) = 1;
    g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("Mounted media doesn't appear to be DVD+/-RW."));
    return FALSE;
  } else if (strstr(Lbuffer, DVDRWFORMAT_ILLEGAL_COMMAND)) {
    (*Lcont) = 1;
    g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("Illegal format for this media."));
    return FALSE;
  } else if (strstr(Lbuffer, DVDRWFORMAT_RESOURCE_UNAVAILABLE)) {
    (*Lcont) = 1;
    g_set_error(Lerreur, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA, _("Resource temporarily unavailable."));
    return FALSE;
  } else if ((p=strstr(Lbuffer, DVDRWFORMAT_FORMATTING)) || (p=strstr(Lbuffer, DVDRWFORMAT_BLANKING))) {
    if ((s=(strchr(p, '%')))) {
      *(s--)=0;
      while (isdigit(*s) || *s=='.') s--;

      _DEB("test => %s\n", s); 

      Lpct = 0.01 * atof(s);
      gtk_progress_bar_set_fraction(Lprogressbar, Lpct);
      g_snprintf(Lsbuf, sizeof(Lsbuf)-1, "%s%%", s);
      gtk_progress_bar_set_text(Lprogressbar, Lsbuf);
    }
  }

  g_free(Lbuffer);
  return TRUE;
}
  
/* effacer un dvd */
gboolean perform_format_dvd(Tgrave *Ag, Ttypeformatdvd Aoperation, GError **Aerror)
{
  gchar **Lcmd;
  gchar *Lcommandline;
  gchar *Lmode;
  gboolean Lstatus = FALSE;
  GIOChannel *Lcom, *Lcomerr;
  guint Lcomevent, Lcomerrevent;
  gint g_out, g_err, Lnbrarg;
  gint *Lcont = sc_grave_get_data(Ag, "cont");
  gint *Lpid = (gint *) sc_grave_get_data(Ag, "pid");
  gboolean *Labort = (gboolean *)sc_grave_get_data(Ag, "gabort");
  Tdriveinfo *Ldevice = matos_get_drive_info(Ag, "dstothercombo");

  if (Aoperation == DVD_FORMAT) {
    Lmode = "";
  } else if (Aoperation == DVD_BLANK) {
    Lmode = "-blank";
  } else {
    Lmode = "-blank=full";
  }
  
/*  if (!Ldriv) {
    g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_CONFIGURATION, _("Error you must manually add this drive in 'properties dialog' box."));

    return FALSE;
  }*/

  Lcommandline = g_strdup_printf("%s -gui %s %s",
      conf_get_string("dvd+rw-format"), Lmode, matos_get_device(Ldevice)); 
  _DEB("execution [%s]\n", Lcommandline);
  Lstatus = g_shell_parse_argv(Lcommandline, &Lnbrarg, &Lcmd, Aerror);
  g_free(Lcommandline);

  if (Lstatus == FALSE) {
    return FALSE;
  }

  /* try to umount device before device access */
  matos_umount_device(Ldevice, NULL);

  Lstatus = g_spawn_async_with_pipes(NULL, Lcmd, NULL, /* env argument */
      (GSpawnFlags ) (G_SPAWN_DO_NOT_REAP_CHILD),
       NULL, NULL, Lpid, NULL, &g_out, &g_err, Aerror);
  g_strfreev(Lcmd);
  if (Lstatus == FALSE) {
    return FALSE;
  }

  Lcom = g_io_channel_unix_new( g_out );
  g_io_channel_set_encoding (Lcom, NULL, NULL);
  g_io_channel_set_flags( Lcom, G_IO_FLAG_NONBLOCK, NULL );
  Lcomevent = g_io_add_watch (Lcom, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI),
                                      dvdrwformat_callback, Ag);
  
  Lcomerr = g_io_channel_unix_new( g_err );
  g_io_channel_set_encoding (Lcomerr, NULL, NULL);
  g_io_channel_set_flags( Lcomerr, G_IO_FLAG_NONBLOCK, NULL );
  Lcomerrevent = g_io_add_watch (Lcomerr, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI),
                                      dvdrwformat_callback, Ag);  

  while (*Lcont > 1 && *Labort == FALSE) {
    gtk_main_iteration(); 
  }

  if (*Labort == TRUE && *Lpid) {
    kill(*Lpid, SIGINT);
  }

  exit_prog(*Lpid, *Labort, Aerror, NULL);

  g_source_remove(Lcomerrevent);
  g_source_remove(Lcomevent);

  g_io_channel_shutdown(Lcomerr, FALSE, NULL);
  g_io_channel_unref(Lcomerr);  
  g_io_channel_shutdown(Lcom, FALSE, NULL);
  g_io_channel_unref(Lcom);
  g_spawn_close_pid(*Lpid);
  *Lpid = 0;

  return *Aerror ? FALSE : TRUE;
}

/*
 * vim:et:ts=8:sts=2:sw=2
 */
