-- $LastChangedDate: 2008-12-16 12:07:45 -0500 (Tue, 16 Dec 2008) $
-- Basic Lua functions.
-- See module.txt for documentation and pitfalls.

lib = {}  -- namespace

-- Abbrev.
function lib.DefaultArg( arg, val )
	if ( arg == nil ) then
		return val
	else
		return arg
	end
end

-- Destroy an object stored as a member of a table.
-- Pass "member" arg as a string.  Calls destroy() if defined.
-- Example: For self.object : lib.DESTROY( self, "object" )
function lib.DESTROY( table, member )
	local obj = table[member]
	if ( obj ) then
		if ( obj.destroy ) then
			obj.destroy( obj )  -- pass as self
		end
		table[member] = nil
	end
end

-- Produces a metatable (class table) that inherits methods from another one.
-- Examples in module.txt.
function lib.DerivedClass( BaseMT )
	local t = {}
	setmetatable( t, BaseMT )
	BaseMT.__index = BaseMT
	return t
end

-- Produces an "instance table" from a "class table" (metatable).
-- For use in a Class:new() method.
-- Examples in module.txt.
function lib.NewInstance( classTable, argTable )
	-- Construct instance table.
	local instance = argTable or {}
	setmetatable( instance, classTable )
	classTable.__index = classTable
	return instance
end

-- Iterates thru a table starting at a key.
-- If starting key is nil, begins at the first key.
-- Class tables (and many others) have literal strings as keys
-- (t.member is equivalent to t["member"]).
function lib.Iterator( t, startingKey )
	local k = startingKey  -- part of closure
	local first = true
	-- Return 3 args (function, table, nil).
	return
	function ( t )
		if ( not first ) then
			k = next( t, k )
		else
			first = false
		end
		return k, t[k]
	end, t, nil
end

-- Begin iterating AFTER the passed key.
function lib.IteratorAfter( t, key )
	local k = key  -- part of closure
	-- Return 3 args (function, table, nil).
	return
	function ( t )
		k = next( t, k )
		return k, t[k]
	end, t, nil
end

-- Catenate two words, placing space if necessary.
function lib.CatWords( s1, s2 )
	if ( s1 ~= "" ) then
		return s1 .. " " .. s2
	else
		return s2
	end
end

-- Split fields of a string.
function lib.SplitFields( str, sep )
	-- This regex pattern needs a separator at end of string.
	if ( str[string.len(str)] ~= sep ) then
		str2 = string.format( "%s%s", str, sep )
		return {str2:match((str2:gsub("[^"..sep.."]*"..sep, "([^"..sep.."]*)"..sep)))}
	else
		return {str:match((str:gsub("[^"..sep.."]*"..sep, "([^"..sep.."]*)"..sep)))}
	end
end

-- Find element in table (created as an array), then remove it.
-- NOP if element is absent.
function lib.ArrayRemove( t, val )
	local n = table.getn( t )
	for i = 1, n do
		if ( t[i] == val ) then
			table.remove( t, i )
			return
		end
	end
end

-- Rotate table (created as an array).
function lib.ArrayRotate( t )
	local n = table.getn( t )
	if ( n > 1 ) then
		local first = t[1]
		table.remove( t, 1 )
		table.insert( t, first )
	end
end
