/* Copyright (c) 1997 The Regents of the University of California.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

#ifdef UNIX
#include <stdlib.h>
#include <dlfcn.h>
#endif
#ifdef NT
#include <windows.h>
#endif
#include <string.h>
#include "m_imp.h"
#include <stdio.h>
#define MAXFILENAME 1000

typedef void (*t_xxx)(void);
int sys_loademup(char *classname, char *dirname)
{
    char symname[MAXFILENAME], filename[MAXFILENAME], *loadlib, *lastslash;
    void *dlobj;
    t_xxx makeout;
    if (strlen(classname) > 100) return (0);
    if (strlen(dirname) > MAXFILENAME - 120) return (0);
    if (*classname == '/') strcpy(filename, classname);
    else sprintf(filename, "%s/%s", dirname, classname);

    lastslash = strrchr(filename, '/');
    strcpy(symname, lastslash + 1);
    strcat(symname, "_setup");


#ifdef __linux__
#define PATHLEN 512
    {
	 char pd_path[PATHLEN];
	 char* obj_path;
	 void *dlobj = NULL;
	 int size = 0;

#ifdef INSTALL_PREFIX
	 strcpy(pd_path, ":"INSTALL_PREFIX"/lib/pd/externs");
#else
	 strcpy(pd_path,":/");
#endif
	 if (getenv("PD_EXTERN_PATH")) {
               strcat(pd_path,":");
               strcat(pd_path,getenv("PD_EXTERN_PATH"));
         }

	 obj_path=pd_path;
	 for (size=0;obj_path[size] != ':' && 
		      obj_path[size] !='\0';size++);

	 while (obj_path && !dlobj) {
		 strncpy(filename,obj_path,size);
		 filename[size]='\0';

		 if (*classname != '/' && size != 0 && filename[size-1] != '/')
			 strcat(filename,"/");
		 strcat(filename,classname);
		 strcat(filename, ".pd_linux");
	//	 fprintf(stderr,"fname = %s\n",filename);
		 dlobj = dlopen(filename,  RTLD_NOW);

		 if (obj_path[size] == '\0') // This was the last token
			 break;
		 obj_path+=size+1;
		 for (size=0;obj_path[size] != ':' && 
			      obj_path[size] !='\0';size++);
	 } 
	if (!dlobj)
	{
//	    post("%s in %s", dlerror(),pd_path);
	    return (0);
	}
	makeout = (t_xxx)dlsym(dlobj,  symname);
    }
#endif

#ifdef IRIX
    {
    	void *dlobj;
    	strcat(filename, ".pd_irix5");
    	if (!sys_isreadablefile(filename)) return (0);
    	dlobj = dlopen(filename,  RTLD_NOW);
	if (!dlobj)
	{
	    post("%s: %s", filename, dlerror());
	    return (0);
	}
	makeout = (t_xxx)dlsym(dlobj,  symname);
    }
#endif
#ifdef NT
    {
    	HINSTANCE ntdll;
    	strcat(filename, ".dll");
    	if (!sys_isreadablefile(filename)) return (0);
    	ntdll = LoadLibrary(filename);
    	if (!ntdll)
    	{
	    post("%s: couldn't load", filename);
	    return (0);
	}
    	makeout = (t_xxx)GetProcAddress(ntdll, symname);  
    }
#endif
    if (!makeout)
    {
    	post("load_object: Symbol \"%s\" not found", symname);
    	return 0;
    }
    (*makeout)();
    return (1);
}
