//-----------------------------------------------------------------------------
// AScript string module
//-----------------------------------------------------------------------------

//#define ASCRIPT_DLL_MODULE
#include "Module_string.h"

AScript_BeginModule(string)

// n = string.len(str:string):map
AScript_DeclareFunction(len)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
}

AScript_ImplementFunction(len)
{
	return Value(static_cast<Number>(::_tcslen(context.GetString(0))));
}

// str = string.strip(str:string):map, option:left,right
AScript_DeclareFunction(strip)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
	DeclareAttr(AScript_Symbol(left));
	DeclareAttr(AScript_Symbol(right));
}

AScript_ImplementFunction(strip)
{
	return Value(env, Strip(context.GetString(0), context.GetAttrs()).c_str());
}

// str = string.left(str, len?):map
AScript_DeclareFunction(left)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
	DeclareArg(env, _T("len"), VTYPE_Number, false, OCCUR_ZeroOrOnce);
}

AScript_ImplementFunction(left)
{
	if (context.IsInvalid(1)) return context.GetValue(0);
	return Value(env, Left(context.GetString(0),
					static_cast<size_t>(context.GetNumber(1))).c_str());
}

// str = string.right(str, len?):map
AScript_DeclareFunction(right)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
	DeclareArg(env, _T("len"), VTYPE_Number, false, OCCUR_ZeroOrOnce);
}

AScript_ImplementFunction(right)
{
	if (context.IsInvalid(1)) return context.GetValue(0);
	return Value(env, Right(context.GetString(0),
					static_cast<size_t>(context.GetNumber(1))).c_str());
}

// str = string.mid(str, start?, len?):map
AScript_DeclareFunction(mid)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
	DeclareArg(env, _T("start"), VTYPE_Number, false, OCCUR_ZeroOrOnce);
	DeclareArg(env, _T("len"), VTYPE_Number, false, OCCUR_ZeroOrOnce);
}

AScript_ImplementFunction(mid)
{
	return Value(env, Middle(context.GetString(0),
		context.IsNumber(1)? static_cast<int>(context.GetNumber(1)) : 0,
		context.IsNumber(2)? static_cast<int>(context.GetNumber(2)) : -1).c_str());
}

// result = string.find(str:string, sub:string, start?:number):map
// attributes: list, rev, icase
AScript_DeclareFunction(find)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"),		VTYPE_String);
	DeclareArg(env, _T("sub"),		VTYPE_String);
	DeclareArg(env, _T("start"),	VTYPE_Number, false, OCCUR_ZeroOrOnce);
	DeclareAttr(AScript_Symbol(icase));
	DeclareAttr(AScript_Symbol(rev));
}

AScript_ImplementFunction(find)
{
	return FindString(env, sig, context.GetString(0), context.GetString(1),
			context.IsNumber(2)? context.GetNumber(2) : 0, context.GetAttrs());
}

// result = string.replace(str:string, sub:string, new:string, maxreplace?:number):map
AScript_DeclareFunction(replace)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"),			VTYPE_String);
	DeclareArg(env, _T("sub"),			VTYPE_String);
	DeclareArg(env, _T("replace"),		VTYPE_String);
	DeclareArg(env, _T("maxreplace"),	VTYPE_Number, false, OCCUR_ZeroOrOnce);
	DeclareAttr(AScript_Symbol(icase));
}

AScript_ImplementFunction(replace)
{
	String result = Replace(context.GetString(0),
			context.GetString(1), context.GetString(2),
			context.IsNumber(3)? context.GetNumber(3) : -1, context.GetAttrs());
	return Value(env, result.c_str());
}

// str = string.capitalize(str:string):map
AScript_DeclareFunction(capitalize)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
}

AScript_ImplementFunction(capitalize)
{
	return Value(env, Capitalize(context.GetString(0)).c_str());
}

// str = string.upper(str:string):map
AScript_DeclareFunction(upper)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
}

AScript_ImplementFunction(upper)
{
	return Value(env, Upper(context.GetString(0)).c_str());
}

// str = string.lower(str:string):map
AScript_DeclareFunction(lower)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
}

AScript_ImplementFunction(lower)
{
	return Value(env, Lower(context.GetString(0)).c_str());
}

// str = string.join(strs[]:string, sep?:string):map
AScript_DeclareFunction(join)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("strs"), VTYPE_String, true);
	DeclareArg(env, _T("sep"), VTYPE_String, false, OCCUR_ZeroOrOnce);
}

AScript_ImplementFunction(join)
{
	const ValueList &valList = context.GetList(0);
	return Value(env, Join(valList,
			context.IsString(1)? context.GetString(1) : _T("")).c_str());
}

// list = string.split(str:string, sep?:string, maxnumber?:number):map {block?}
AScript_DeclareFunction(split)
{
	SetMode(RSLTMODE_Normal, MAP_On);
	DeclareArg(env, _T("str"), VTYPE_String);
	DeclareArg(env, _T("sep"), VTYPE_String, false, OCCUR_ZeroOrOnce);
	DeclareArg(env, _T("maxnumber"), VTYPE_Number, false, OCCUR_ZeroOrOnce);
	DeclareAttr(AScript_Symbol(icase));
	DeclareBlock(OCCUR_ZeroOrOnce);
}

AScript_ImplementFunction(split)
{
	const TCHAR *str = context.GetString(0);
	const TCHAR *sep = context.IsString(1)? context.GetString(1) : NULL;
	int maxNumber = context.IsValid(2)? static_cast<int>(context.GetNumber(2)) : -1;
	return Object_String::Split(env, sig, this, context, str, sep, maxNumber);
}

// Module entry
AScript_ModuleEntry()
{
	AScript_AssignFunction(len);
	AScript_AssignFunction(strip);
	AScript_AssignFunction(left);
	AScript_AssignFunction(right);
	AScript_AssignFunction(mid);
	AScript_AssignFunction(capitalize);
	AScript_AssignFunction(upper);
	AScript_AssignFunction(lower);
	AScript_AssignFunction(join);
	AScript_AssignFunction(split);
	AScript_AssignFunction(find);
	AScript_AssignFunction(replace);
}

AScript_EndModule(string)

AScript_DLLModuleEntry(string)
