/* +-------------------------------------------------------------------+ */
/* | Copyright 1993, Jean-Pierre Demailly			       | */
/* | <demailly@fourier.ujf-grenoble.fr>				       | */
/* |								       | */
/* | Permission to use, copy, modify, and to distribute this software  | */
/* | and its documentation for any purpose is hereby granted without   | */
/* | fee, provided that the above copyright notice appear in all       | */
/* | copies and that both that copyright notice and this permission    | */
/* | notice appear in supporting documentation.	 There is no	       | */
/* | representations about the suitability of this software for	       | */
/* | any purpose.  this software is provided "as is" without express   | */
/* | or implied warranty.					       | */
/* |								       | */
/* +-------------------------------------------------------------------+ */

/* $Id: readLXP.c,v 1.14 2021/01/24 20:15:34 demailly Exp $ */

#define MIN(a,b)       (((a) < (b)) ? (a) : (b))

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include "xpaint.h"
#include "image.h"
#include "rwTable.h"

#if defined(sco) || defined(__CYGWIN__)
#include <time.h>
#else
#include <time.h>
#include <sys/time.h>
#endif

#include <string.h>
#include <X11/Intrinsic.h>

#ifndef TRUE
#define TRUE	1
#define FALSE	0
#endif

extern void AddFileToGlobalList(char * file);
extern char * GetShareDir();
extern Image * ReadScriptC(char *file);


static char tmpdir[256] = "";
static char curdir[256] = "";

void SetScriptDir(char *file)
{
    int k;
    char *ptr;
    
    curdir[0] = '\0';
    if (!file) return;
    k = strlen(file) - 2;
    if (k >= 0 && file[k] == '.' && file[k+1] == 'c') {
        ptr = strrchr(file, '/');
        if (ptr) {
	    k = ptr - file;
	    strncpy(curdir, file, k);
	    curdir[k] = '\0';
	}
    }
}

char *Basename(char *file)
{
    char *ptr;
    if (!file) return NULL;
    ptr = strrchr(file, '/');
    if (!ptr) return file;
    return ptr+1;
}

char * ArchiveFile(char * file)
{
    static char path[512];
    struct stat buf;

    if (!stat(file, &buf)) {
      if (*file != '/') {
        getcwd(path, 256);
        strcat(path, "/");
        strcat(path, file);
      } else
        strcpy(path, file);	
      AddFileToGlobalList(path);
      return path;
    }

    if (*tmpdir) {
      sprintf(path, "%s/%s", tmpdir, file);
      if (!stat(path, &buf)) {
        AddFileToGlobalList(path);
        return path;
      }
    }

    if (*curdir) {
      sprintf(path, "%s/%s", curdir, file);
      if (!stat(path, &buf)) {
        AddFileToGlobalList(path);
        return path;
      }
    }

    return NULL;
}

Image **ImagesFromList(char **files, int *n)
{
  int k, p;
  Image **img;
  
  if (!files) {
    *n = 0;
    return NULL;
  }
  p = 0;
  while (files[p]) ++p;
  img = (Image **) malloc((p+1) * sizeof(Image *));

  for (k=0; k<p; k++)
    img[k] = ImageFromFile(ArchiveFile(files[k]));
  img[p] = NULL;
  
  *n = p;
  return img;
}

void DeleteListedImages(Image **img)
{
  int k;

  k = 0;
  if (!img) return;
  while (img[k]) {
    ImageDelete(img[k]);
    k++;
  }
  free(img);
}
		       
/* Test LXP format */
/* LXP is just a plain X.tar.gz archive containing a single directory ./
 * and a C file script.c which may combine any number of other files
 * (images, other .c files of .h headers)
 */
int
TestLXP(char *file)
{
    char header[12], cmd[512];
    FILE *fp;

    fp = fopen(file, "rb");
    if (!fp) return 0;

    fread(header, 1, 8, fp);
    fclose(fp);
    if (strncmp(header, "\037\213", 2)) return 0;

    sprintf(cmd, "tar tvf %s", file);
    fp = popen(cmd, "r");

    while(!feof(fp)) {
        fgets(cmd, 510, fp);
        if (strstr(cmd, "./script.c")) {
	    pclose(fp);
	    return 1;
	}
    }

    pclose(fp);
    return 0;
}

/* read LXP format */
Image *
ReadLXP(char *file)
{
    Image *image;
    struct stat buf;
    char cmd[2048];
    char *home;
    int n = 0;

    if (!TestLXP(file)) return NULL;

    home = getenv("HOME");
    if (!home) return NULL;

 retry:
    sprintf(tmpdir, "%s/.xpaint/tmp/%s_files_%04d", home, Basename(file), n);
    if (stat(tmpdir, &buf) != -1) { n++; goto retry; }

    sprintf(cmd, "mkdir -p \"%s\" ; ln -s -f \"%s\" \"%s\" ; "
	         "cd \"%s\" ; tar xvfz \"%s\"",
            tmpdir, file, tmpdir, tmpdir, file);
    if (system(cmd));
    sprintf(cmd, "%s/script.c", tmpdir);
    AddFileToGlobalList(cmd);
    image = ReadScriptC(cmd);
    tmpdir[0] = '\0';
    /* clean files ??
    sprintf(cmd, "rm -rf \"%s/.xpaint/tmp/%s_files_%04d\"",
	    home, Basename(file), n);
    if (system(cmd));
    */    
    return image;
}
