#include <string.h>
#include <stream.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include "mkstr.h"
#include "environ.h"

EnvironVar Environment::OPD_standard[] = {

    {"OPD_ROOT","/usr/local/lib/opd_root","ObjectProDSP root directory"},
    // This must be first member if this array!!

    {"OPD_TEMP","/tmp","system directory for temporary files"},
    {"OPD_SHELL","/bin/sh","executable for ANSI stadard shell"},
    {"OPD_X_BIN","/usr/bin/X11","directory for X-windows executables"},
    {"HOME",0,"user home directory"},
    {0}
};

const char* Environment::expand_file_name(const char * file_name)
{
	const max_length = 512 ;
	static char buf[max_length+1] ;
	char name_buf[max_length] ;
	char * dest = buf ;
	int count = 0 ;
	int changed = 0 ;
	const char * pt = file_name ;
	while(*pt && count < max_length && !isspace(*pt)) if (*pt != '$') *dest++ = *pt++,count++;
	else {
		int ncount = 0 ;
		char * npt = name_buf ;
		for (pt++; *pt && ncount < max_length;pt++)
			if (isalnum(*pt) || *pt == '_') *npt++ = *pt, ncount++;
			else break ;
		if (ncount == max_length && *pt) return file_name ;
		*npt++ = '\0' ;
		const char * env = getenv(name_buf);
		if (!env) return file_name ;
		while (*env && count < max_length) *dest++ = *env++,count++ ;
		if (count == max_length && *npt) return file_name ;
		changed = 1 ;
	}
	if (count == max_length && *pt) return file_name ;
	if (!changed) return file_name ;
	*dest = '\0' ;
	return buf ;
}

const char * Environment::get(const char * name)
{
	const char * val = getenv(name);
	if (val) return val ;
	for (EnvironVar * tab = Environment::OPD_standard;
		tab->Name; tab++) if (!strcmp(name,tab->Name)) return tab->Name ;
	return 0;
}

void Environment::Set()
{
	for (const EnvironVar * var = TheVariables; var->Name; var++) {
		if (getenv(var->Name)) continue ;
		if (var->LocalFlag) continue ;
		char * ToPut = Concatenate(var->Name,"=",var->DefaultValue);
		putenv(ToPut);
	}
}


void Environment::Display()
{
	for (const EnvironVar * var = TheVariables; var->Name; var++) {
		if (getenv(var->Name)) cout << var->Name << " is now set to `"
			<< getenv(var->Name) << "'.\n" ;
		if (var->DefaultValue) cout <<
			"The ObjectProDSP default value for `" <<
			var->Name << "' is `" << var->DefaultValue << "'.\n" ;
		else cout << var->Name <<
			" is not set to a default value by ObjectProDSP.\n" ;
		cout << "This variable is the " << var->Description << ".\n";
		if (var->DefaultDescription) cout <<
			"The default is for " << var->DefaultDescription
			<<".\n" ;
		if (var->Options) {
			for (int Count = 0 ; var->Options[Count];Count++) ;
			if (Count > 1) cout << "Available options include:\n" ;
			else cout << "Another options for this is " ;
			for (Count = 0 ; var->Options[Count];Count++)
				cout << var->Options[Count] << ".\n" ;
			if (var->LocalFlag)
				cout << "This variable is used locally only.\n" ;
		}
		cout << "\n" ;
	}
}

