/*
 * grn_attach.c - attaching a file
 *
 *
 * $Id: grn_attach.c,v 1.2 2000/07/19 06:26:21 sc Exp $
 */
/* Copyright (C) 1999-2000  Sergey Chernikov (sc@ivvs.ul.ru)
 *
 * Authors: Sergey Chernikov <sc@ivvs.ul.ru>
 *
 * 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 "grn_consts.h"
#include "mutt.h"
#include "mime.h"
#include "grn_types.h"
#include "grn_attach.h"
#include "grn_mime.h"
#include "grn_util.h"
#include "grn_config.h"


static void mtype2body(const gchar *mtype, BODY *b)
{
  gchar **arr = g_strsplit(mtype, "/", 2);
  if (str_check(arr[0]))
  {
    if (! g_strcasecmp(arr[0], "audio"))  b->type = TYPEAUDIO;
    else if (! g_strcasecmp(arr[0], "application"))  b->type = TYPEAPPLICATION;
    else if (! g_strcasecmp(arr[0], "image"))  b->type = TYPEIMAGE;
    else if (! g_strcasecmp(arr[0], "message"))  b->type = TYPEMESSAGE;
    else if (! g_strcasecmp(arr[0], "model"))  b->type = TYPEMODEL;
    else if (! g_strcasecmp(arr[0], "multipart"))  b->type = TYPEMULTIPART;
    else if (! g_strcasecmp(arr[0], "text"))  b->type = TYPETEXT;
    else if (! g_strcasecmp(arr[0], "video"))  b->type = TYPEVIDEO;
    else {
      b->type = TYPEOTHER;
      b->xtype = g_strdup(arr[0]);
    }
  }
  b->subtype = str_copy(arr[1]);
  if (arr)  g_strfreev(arr);
}


static void aw_list_refresh(GtkCList *clist, t_message *m)
{
  GSList *l;

  gtk_clist_freeze(clist);
  gtk_clist_clear(clist);
  for (l=m->attachments; l; l=l->next)
  {
    BODY *b = (BODY *) l->data;
    gchar *row[3];
    gint idx;

    if (! b)  continue;
    row[0] = str_copy(b->filename);
    row[1] = body_mtype(b);
    row[2] = menc2str(b);
    idx = gtk_clist_append(clist, row);
    gtk_clist_set_row_data(clist, idx, b);
    for (idx=0; idx<3; idx++)  str_free(&row[idx]); 
  }
  gtk_clist_columns_autosize(clist);
  gtk_clist_thaw(clist);
}

static void aw_sel(GtkCList *clist, gint row, gint col, GdkEventButton *ev,
                   GtkWidget *box)
{
  GtkWidget *btn_del = gtk_object_get_data(GTK_OBJECT(box), KEY_BTN_DEL);

  if (btn_del)  gtk_widget_set_sensitive(btn_del, TRUE);
  if (! clist->selection)  gtk_widget_set_sensitive(btn_del, FALSE);
}

static void aw_fs_ok(GtkWidget *btn, GtkFileSelection *fs)
{
  gchar *fn = gtk_file_selection_get_filename(fs);
  GtkWidget *box = gtk_object_get_data(GTK_OBJECT(fs), KEY_WND);
  GtkCList *clist = gtk_object_get_data(GTK_OBJECT(box), KEY_CLIST);
  t_message *m = gtk_object_get_data(GTK_OBJECT(box), KEY_MSG);

  if (str_check(fn) && box && clist && m)
  {
    BODY *b = mutt_make_file_attach(fn);
    mtype2body(gnome_mime_type_of_file(fn), b);
    m->attachments = g_slist_append(m->attachments, b);
    aw_list_refresh(clist, m);
  }
  gtk_widget_destroy(GTK_WIDGET(fs));
}
static void aw_fs_cancel(GtkWidget *btn, GtkFileSelection *fs)
{
  gtk_widget_destroy(GTK_WIDGET(fs));
}
static void aw_add(GtkWidget *w, GtkWidget *box)
{
  GtkFileSelection *fs;
  
  fs = GTK_FILE_SELECTION(gtk_file_selection_new(_("Attach file")));
  gtk_object_set_data(GTK_OBJECT(fs), KEY_WND, box);
  gtk_signal_connect(GTK_OBJECT(fs->ok_button), "clicked",
		     GTK_SIGNAL_FUNC(aw_fs_ok), fs);
  gtk_signal_connect(GTK_OBJECT(fs->cancel_button), "clicked",
		     GTK_SIGNAL_FUNC(aw_fs_cancel), fs);
  gtk_widget_show(GTK_WIDGET(fs));
}

static void aw_del(GtkWidget *w, GtkWidget *box)
{
  GtkWidget *btn_del = gtk_object_get_data(GTK_OBJECT(box), KEY_BTN_DEL);
  GtkCList *clist = gtk_object_get_data(GTK_OBJECT(box), KEY_CLIST);
  t_message *m = gtk_object_get_data(GTK_OBJECT(box), KEY_MSG);
  GList *l;

  if ((! clist) || (! m))  return;
  if (btn_del)  gtk_widget_set_sensitive(btn_del, FALSE);

  for (l=clist->selection; l; l=l->next)
  {
    gint row = GPOINTER_TO_INT(l->data);
    BODY *b = gtk_clist_get_row_data(clist, row);
    if (! b)  continue;

    m->attachments = g_slist_remove(m->attachments, b);
    mutt_free_body(&b);
  }
  aw_list_refresh(clist, m);
}

static GtkWidget *aw_create(void)
{
  gchar *ttl[3] = {_("File name"), _("Type"), _("Encoding")};
  GtkWidget *box, *scrwin, *bbox, *btn;
  GtkCList *clist;
  
  box = gtk_hbox_new(FALSE, FALSE);
  clist = GTK_CLIST(gtk_clist_new_with_titles(3, ttl));
  gtk_widget_set_usize(GTK_WIDGET(clist), 300, 200);
  gtk_clist_column_titles_passive(clist);
  gtk_clist_set_selection_mode(clist, GTK_SELECTION_EXTENDED);
  gtk_signal_connect(GTK_OBJECT(clist), "select_row",
                     GTK_SIGNAL_FUNC(aw_sel), box);
  
  scrwin = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_container_add(GTK_CONTAINER(scrwin), GTK_WIDGET(clist));
  gtk_box_pack_start(GTK_BOX(box), scrwin, TRUE, TRUE, 0);
  gtk_object_set_data(GTK_OBJECT(box), KEY_CLIST, clist);
  
  bbox = gtk_vbutton_box_new();
  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), gnome_preferences_get_button_layout());
  gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), GNOME_PAD);
  gtk_box_pack_start(GTK_BOX(box), bbox, FALSE, FALSE, 2);
  
  btn = gnome_pixmap_button(gnome_stock_pixmap_widget(NULL, GNOME_STOCK_PIXMAP_ADD),
                            _("Add..."));
  gtk_box_pack_start(GTK_BOX(bbox), btn, TRUE, TRUE, 0);
  gtk_signal_connect(GTK_OBJECT(btn), "clicked",
		     GTK_SIGNAL_FUNC(aw_add), box);
  
  btn = gnome_pixmap_button(gnome_stock_pixmap_widget(NULL, GNOME_STOCK_PIXMAP_REMOVE),
                            _("Delete"));
  gtk_box_pack_start(GTK_BOX(bbox), btn, TRUE, TRUE, 0);
  gtk_widget_set_sensitive(btn, FALSE);
  gtk_signal_connect(GTK_OBJECT(btn), "clicked",
		     GTK_SIGNAL_FUNC(aw_del), box);
  gtk_object_set_data(GTK_OBJECT(box), KEY_BTN_DEL, btn);
  
  return box;
}

static void aw_set_data(GtkWidget *aw, t_message *m)
{
  GtkCList *clist;
  g_return_if_fail(m != NULL);
  
  gtk_object_set_data(GTK_OBJECT(aw), KEY_MSG, m);
  clist = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(aw), KEY_CLIST));
  if (! clist)  return;

  aw_list_refresh(clist, m);
}


static gboolean adlg_delete(GtkWidget *w)
{
  grn_save_ws(8, w);
  return FALSE;
}
static void adlg_btn_event(GtkWidget *btn, GtkWidget *w)
{
  grn_save_ws(8, w);
}
GtkWidget *dlg_attachments(t_message *m)
{
  GtkWidget *dlg, *aw;
  
  dlg = gnome_dialog_new(_("Attachments"), GNOME_STOCK_BUTTON_CLOSE, NULL);
  gnome_dialog_set_close(GNOME_DIALOG(dlg), TRUE);
  gtk_window_set_policy(GTK_WINDOW(dlg), FALSE, TRUE, FALSE);
  gtk_window_set_default_size(GTK_WINDOW(dlg), grn_prefs.ws[8].width, grn_prefs.ws[8].height);
  gtk_widget_set_uposition(dlg, grn_prefs.ws[8].x, grn_prefs.ws[8].y);
  gtk_signal_connect(GTK_OBJECT(dlg), "delete_event",
		     GTK_SIGNAL_FUNC(adlg_delete), NULL);
  gnome_dialog_button_connect(GNOME_DIALOG(dlg), 0,
			      GTK_SIGNAL_FUNC(adlg_btn_event), dlg);
  
  aw = aw_create();
  aw_set_data(aw, m);
  gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dlg)->vbox), aw, TRUE, TRUE, 0);
  gtk_widget_show_all(dlg);
  return dlg;
}

typedef struct att_data
{
  GtkWidget **dlg;
  GtkWidget *btn;
} att_data;

static void adlg_destroy(GtkWidget *w, att_data *ad)
{
  *(ad->dlg) = NULL;
  gtk_widget_set_sensitive(ad->btn, TRUE);
  g_free(ad);
}
void evt_attachments(GtkWidget *w)
{
  GtkWidget *mpw;
  t_message *m;
  static GtkWidget *dlg;
  att_data *ad;
  if (! w->parent)  return;
  if (dlg)  return;
  
  mpw = gtk_object_get_data(GTK_OBJECT(w->parent), KEY_MSGPOST);
  if (! mpw)  mpw = gtk_object_get_data(GTK_OBJECT(w), KEY_MSGPOST);
  if (! mpw)  return;
  m = gtk_object_get_data(GTK_OBJECT(mpw), KEY_MSG);
  if (! m)  return;

  dlg = dlg_attachments(m);
  gtk_widget_set_sensitive(w, FALSE);
  ad = g_new(att_data, 1);
  ad->dlg = &dlg;  ad->btn = w;
  gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
		     GTK_SIGNAL_FUNC(adlg_destroy), ad);
}


syntax highlighted by Code2HTML, v. 0.9.1