//-----------------------------------------------------------------------------
// AScript sys module
//-----------------------------------------------------------------------------
#include <ascript.h>

AScript_BeginModule(sys)

//-----------------------------------------------------------------------------
// AScript module functions: sys
//-----------------------------------------------------------------------------
// sys.echo(flag:boolean)
AScript_DeclareFunction(echo)
{
	SetMode(RSLTMODE_Normal, FLAG_None);
	DeclareArg(env, "flag", VTYPE_Boolean);
	SetHelp(
	"Enables or disables echo-back functionality according to flag.");
}

AScript_ImplementFunction(echo)
{
	env.SetEchoFlag(args.GetBoolean(0));
	return Value::Null;
}

// sys.exit(status?:number)
AScript_DeclareFunction(exit)
{
	SetMode(RSLTMODE_Normal, FLAG_None);
	DeclareArg(env, "status", VTYPE_Number, OCCUR_ZeroOrOnce);
	SetHelp(
	"Terminates the program with a specified status number.");
}

AScript_ImplementFunction(exit)
{
	::exit(args.IsNumber(0)? args.GetInt(0) : 0);
	return Value::Null;
}

// sys.listcodec()
AScript_DeclareFunction(listcodec)
{
	SetMode(RSLTMODE_Normal, FLAG_None);
	SetHelp(
	"Returns a list of character codecs that are registered.");
}

AScript_ImplementFunction(listcodec)
{
	Value result;
	ValueList &valList = result.InitAsList(env);
	foreach_const (CodecFactory::List, ppCodecFactory, CodecFactory::GetList()) {
		const CodecFactory *pCodecFactory = *ppCodecFactory;
		valList.push_back(Value(env, pCodecFactory->GetName()));
	}
	return result;
}

AScript_ModuleEntry()
{
	// value assignment
	do {
		Value value;
		ValueList &valList = value.InitAsList(env);
		StringList strList;
		OAL::SetupModulePath(strList);
		foreach (StringList, pStr, strList) {
			valList.push_back(Value(env, pStr->c_str()));
		}
		AScript_AssignValue(path, value);
	} while (0);
	AScript_AssignValue(ps1, Value(env, ">>> "));
	AScript_AssignValue(ps2, Value(env, "... "));
	do {
		Value value;
#if defined(_MSC_VER)
		value = Value(AScript_Symbol(msc));
#elif defined(__BORLANDC__)
		value = Value(AScript_Symbol(bcc));
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
		value = Value(AScript_Symbol(gnuc));
#else
		value = Value::Null;
#endif
		AScript_AssignValue(build, value);
	} while (0);
	AScript_AssignValue(executable, Value(env, OAL::GetExecutable().c_str()));
	AScript_AssignValue(datadir, Value(env, OAL::GetDataDir().c_str()));
	AScript_AssignValue(libdir, Value(env, OAL::GetLibDir().c_str()));
	// function assignment
	AScript_AssignFunction(echo);
	AScript_AssignFunction(exit);
	AScript_AssignFunction(listcodec);
}

AScript_ModuleTerminate()
{
}

void Setup(Module *pModule, Signal sig, int argc, const char *argv[])
{
	Environment &env = *pModule;
	do {
		Value value;
		ValueList &valList = value.InitAsList(env);
		if (argc >= 2 && argv != NULL) {
			valList.push_back(Value(env,
					OAL::MakeAbsPath(OAL::FileSeparator, argv[1], NULL).c_str()));
			for (int i = 2; i < argc; i++) {
				const char *arg = argv[i];
				valList.push_back(Value(env, arg));
			}
		}
		env.AssignValue(Symbol::Add("argv"), value, false);
	} while (0);
	env.GetGlobal()->_pModule_sys = pModule;
}

AScript_EndModule(sys, sys)

AScript_RegisterModule(sys)
