/*  SciGraphica - Scientific graphics and data manipulation
 *  Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <gtkextra/gtkextra.h>
#include "sg_project_autosave.h"
#include "sg_dialogs.h"
#include "sg.h"
#include "sg_project.h"


gboolean project_changed_since_last_autosave = FALSE;


static gchar autosave_filename[250] = "";
static gboolean autosave_locked = FALSE;

static gint autosave(gpointer data);
 

/* set new autosave timeout when interval (in minutes) > 0
 * otherwise disable timeout */ 
void sg_project_autosave_set( gint autosave_interval )
{
 static gint *timeout_tag = NULL;

 if ( autosave_interval > 0 )
    {if ( timeout_tag )
        gtk_timeout_remove( *timeout_tag ); /* remove previous timeout */
     else
        timeout_tag = g_new(gint, 1);

     /* set new timeout; gtk_timeout_add wants milliseconds */
     *timeout_tag = gtk_timeout_add(autosave_interval * 60 * 1000,
                                    (GtkFunction)autosave, NULL );
    }
 else
    {
     /* remove autosave timeout */
     if ( timeout_tag )
        {gtk_timeout_remove(*timeout_tag);
         g_free(timeout_tag);
         timeout_tag = NULL;
        }

     /* if locked, then wait till autosave() is done */
     while ( autosave_locked ) sleep(1);

     /* remove autosave file */
     if ( *autosave_filename ) remove(autosave_filename);
    }
}

/* autosave the current project if necessary
 * return TRUE/FALSE: continues/terminates subsequent autosave timeouts */
static
gint autosave( gpointer data )
{
 /* locked avoids simultaneous autosave invokations */
 if ( autosave_locked ) return TRUE;
 autosave_locked = TRUE;

 if ( project_changed == FALSE )
    {
     /* only remove previous autosave file; no save needed, nothing has changed */
     if (*autosave_filename) remove(autosave_filename);
     *autosave_filename = '\0';
    }
 else if ( project_changed_since_last_autosave )
    {
     /* autosave the current project */
     if ( *autosave_filename ) remove(autosave_filename);
     g_snprintf(autosave_filename, 250, "%s/" AUTOSAVE_PREFIX "%s", last_project_path,
                                                                    last_project_filename);
     if ( sg_project_file_export_xml(autosave_filename) )
        project_changed_since_last_autosave = FALSE;
    }

 /* unlock */
 autosave_locked = FALSE;

 return TRUE;
}


/* Check for a newer rescued or autosaved version of the file. Pop up a dialog that asks
 * whether to open the newer rescued/autosaved file instead. This situation can occur when
 * SciGraphica is forcefully terminated, leaving rescue and/or autosave files behind. */
gchar*
sg_project_autosave_check(gchar *file)
{
 gchar autosave_fn[250], rescue_fn[250];
 gboolean autosave_exist, rescue_exist;
 struct stat file_sb, autosave_sb, rescue_sb;
 time_t file_mtime, autosave_mtime, rescue_mtime, mtime;
 
 /* quit when stat on file fails */
 if ( stat(file, &file_sb) == -1 ) return file;

 g_snprintf(autosave_fn, 250, "%s/" AUTOSAVE_PREFIX "%s", g_dirname(file), g_basename(file));
 autosave_exist = ( stat(autosave_fn, &autosave_sb) != -1 );

 g_snprintf(rescue_fn, 250, "%s/" RESCUE_PREFIX "%s", g_dirname(file), g_basename(file));
 rescue_exist = ( stat(rescue_fn, &rescue_sb) != -1 );
  

#ifndef _POSIX_SOURCE
 file_mtime = file_sb.st_mtimespec.tv_sec;
 if ( autosave_exist ) autosave_mtime = autosave_sb.st_mtimespec.tv_sec;
 if ( rescue_exist ) rescue_mtime = rescue_sb.st_mtimespec.tv_sec;
#else
 file_mtime = file_sb.st_mtime;
 if ( autosave_exist ) autosave_mtime = autosave_sb.st_mtime;
 if ( rescue_exist ) rescue_mtime = rescue_sb.st_mtime;
#endif

 /* mtime will contain the time of the most recent autosave/rescue file */
 mtime = file_mtime;
 if ( autosave_exist && rescue_exist )
  mtime = (rescue_mtime > autosave_mtime ? rescue_mtime : autosave_mtime);
 else if ( autosave_exist )
  mtime = autosave_mtime;
 else if ( rescue_exist )
  mtime = rescue_mtime;

 if ( rescue_exist && mtime == rescue_mtime && mtime > file_mtime )
 {gchar message[]= "Found rescued file that is newer.\nOpen that instead?";
  if ( sg_accept_dialog(message, 1) == YES_CLICKED ) g_snprintf(file, 1+strlen(rescue_fn), "%s", rescue_fn);
 }
 else if ( autosave_exist && mtime == autosave_mtime && mtime > file_mtime )
 {gchar message[]= "Found autosaved file that is newer.\nOpen that instead?";
  if ( sg_accept_dialog(message, 1) == YES_CLICKED ) g_snprintf(file, 1+strlen(autosave_fn), "%s", autosave_fn);
 }
 return file;
}


syntax highlighted by Code2HTML, v. 0.9.1