/* This is -*- C -*- */
/* $Id: guppi-data-importer-plug-in.c,v 1.14 2001/10/10 06:48:08 trow Exp $ */

/*
 * guppi-data-importer-plug-in.c
 *
 * Copyright (C) 2000 EMC Capital Management, Inc.
 *
 * Developed by Jon Trowbridge <trow@gnu.org> and
 * Havoc Pennington <hp@pobox.com>.
 *
 * 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 <config.h>
#include "guppi-data-importer-plug-in.h"

/* #include <gnome.h> */
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-util.h>

#include <guppi-plug-in-spec.h>
#include <guppi-memory.h>

static GtkObjectClass *parent_class = NULL;

static void
guppi_data_importer_plug_in_finalize (GtkObject * obj)
{
  if (parent_class->finalize)
    parent_class->finalize (obj);
}

static void
guppi_data_importer_plug_in_class_init (GuppiDataImporterPlugInClass * klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *) klass;

  parent_class = gtk_type_class (GUPPI_TYPE_PLUG_IN);

  object_class->finalize = guppi_data_importer_plug_in_finalize;
}

static void
guppi_data_importer_plug_in_init (GuppiDataImporterPlugIn * obj)
{

}

GtkType guppi_data_importer_plug_in_get_type (void)
{
  static GtkType guppi_data_importer_plug_in_type = 0;
  if (!guppi_data_importer_plug_in_type) {
    static const GtkTypeInfo guppi_data_importer_plug_in_info = {
      "GuppiDataImporterPlugIn",
      sizeof (GuppiDataImporterPlugIn),
      sizeof (GuppiDataImporterPlugInClass),
      (GtkClassInitFunc) guppi_data_importer_plug_in_class_init,
      (GtkObjectInitFunc) guppi_data_importer_plug_in_init,
      NULL, NULL, (GtkClassInitFunc) NULL
    };
    guppi_data_importer_plug_in_type =
      gtk_type_unique (GUPPI_TYPE_PLUG_IN, &guppi_data_importer_plug_in_info);
  }
  return guppi_data_importer_plug_in_type;
}

GuppiPlugIn *
guppi_data_importer_plug_in_new (void)
{
  return
    GUPPI_PLUG_IN (guppi_type_new (guppi_data_importer_plug_in_get_type ()));
}

void
guppi_data_importer_plug_in_add_accepted_extension (GuppiDataImporterPlugIn *
						    p, const gchar * ext)
{
  p->accepted_extensions = g_slist_prepend (p->accepted_extensions,
					    guppi_strdup (ext));
}

void
guppi_data_importer_plug_in_add_accepted_extensions (GuppiDataImporterPlugIn *
						     p, const gchar * ext[])
{
  gint i = 0;
  while (ext[i]) {
    p->accepted_extensions = g_slist_prepend (p->accepted_extensions,
					      guppi_strdup (ext[i]));
    ++i;
  }
}

void
guppi_data_importer_plug_in_add_rejected_extension (GuppiDataImporterPlugIn *
						    p, const gchar * ext)
{
  p->accepted_extensions = g_slist_prepend (p->rejected_extensions,
					    guppi_strdup (ext));
}

void
guppi_data_importer_plug_in_add_rejected_extensions (GuppiDataImporterPlugIn *
						     p, const gchar * ext[])
{
  gint i = 0;
  while (ext[i]) {
    p->accepted_extensions = g_slist_prepend (p->rejected_extensions,
					      guppi_strdup (ext[i]));
    ++i;
  }
}

/***************************************************************************/

struct assess_hack {
  const gchar *filename;
  gpointer data;
  gsize size;
  GList *list;
};

/* Extensions that we usually associated with binary files.  Text-based
   importers will probably want to reject these. */
static const gchar *bin_extensions[] = {
  "jpg", "jpeg", "png", "gif", "bmp", "ppm", "pbm", "pgm", "xcf",
  "dvi", "o", "a", "la", "so", "pdf", "rpm", "deb", "tar",
  "au", "wav", "mp3",
  "exe", "com",
  NULL
};

static void
assess_iter (GuppiPlugInSpec * spec, gpointer user_data)
{
  struct assess_hack *ah = (struct assess_hack *) user_data;
  GuppiPlugIn *pi;
  GuppiDataImporterPlugIn *dipi;
  double c, conf = 2;		/* this is, of course, an illegal value */
  GuppiDataImporterAssessment *gdia;
  const gchar *ext;
  GSList *iter;
  gboolean checking_ext;
  gint i;

  g_return_if_fail (GUPPI_IS_PLUG_IN_SPEC (spec));

  pi = guppi_plug_in_spec_plug_in (spec);
  dipi = GUPPI_DATA_IMPORTER_PLUG_IN (pi);

  if (! dipi->imports_files)
    return;

  /* Check our lists of allowed and forbidden extensions. */
  if (ah->filename && (ext = g_extension_pointer (ah->filename))) {
    checking_ext = TRUE;
    iter = dipi->accepted_extensions;
    while (iter) {
      if (g_strcasecmp (ext, (gchar *) iter->data) == 0) {
	conf = MIN (conf, 1);
	iter = NULL;
	checking_ext = FALSE;
      } else {
	iter = g_slist_next (iter);
      }
    }

    if (dipi->reject_if_not_accepted && conf > 1)
      conf = 0;

    if (conf > 0 && dipi->reject_binary_extensions) {
      for (i = 0; conf > 0 && bin_extensions[i] != NULL; ++i) {
	if (g_strcasecmp (ext, bin_extensions[i]) == 0) {
	  conf = 0;
	}
      }
    }

    iter = dipi->rejected_extensions;
    while (conf > 0 && iter && checking_ext) {
      if (g_strcasecmp (ext, (gchar *) iter->data) == 0) {
	conf = 0;
	iter = NULL;
      } else {
	iter = g_slist_next (iter);
      }
    }
  }

  if (conf > 0 && dipi->assess_by_filename && ah->filename) {
    c = (dipi->assess_by_filename) (ah->filename);
    conf = MIN (conf, c);
  }

  if (conf > 0 && dipi->assess_by_peek && ah->data && ah->size > 0) {
    c = (dipi->assess_by_peek) (ah->data, ah->size);
    conf = MIN (conf, c);
  }

  if (conf > 1)
    conf = 0.5;

  if (conf > 0) {
    gdia = guppi_new (GuppiDataImporterAssessment, 1);
    gdia->confidence = CLAMP (conf, 0, 1);
    gdia->spec = spec;
    gdia->plug_in = dipi;
    ah->list = g_list_prepend (ah->list, gdia);
  }
}

static gint
assess_comp_func (gconstpointer a, gconstpointer b)
{
  GuppiDataImporterAssessment *aa = (GuppiDataImporterAssessment *) a;
  GuppiDataImporterAssessment *bb = (GuppiDataImporterAssessment *) b;

  return (aa->confidence < bb->confidence) - (aa->confidence >
					      bb->confidence);
}

GList *
guppi_data_importer_plug_in_assess (const gchar * filename,
				    gpointer data, gsize size)
{
  struct assess_hack ah;
  ah.filename = filename;
  ah.data = data;
  ah.size = size;
  ah.list = NULL;

  guppi_plug_in_spec_foreach_of_type ("data_import", assess_iter, &ah);
  return g_list_sort (ah.list, assess_comp_func);
}



/* $Id: guppi-data-importer-plug-in.c,v 1.14 2001/10/10 06:48:08 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1