/* Bluefish HTML Editor
 * bluefish.c - main source file
 *
 * Copyright (C) 1998 Olivier Sessink and Chris Mazuc
 *
 * 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 <stdlib.h>
#include "config.h"  /* must be before the gdk_imlib !!!!! */

#if HAVE_LIBGDK_IMLIB
#include <gdk_imlib.h>
#endif

#include <gtk/gtk.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "bluefish.h"
#include "interface.h"
#include "callbacks.h"

void
cya_later (GtkWidget * widget, gpointer data)
{
  gchar *projectfilename, *lockfilename;

  if (current_project.filename != NULL)
    {
      projectfilename = current_project.filename;
      g_free (current_project.filename);
      current_project.filename = g_malloc (1024);
      strncat (strcpy (current_project.filename,
		       (char *) getenv ("HOME")),
	       "/.bluefish/projects/default", 1023);
      project_to_file ();
      current_project.filename = projectfilename;
    }
  file_close_all (NULL, "make_me_non_null");

  if (g_list_length (documentlist) > 1)
    {
#ifdef DEBUG
      g_print ("cya_later, not all documents are closed\n");
#endif
    }
  else
    {
      /* clean up the lock file */
      lockfilename = g_malloc (1024);
      strncat (strcpy (lockfilename, getenv ("HOME")), "/.bluefish/lock", 1023);
      remove (lockfilename);
      g_free (lockfilename);

      gtk_main_quit ();
    }
}

int
main (gint argc, gchar * argv[])
{

  /* see if we're running as root, if so, exit with an error */
  if (geteuid () == 0)
    {
      g_print ("Error: cannot run as root (for security reasons)\n");
      /* effective uid == 0 and the real uid != 0 means it's suid root */
      /* give an additional message if this is the case */
      if (getuid () != 0)
	{
	  g_print ("Please contact your system administrator\n");
	}
      exit (EXIT_FAILURE);
    }

  /* for international language support */
  gtk_set_locale ();

  gdk_init (&argc, &argv);

#if HAVE_LIBGDK_IMLIB
  /* Immediately after initialising GDK, Initialise Imlib */
  gdk_imlib_init ();
#endif

  /* create the window widget and start gtk */
  gtk_init (&argc, &argv);

  /* display a splash screen with progress bar
   * also creates the main window, reads the config, 
   * checks directories etc... 
   */
  startup ();
#ifdef DEBUG
  g_print ("main, startup() finished, going into gtk_main()\n");
#endif

  gtk_main ();

  exit (0);
}


void
change_dir (gchar * filename)
{
/* you can call this function with a filename, it will search for 
 * the last occurence of a / and try to change the current path to
 * that directory
 */
  gchar *tmpstring;
  gint returncode;
  gchar *tmp;			/* temporary pointer */

  tmpstring = g_malloc0 (strlen (filename) + 1);
  strcpy (tmpstring, filename);
#ifdef DEBUG
  g_print ("change_dir, 1 tmpstring = %s in %p\n", tmpstring, tmpstring);
#endif
  tmp = strrchr (tmpstring, '/');
  if (tmp == NULL)
    {
      return;
    }
  strcpy (tmp, "\0");
#ifdef DEBUG
  g_print ("change_dir, 2 tmpstring=%s in %p\n", tmpstring, tmpstring);
#endif
  returncode = chdir (tmpstring);
#ifdef DEBUG
  g_print
    ("change_dir, chdir returncode = %d (0=success), tmpstring in %p\n",
     returncode, tmpstring);
#endif
  g_free (tmpstring);
#ifdef DEBUG
  g_print ("change_dir, after gfree(tmpstring) \n");
#endif
}

/* Strips away the leading path... Should maybe be optional? */
char *
strip_filename (gchar * string)
{
  gint i, j;
  gchar *new_string;

  if (string[0] != '/')
    {
#ifdef DEBUG
      g_print ("%s\n", string);
#endif
      return string;
    }
  for (i = strlen (string) - 1; i >= 0; i--)
    {

      if (string[i] == '/')
	break;
    }
  if (i > 0)
    i++;
  new_string = g_malloc0 ((strlen (string) - i) + 1);
  for (j = 0; j <= (strlen (string) - i) - 1; j++)
    new_string[j] = string[i + j];

  return new_string;
}

/* this function is useful in changing absolute paths to relative paths */
gchar *
strip_common_path (char *image_fn, char *html_fn)
{
  gchar *tempstr;
  int count, count2, dir_length;

  count = 0;
  tempstr = strrchr (image_fn, '/');
  dir_length = strlen (image_fn) - strlen (tempstr);
  dir_length += 1;
#ifdef DEBUG
  g_print ("strip_common_path, dir_lenght=%d\n", dir_length);
#endif
  while ((strncmp (image_fn, html_fn, count + 1)) == 0)
    {
      count++;
      if (count > dir_length)
	{
	  count = dir_length;
	  break;
	}
    }
#ifdef DEBUG
  g_print ("strip_common_path, equal count = %d\n", count);
#endif
  count2 = strlen (image_fn);
  tempstr = g_malloc (count2 - count + 2);
  memcpy (tempstr, &image_fn[count], count2 - count + 2);
#ifdef DEBUG
  g_print ("strip_common_path, tempstr= %s, should be %d long\n",
	   tempstr, count2 - count);
#endif
  return tempstr;
  /* the function that calls this one must use gfree() somewhere!! */
}



void
window_close (GtkWidget * button, gpointer windowname)
{
  gtk_signal_handlers_destroy (GTK_OBJECT (windowname));
  gtk_grab_remove (windowname);
  gtk_widget_destroy (windowname);
}

gint
file_exists_and_readable (gchar * filename)
{
  struct stat naamstat;
  if (strlen (filename) < 2)
    return 0;
#ifdef DEBUG
  g_print
    ("file_exists_and_readable, filename=\"%s\", strlen(filename)=%d\n",
     filename, strlen (filename));
#endif
  if ((stat (filename, &naamstat) == -1) && (errno == ENOENT))
    {
/*              if(naamstat.st_mode & S_IREAD) { */
      return (0);
/*              }
   return(0); */
    }
  else
    {
      return (1);
    }
}


/* forces everything to be flushed */
void
flush_queue (void)
{
  while (gtk_events_pending ())
    {
      gtk_main_iteration ();
    }
  while (gdk_events_pending ())
    {
      gdk_flush ();
    }
}

/* designed for adding strings to colorlist, urllist, fontlist and targetlist */
void
add_to_list (GList * which_list, gchar * string)
{
  gchar *tempstr2, *tmp_pntr;
  gint count, add;

  tempstr2 = g_malloc (strlen (string) + 1);
  strcpy (tempstr2, string);
  count = g_list_length (which_list) - 1;
  add = 1;
#ifdef DEBUG
  g_print ("add_to_list, count=%d, list=%p\n", count, which_list);
#endif
  while (count > 0)
    {
      tmp_pntr = g_list_nth_data (which_list, count);
#ifdef DEBUG
      g_print ("add_to_list, count=%d, tempstr2=%s\n", count, tempstr2);
      g_print ("add_to_list, tmp_pntr=%s\n", tmp_pntr);
#endif
      if (strcmp (tmp_pntr, tempstr2) == 0)
	{
	  add = 0;
#ifdef DEBUG
	  g_print ("add_to_list, strings are the same, don't add!!\n");
#endif
	}
      count--;
    }
  if (add)
    {
#ifdef DEBUG
      g_print ("add_to_list, adding string=%s, listlenght=%d\n", string,
	       g_list_length (which_list));
#endif
      which_list = g_list_append (which_list, tempstr2);
    }
  else
    {
#ifdef DEBUG
      g_print ("add_to_list, string is already in there, freeing\n");
#endif
      g_free (tempstr2);
    }
}
