# AVSLib :: 'debug' package :: 'logging' module
# Copyright (c) 2005, 2007 George Zarkadas (gzarkadas@users.sourceforge.net)

# This program is free software; you can redistribute it and/or modify it under the terms of 
# the GNU General Public License as published by the Free Software Foundation; either 
# version 2 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program; 
# if not, write to the "Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
# MA  02111-1307  USA"

DefineModule("avslib", "debug", "logging")

# There must *not* be a debuging version of this module because then each call to 
# DebugLog would result in calling recursively the function indefinetly and eventually 
# in abnormal termination due to stack overflow.

global __load__ = Eval("""
	LoadModule("avslib", "numeric", "core")
	""")
global __load__ = IsPackageLoaded("avslib", "string") ? NOP : Eval("""
	LoadModule("avslib", "string", "core")
	LoadModule("avslib", "string", "sprintf")
	""")

# Values <  DBG_LIBRARY 
#     are considered user's space (99 available).
# Values >= DBG_LIBRARY and < DBG_RESERVED 
#     are reserved for other libraries' internal logging and are free 
#     to be defined by extension developers (63900 available).
# Values >= DBG_RESERVED 
#     are reserved for AVSLib.

global DBG_NODEBUG  = 0    # no logging

global DBG_LEVEL_1  = 1    # User level-1 logging (eg. for new code)
global DBG_LEVEL_2  = 2    # User level-2 logging (eg. for beta code)
global DBG_LEVEL_3  = 3    # User level-3 logging (eg. for stable code)
global DBG_LEVEL_4  = 4    # User level-4 logging (eg. for well tested code)

global DBG_LIBRARY  = 100  # Other libraries' level-1 logging (up to 3999)
global DBG_RESERVED = 64000 # values >= DBG_RESERVED are reserved for AVSLib's logging

global DBG_FILT_STD = DBG_RESERVED + 100	# filters only - moderate
global DBG_FILT_EXT = DBG_RESERVED + 200	# filters only - verbose

global DBG_FUNC_STD = DBG_RESERVED + 300	# above + top-level functions - moderate
global DBG_FUNC_EXT = DBG_RESERVED + 400	# above + top-level functions - verbose

global DBG_CONT_STD = DBG_RESERVED + 500	# above + containers internals - moderate
global DBG_CONT_EXT = DBG_RESERVED + 600	# above + containers internals - verbose

global DBG_CORE_STD = DBG_RESERVED + 700	# above + core functions - moderate
global DBG_CORE_EXT = DBG_RESERVED + 800	# above + core functions - verbose


# logging internal variables and access (get/set) functions

global __debug_mode = DBG_NODEBUG
global __debug_log_fname = "__log__.txt"
# There is no need to provide access function below; we only use WriteFileEnd
global __debug_log_clip = BlankClip(length=1) 

Function GetDebugMode() { return __debug_mode }

Function SetDebugMode(int mode)
{
	Assert(mode >= 0, \
		"SetDebugMode: mode can only have positive values")
	oldmode = __debug_mode
	global __debug_mode = mode
	return oldmode
}

Function GetDebugFile() { return __debug_log_fname }

Function SetDebugFile(string path)
{
	oldpath = __debug_log_fname
	global __debug_log_fname = path
	return oldpath
}

# DebugLog implementation

	Function __debug_log_core(string format, \
		val "p01", val "p02", val "p03", val "p04", val "p05", val "p06", \
		val "p07", val "p08", val "p09", val "p10", val "p11", val "p12", \
		val "p13", val "p14", val "p15", val "p16", val "p17", val "p18", \
		val "p19", val "p20", val "p21", val "p22", val "p23", val "p24", \
		val "p25", val "p26", val "p27", val "p28", val "p29", val "p30", \
		val "p31", val "p32", val "p33", val "p34", val "p35", val "p36", \
		val "p37", val "p38", val "p39", val "p40", val "p41", val "p42", \
		val "p43", val "p44", val "p45", val "p46", val "p47", val "p48", \
		val "p49", val "p50" )
	{
		# if format is not provided (""), create a default one
		fmt = format == "" \
			? StrFill("\t%v", Count(p01, p02, p03, p04, p05, p06, p07, p08, \
				p09, p10, p11, p12, p13, p14, p15, p16) + Count(p17, p18, \
				p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, \
				p31, p32, p33) + Count(p34, p35, p36, p37, p38, p39, p40, \
				p41, p42, p43, p44, p45, p46, p47, p48, p49, p50)) \
			: format
		fmt = format == "" ? StrMid(fmt, 2, StrLen(fmt)) : fmt
		# printf the exression and write it to log file
		s_out = StrPrint(format, p01, p02, p03, p04, p05, p06, p07, p08, \
			p09, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, \
			p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, \
			p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, \
			p48, p49, p50)
		dummy = WriteFileEnd(__debug_log_clip, __debug_log_fname, "s_out")
		# return the length of string written.
		return StrLen(s_out)
	}

Function DebugLog(int debug_level, string format, val "p01", val "p02", \
	val "p03", val "p04", val "p05", val "p06", val "p07", val "p08", \
	val "p09", val "p10", val "p11", val "p12", val "p13", val "p14", \
	val "p15", val "p16", val "p17", val "p18", val "p19", val "p20", \
	val "p21", val "p22", val "p23", val "p24", val "p25", val "p26", \
	val "p27", val "p28", val "p29", val "p30", val "p31", val "p32", \
	val "p33", val "p34", val "p35", val "p36", val "p37", val "p38", \
	val "p39", val "p40", val "p41", val "p42", val "p43", val "p44", \
	val "p45", val "p46", val "p47", val "p48", val "p49", val "p50" )
{
	return __debug_mode < debug_level \
		? NOP \
		: __debug_log_core(format, p01, p02, p03, p04, p05, p06, p07, p08, \
			p09, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, \
			p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, \
			p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, \
			p48, p49, p50)
}
