#include <v_lib.h>
#include "istrings.h"
#include "ipltrans.h"
#include "cspace.h"
#include "state.h"
#include "iplver.h"

GLOBAL_STRING(ipl_usage,
	"Image processing language interpreter.\n"
	"Version " IPL_VERSION " by Vladimir A. Smirnov.\n"
	"Usage: " IPL_BASENAME " <scriptfile>\n"
	"For brief IPL language description, type " IPL_BASENAME " --help-ipl.\n"
	"For brief NSL built-in language description, type " IPL_BASENAME " --help-nsl.\n")

/* can't be very long: will pass it to printf() */
GLOBAL_STRING(ipl_exit_status,
	"IPL run completed: %s. (alloc: %u bytes; leak: %u bytes)\n")

GLOBAL_STRING(ipl_key_global,"global")
GLOBAL_STRING(ipl_key_random_seed,"random_seed")
GLOBAL_STRING(ipl_key_alias,"alias")
GLOBAL_STRING(ipl_unable_to_open,"unable to open: ")
GLOBAL_STRING(ipl_success,"success")
GLOBAL_STRING(ipl_error,"error(s)")

GLOBAL_STRING(ipl_open_brace,IPL_OPEN_BRACE)
GLOBAL_STRING(ipl_close_brace,IPL_CLOSE_BRACE)
GLOBAL_STRING(ipl_open_bracket,IPL_OPEN_BRACKET)
GLOBAL_STRING(ipl_close_bracket,IPL_CLOSE_BRACKET)
GLOBAL_STRING(ipl_comma,IPL_COMMA)

GLOBAL_STRING(ipl_key_void,"void")
GLOBAL_STRING(ipl_key_true,"true")
GLOBAL_STRING(ipl_key_false,"false")

GLOBAL_STRING(ipl_key_rgb,"RGB")
GLOBAL_STRING(ipl_key_rgba,"RGBA")
GLOBAL_STRING(ipl_key_hsv,"HSV")
GLOBAL_STRING(ipl_key_hsva,"HSVA")
GLOBAL_STRING(ipl_key_cie,"CIE")
GLOBAL_STRING(ipl_desc_rgb,"channels 0...3 represents red, green and blue")
GLOBAL_STRING(ipl_desc_rgba,"channels 0...4 represents red, green, blue and alpha")
GLOBAL_STRING(ipl_desc_hsv,"channels 0...3 represents hue, saturation, and value")
GLOBAL_STRING(ipl_desc_hsva,"channels 0...4 represents hue, saturation, value and alpha")
GLOBAL_STRING(ipl_desc_cie,"channels 0...3 represents CIE X, Y and Z")
GLOBAL_STRING(ipl_key_red,"red")
GLOBAL_STRING(ipl_key_green,"green")
GLOBAL_STRING(ipl_key_blue,"blue")
GLOBAL_STRING(ipl_key_alpha,"alpha")
GLOBAL_STRING(ipl_key_hue,"hue")
GLOBAL_STRING(ipl_key_saturation,"saturation")
GLOBAL_STRING(ipl_key_value,"value")
GLOBAL_STRING(ipl_key_cieX,"cieX")
GLOBAL_STRING(ipl_key_cieY,"cieY")
GLOBAL_STRING(ipl_key_cieZ,"cieZ")
GLOBAL_STRING(ipl_key_targets,"targets")
GLOBAL_STRING(ipl_key_output,"output")
GLOBAL_STRING(ipl_key_matrix,"matrix")
GLOBAL_STRING(ipl_desc_matrix,"2D array of real numbers")
GLOBAL_STRING(ipl_key_vector,"vector")
GLOBAL_STRING(ipl_desc_vector,"array of real numbers")
GLOBAL_STRING(ipl_key_decomposition,"decomposition")
GLOBAL_STRING(ipl_desc_decomposition,"binary-tree image decomposition")
GLOBAL_STRING(ipl_key_state,"state")
GLOBAL_STRING(ipl_tab_string,"\t")
GLOBAL_STRING(ipl_eol_string,"\n")
GLOBAL_STRING(ipl_key_source_dimension,"source_dimension")
GLOBAL_STRING(ipl_key_depth_range,"depth_range")
GLOBAL_STRING(ipl_key_area_range,"area_range")
GLOBAL_STRING(ipl_key_value_range,"value_range")
GLOBAL_STRING(ipl_key_at_depth,"at_depth")
GLOBAL_STRING(ipl_key_leafs,"leafs")
GLOBAL_STRING(ipl_key_values,"values")
GLOBAL_STRING(ipl_key_histogram,"histogram")
GLOBAL_STRING(ipl_run_time_fmt,"time since start: %.2f\n")

/* generic operations */

GLOBAL_STRING(ipl_key_generic_constant,"constant")
GLOBAL_STRING(ipl_desc_generic_constant,
		" <real value>: sets all elements to given 'value'")

GLOBAL_STRING(ipl_key_generic_uniform,"uniform")
GLOBAL_STRING(ipl_desc_generic_uniform,
		" <real lower,upper>: sets all elements to samples of uniform\n"
		"\t\tdistribution with given 'lower' and 'upper' bounds")

GLOBAL_STRING(ipl_key_generic_gaussian,"gaussian")
GLOBAL_STRING(ipl_desc_generic_gaussian,
		" <real mean,standard_deviation>: sets all elements to \n"
		"\t\tsamples of normal distribution with given mean and\n"
		"\t\tstandard deviation")

GLOBAL_STRING(ipl_key_generic_puts,"puts")
GLOBAL_STRING(ipl_desc_generic_puts,
		" <string token>: writes 'token' to standard output")

GLOBAL_STRING(ipl_key_generic_run_time,"run_time")
GLOBAL_STRING(ipl_desc_generic_run_time,
		": prints time since the start of program")

/* matrix operations */

GLOBAL_STRING(ipl_key_matrix_copy,"copy")
GLOBAL_STRING(ipl_desc_matrix_copy,
		" <matrix src>: copies the data from matrix 'src'")

GLOBAL_STRING(ipl_key_matrix_input,"input")
GLOBAL_STRING(ipl_desc_matrix_input,
		" <string image_name,channel_name>: loads data from image file")

GLOBAL_STRING(ipl_key_matrix_get,"get")
GLOBAL_STRING(ipl_desc_matrix_get,
		" <int dst_left,dst_top;matrix src;uint left,top,right,bottom>:\n"
		"\t\tcopies contents of source rectangle [left...bottom]\n"
		"\t\tat [dst_left,dst_top] position of current matrix\n"
		"\t\t(may be useful for circular shifts of elements)")

GLOBAL_STRING(ipl_key_matrix_set_elem,"set_elem")
GLOBAL_STRING(ipl_desc_matrix_set_elem,
		" <uint col,row;real value>: sets element at 'row' and 'col'\n"
		"\t\tto 'value'")

GLOBAL_STRING(ipl_key_matrix_set_rect,"set_rect")
GLOBAL_STRING(ipl_desc_matrix_set_rect,
		" <uint left,top,right,bottom;real value>: sets all elements\n"
		"\t\tin specified rectangle to given 'value'")

GLOBAL_STRING(ipl_key_matrix_shift,"shift")
GLOBAL_STRING(ipl_desc_matrix_shift,
		" <int shift_cols,shift_rows>: circular shift of elements")

GLOBAL_STRING(ipl_key_matrix_mirror,"mirror")
GLOBAL_STRING(ipl_desc_matrix_mirror,
		" <boolean mirror_x,mirror_y>: mirrors\n"
		"\t\trows and / or columns of the matrix")

GLOBAL_STRING(ipl_key_matrix_transpose,"transpose")
GLOBAL_STRING(ipl_desc_matrix_transpose,": transposes the matrix")

GLOBAL_STRING(ipl_key_matrix_expand,"expand")
GLOBAL_STRING(ipl_desc_matrix_expand,
		" <uint new_width,new_height>: expands or crops the matrix,\n"
		"\t\tpadding it with state->pad_value if necessary")

GLOBAL_STRING(ipl_key_matrix_expand_powers2,"expand_powers2")
GLOBAL_STRING(ipl_desc_matrix_expand_powers2,
		": expands the matrix in such a way that both width\n"
		"\t\tand height becomes powers of 2")

GLOBAL_STRING(ipl_key_matrix_resize,"resize")
GLOBAL_STRING(ipl_desc_matrix_resize,
		" <uint new_width,new_height>: resizes the matrix using\n"
		"\t\tsubpixel-correct bilinear interpolation")

GLOBAL_STRING(ipl_key_matrix_save,"save")
GLOBAL_STRING(ipl_desc_matrix_save,
		" <string file_name>: writes matrix to text file")

GLOBAL_STRING(ipl_key_matrix_load,"load")
GLOBAL_STRING(ipl_desc_matrix_load,
		" <string file_name>: reads matrix from text file")

GLOBAL_STRING(ipl_key_tga,"tga") /* used by matrix_save/load32_op */

GLOBAL_STRING(ipl_key_matrix_save32,"save32")
GLOBAL_STRING(ipl_desc_matrix_save32,
		" <string file_name>: converts matrix data to fixed-point\n"
		"\t\trepresentation (assumes [0..1] range) and writes to TGA file")

GLOBAL_STRING(ipl_key_matrix_load32,"load32")
GLOBAL_STRING(ipl_desc_matrix_load32,
		" <string file_name>: reads TGA file and converts data from\n"
		"\t\tfixed-point representation to [0..1] range")

GLOBAL_STRING(ipl_key_matrix_row_linear,"row_linear")
GLOBAL_STRING(ipl_desc_matrix_row_linear,
		" <real min,max>: linearly interpolates from given 'min'\n"
		"\t\tto given 'max' and writes results to every row")

GLOBAL_STRING(ipl_key_matrix_col_linear,"col_linear")
GLOBAL_STRING(ipl_desc_matrix_col_linear,
		" <real min,max>: linearly interpolates from given 'min'\n"
		"\t\tto given 'max' and writes results to every column")

GLOBAL_STRING(ipl_key_matrix_fourier_forward,"fourier_forward")
GLOBAL_STRING(ipl_desc_matrix_fourier_forward,
		": replaces matrix by its 2D Fourier transform")

GLOBAL_STRING(ipl_key_matrix_fourier_inverse,"fourier_inverse")
GLOBAL_STRING(ipl_desc_matrix_fourier_inverse,
		": replaces 2D Fourier transform by its inversion")

GLOBAL_STRING(ipl_key_matrix_scale,"scale")
GLOBAL_STRING(ipl_desc_matrix_scale,
		" <real value>: multiplies all elements by given 'value'")

GLOBAL_STRING(ipl_key_matrix_offset,"offset")
GLOBAL_STRING(ipl_desc_matrix_offset,
		" <real value>: performs either addition of given 'value' to\n"
		"\t\tall elements of (spatial-domain) matrix, or phase addition\n"
		"\t\tfor frequency-domain matrix")

GLOBAL_STRING(ipl_key_matrix_mat_offset,"mat_offset")
GLOBAL_STRING(ipl_desc_matrix_mat_offset,
		" <matrix other>: performs either per-element addition of \n"
		"\t\telements of two (spatial-domain) matrices, or per-element\n"
		"\t\tphase addition of two frequency-domain matrices")

GLOBAL_STRING(ipl_key_matrix_mat_scale,"mat_scale")
GLOBAL_STRING(ipl_desc_matrix_mat_scale,
		" <matrix other>: per-element multiplication of two matrices\n"
		"\t\tor (complex) multiplication of two Fourier transforms\n"
		"\t\t(useful for computing convolutions)")

GLOBAL_STRING(ipl_key_matrix_mat_unscale,"mat_unscale")
GLOBAL_STRING(ipl_desc_matrix_mat_unscale,
		" <matrix other>: per-element division of two matrices\n"
		"\t\tor (complex) division of two Fourier transforms\n"
		"\t\t(useful for computing deconvolutions)")

GLOBAL_STRING(ipl_key_matrix_zero_rows,"zero_rows")
GLOBAL_STRING(ipl_desc_matrix_zero_rows,
		" <uint min,max>; clears rows in range ['min','max']\n"
		"\t\t(operates correctly with Fourier transforms; useful\n"
		"\t\tfor frequency-domain filtering)")

GLOBAL_STRING(ipl_key_matrix_zero_cols,"zero_cols")
GLOBAL_STRING(ipl_desc_matrix_zero_cols,
		" <uint min,max>: clears columns in range ['min','max']\n"
		"\t\t(operates correctly with Fourier transforms; useful\n"
		"\t\tfor frequency-domain filtering)")

GLOBAL_STRING(ipl_key_matrix_convolve3x3,"convolve3x3")
GLOBAL_STRING(ipl_desc_matrix_convolve3x3,
		" <matrix filter3x3>: convolves the matrix with 3x3 PSF")

GLOBAL_STRING(ipl_key_matrix_band_reject,"band_reject")
GLOBAL_STRING(ipl_desc_matrix_band_reject,
		" <uint min,max>: clears both rows and columns in range\n"
		"\t\t['min','max'] (operates correctly with Fourier transforms;\n"
		"\t\tuseful for frequency-domain filtering)")

GLOBAL_STRING(ipl_key_matrix_band_pass,"band_pass")
GLOBAL_STRING(ipl_desc_matrix_band_pass,
		" <uint min,max>: clears both rows and columns outside the\n"
		"\t\trange ['min','max'] (operates correctly with Fourier\n"
		"\t\ttransforms; useful for frequency-domain filtering)")

GLOBAL_STRING(ipl_key_matrix_adjust_contrast,"adjust_contrast")
GLOBAL_STRING(ipl_desc_matrix_adjust_contrast,
		" <real min,max>: linearly interpolates range\n"
		"\t\t['min';'max'] in current (spatial-domain) matrix to\n"
		"\t\trange [0,1] (useful for selecting the only specific,\n"
		"\t\ta-priori known range for visualizing at full contrast;\n"
		"\t\tshouldn't be confused with \"normalize\" operation)")

GLOBAL_STRING(ipl_key_matrix_normalize,"normalize")
GLOBAL_STRING(ipl_desc_matrix_normalize,
		": linearly transforms all elements in such a way that\n"
		"\t\tminimal value of matrix becomes 0, and maximal becomes 1")

GLOBAL_STRING(ipl_key_matrix_range_normalize,"range_normalize")
GLOBAL_STRING(ipl_desc_matrix_range_normalize,
		" <real new_min,new_max>: linearly transforms all\n"
		"\t\telements in such a way that minimal value of matrix becomes\n"
		"\t\t'new_min', and maximal one becomes 'new_max'")

GLOBAL_STRING(ipl_key_matrix_gamma_correction,"gamma_correction")
GLOBAL_STRING(ipl_desc_matrix_gamma_correction,
		" <vector curve>: performs arbitrary transform of all\n"
		"\t\telements in such a way that minimal value of matrix becomes\n"
		"\t\tequal to first element of 'curve', and maximal one becomes\n"
		"\t\tequal to last element of 'curve'; uses 'curve' as\n"
		"\t\tinput-to-output function (useful for color reduction and\n"
		"\t\thistogram equalization)")

GLOBAL_STRING(ipl_key_matrix_draw_decomposition,"draw_decomposition")
GLOBAL_STRING(ipl_desc_matrix_draw_decomposition,
		" <decomposition decomp>: stores (sparse)\n"
		"\t\trepresentation of binary image decomposition 'decomp'\n"
		"\t\tin current matrix")

GLOBAL_STRING(ipl_key_matrix_draw_decomposition_scale,
		"draw_decomposition_scale")
GLOBAL_STRING(ipl_desc_matrix_draw_decomposition_scale,
		" <decomposition decomp;vector colors>:\n"
		"\t\tstores representation of binary decomposition 'decomp',\n"
		"\t\tusing, at each depth, colors from vector 'colors'")

GLOBAL_STRING(ipl_key_matrix_draw_decomposition_linear,
		"draw_decomposition_linear")
GLOBAL_STRING(ipl_desc_matrix_draw_decomposition_linear,
		" <decomposition decomp;real min,max>:\n"
		"\t\tstores representation of binary decomposition 'decomp',\n"
		"\t\tusing, at each depth, colors from 'min' up to 'max'")

GLOBAL_STRING(ipl_key_matrix_matrix_transform,"matrix_transform")
GLOBAL_STRING(ipl_desc_matrix_matrix_transform,
		" <string name[(real arg1,...,argN)]>: executes\n"
		"\t\ttransform 'name' for current spatial-domain matrix")

GLOBAL_STRING(ipl_key_matrix_cartesian_transform,"cartesian_transform")
GLOBAL_STRING(ipl_desc_matrix_cartesian_transform,
		" <string name[(real arg1,...,argN)]>:\n"
		"\t\texecutes transform 'name' for current frequency-domain\n"
		"\t\tmatrix, passing (Re,Im) pairs on each iteration")

GLOBAL_STRING(ipl_key_matrix_polar_transform,"polar_transform")
GLOBAL_STRING(ipl_desc_matrix_polar_transform,
		" <string name[(real arg1,...,argN)]>: executes\n"
		"\t\ttransform 'name' for current frequency-domain matrix,\n"
		"\t\tpassing (Magnitude,Phase) pairs on each iteration")

GLOBAL_STRING(ipl_key_matrix_matrix_pair_transform,
		"matrix_pair_transform")
GLOBAL_STRING(ipl_desc_matrix_matrix_pair_transform,
		" <string name[(real arg1,...,argN)];matrix other>:\n"
		"\t\texecutes transform 'name' for current and 'other'\n"
		"\t\tmatrices (both matrices must be in spatial domain)")

GLOBAL_STRING(ipl_key_matrix_cartesian_pair_transform,
		"cartesian_pair_transform")
GLOBAL_STRING(ipl_desc_matrix_cartesian_pair_transform,
		" <string name[(real arg1,...,argN)];matrix m2>:\n"
		"\t\texecutes transform 'name' for current and 'm2'\n"
		"\t\tmatrices (both matrices must be in frequency domain),\n"
		"\t\tpassing (Re1,Im1) and (Re1,Im2) pairs")

GLOBAL_STRING(ipl_key_matrix_polar_pair_transform,
		"polar_pair_transform")
GLOBAL_STRING(ipl_desc_matrix_polar_pair_transform,
		" <string name[(real arg1,...,argN)];matrix other>:\n"
		"\t\texecutes transform 'name' for current and 'other'\n"
		"\t\tmatrices (both matrices must be in frequency domain),\n"
		"\t\tpassing (Magnitude1,Phase1) and (Magnitude2,Phase2) pairs")

GLOBAL_STRING(ipl_key_matrix_spectrum,"spectrum")
GLOBAL_STRING(ipl_desc_matrix_spectrum,
		": replaces current frequency-domain matrix by its (half-sized)\n"
		"\t\tpower spectrum estimation (adds magnitudes which\n"
		"\t\tcorresponds to maximal and zero frequencies)")

/* vector operations */

GLOBAL_STRING(ipl_key_vector_copy,"copy")
GLOBAL_STRING(ipl_desc_vector_copy,
		" <vector src>: copies the data from vector 'src'")

GLOBAL_STRING(ipl_key_vector_save,"save")
GLOBAL_STRING(ipl_desc_vector_save,
		" <string file_name>: writes vector to text file")

GLOBAL_STRING(ipl_key_vector_load,"load")
GLOBAL_STRING(ipl_desc_vector_load,
		" <string file_name>: loads vector from text file")

GLOBAL_STRING(ipl_key_vector_shift,"shift")
GLOBAL_STRING(ipl_desc_vector_shift,
		" <int amount>: circular shift of elements")

GLOBAL_STRING(ipl_key_vector_mirror,"mirror")
GLOBAL_STRING(ipl_desc_vector_mirror,
		": mirrors the vector")

GLOBAL_STRING(ipl_key_vector_linear,"linear")
GLOBAL_STRING(ipl_desc_vector_linear,
		" <real min,max>: linearly interpolates from 'min' to 'max'")

GLOBAL_STRING(ipl_key_vector_histogram,"histogram")
GLOBAL_STRING(ipl_desc_vector_histogram,
		" <matrix src>: computes histogram of matrix 'src',\n"
		"\t\tlower bound of first bin will be equal to minimal element\n"
		"\t\tof 'src', upper bound of last bin will be equal to maximal\n"
		"\t\telement of 'src'")

GLOBAL_STRING(ipl_key_vector_range_histogram,"range_histogram")
GLOBAL_STRING(ipl_desc_vector_range_histogram,
		" <matrix src;real min,max>: computes histogram of 'src',\n"
		"\t\tlower bound of first bin will be equal to 'min', upper\n"
		"\t\tbound of last bin will be equal to 'max'")

GLOBAL_STRING(ipl_key_vector_histogram_with_coords,"histogram_with_coords")
GLOBAL_STRING(ipl_desc_vector_histogram_with_coords,
		" <matrix src,vector coords>: computes histogram\n"
		"\t\tof matrix 'src', stores center of each bin to 'coords'")

GLOBAL_STRING(ipl_key_vector_range_histogram_with_coords,
		"range_histogram_with_coords")
GLOBAL_STRING(ipl_desc_vector_range_histogram_with_coords,
		" <matrix src,vector coords>: computes range histogram\n"
		"\t\tof matrix 'src', stores center of each bin to 'coords'")

GLOBAL_STRING(ipl_key_vector_integrate,"integrate")
GLOBAL_STRING(ipl_desc_vector_integrate,
		": computes running sum (\"discrete integral\")")

GLOBAL_STRING(ipl_key_vector_normalize,"normalize")
GLOBAL_STRING(ipl_desc_vector_normalize,
		": linearly transforms all elements in such a way that\n"
		"\t\tminimal value of vector becomes 0, and maximal becomes 1")

GLOBAL_STRING(ipl_key_vector_range_normalize,"range_normalize")
GLOBAL_STRING(ipl_desc_vector_range_normalize,
		" <real new_min,new_max>: linearly transforms all\n"
		"\t\telements in such a way that minimal value of vector becomes\n"
		"\t\t'new_min', and maximal one becomes 'new_max'")

GLOBAL_STRING(ipl_key_vector_vector_transform,"vector_transform")
GLOBAL_STRING(ipl_desc_vector_vector_transform,
		" <string name[(real arg1,...,argN)]>: executes\n"
		"\t\ttransform 'name' for current spatial-domain vector")

GLOBAL_STRING(ipl_key_vector_vector_pair_transform,"vector_pair_transform")
GLOBAL_STRING(ipl_desc_vector_vector_pair_transform,
		" <string name[(real arg1,...,argN)];vector other>:\n"
		"\t\texecutes transform 'name' for current and 'other'\n"
		"\t\tspatial-domain vectors")

/* decomposition operations */

GLOBAL_STRING(ipl_key_decomposition_decompose,"decompose")
GLOBAL_STRING(ipl_desc_decomposition_decompose,
	" <matrix src;real threshold;uint histogram_divisions>:\n"
	"\t\tdecomposes matrix 'src' with given 'threshold' and,\n"
	"\t\teach level, computes histograms of size 'histogram_divisions'")

GLOBAL_STRING(ipl_key_decomposition_save,"save")
GLOBAL_STRING(ipl_desc_decomposition_save,
	" <string file_name;boolean save_values,relative_frequencies>:\n"
	"\t\tsaves ASCII description of decomposition to file 'file_name'")

GLOBAL_STRING(ipl_valid_class_ops_fmt, \
	"\nValid operations for \"%s\" class:\n")

/* built-in functions */

GLOBAL_STRING(ipl_key_width_of,"width_of")
GLOBAL_STRING(ipl_desc_width_of,"returns number of cols in given matrix")
GLOBAL_STRING(ipl_key_height_of,"height_of")
GLOBAL_STRING(ipl_desc_height_of,"returns number of cols in given matrix")
GLOBAL_STRING(ipl_key_size_of,"size_of")
GLOBAL_STRING(ipl_desc_size_of,"returns number of elements in given vector")
GLOBAL_STRING(ipl_key_depth_of,"depth_of")
GLOBAL_STRING(ipl_desc_depth_of,"returns depth of given binary decomposition")
GLOBAL_STRING(ipl_key_user_input,"input")
GLOBAL_STRING(ipl_desc_user_input,"reads number from standard input")

GLOBAL_STRING(ipl_key_step,"step")
GLOBAL_STRING(ipl_key_pass,"pass")

/* efunc.c */

GLOBAL_STRING(ipl_key_function,"function")

/* state.c */

GLOBAL_STRING(ipl_key_custom_width,"custom_width")
GLOBAL_STRING(ipl_desc_custom_width,"width of matrix to be loaded/created")
GLOBAL_STRING(ipl_key_custom_size,"custom_size")
GLOBAL_STRING(ipl_desc_custom_size,"size of vector to be created")
GLOBAL_STRING(ipl_key_custom_height,"custom_height")
GLOBAL_STRING(ipl_desc_custom_height,"height of matrix to be loaded/created")
GLOBAL_STRING(ipl_key_input_powers2,"input_powers2")
GLOBAL_STRING(ipl_desc_input_powers2,"resizing flag for matrix to be loaded")
GLOBAL_STRING(ipl_key_input_square,"input_square")
GLOBAL_STRING(ipl_desc_input_square,"resizing flag for matrix to be loaded")
GLOBAL_STRING(ipl_key_frequency_domain,"frequency_domain")
GLOBAL_STRING(ipl_desc_frequency_domain,"affects the interpretation of data")
GLOBAL_STRING(ipl_key_pad_value,"pad_value")
GLOBAL_STRING(ipl_desc_pad_value,"padding value for \"expand\" / \"expand_powers2\"")
GLOBAL_STRING(ipl_key_signed,"signed")
GLOBAL_STRING(ipl_key_unsigned,"unsigned")
GLOBAL_STRING(ipl_key_boolean,"boolean")
GLOBAL_STRING(ipl_key_real,"real")
GLOBAL_STRING(ipl_key_unknown_type,"[unknown type]")
GLOBAL_STRING(ipl_key_dump,"dump")

/*
 * This _is_ weird, but handy :)
 */

void iplHelp()
{
	conPuts("The IPL script can contain:\n");
	conPrintf("\t\"%s\" section(s);\n",ipl_key_global);
	conPuts(
		"\tdefinitions of IPL object(s);\n"
		"\tdefinitions of transform(s);\n"
		"\tdefinitions of function(s);\n");
	conPrintf("\t\"%s\" section(s).\n\n",ipl_key_targets);
	conPrintf(
"The main purpose of the \"%s\" section is to define aliases. The initial\n",
		ipl_key_global);
	conPuts(
"value of the random number generator can be specified there also. All ");
	conPrintf(
"\"%s\"\nsections parsed _before_ any \"%s\" section. The format of section:\n",
		ipl_key_global,ipl_key_targets);
	conPrintf(
"\n%s\n"
"{\n"
"\t%s <integer>\n\t%s <old_token> <replacement>\n"
"\t%s <old_token> <replacement>\n"
"\t...\n"
"}\n\n",
		ipl_key_global,ipl_key_random_seed,ipl_key_alias,ipl_key_alias);
	conPuts(
"where\n"
"\t<integer> - initial value of random number generator;\n"
"\t<old_token> - string to be replaced by <replacement>.\n\n");
	conPrintf(
"The purpose of \"%s\" section is to specify raster images and IPL\n",
		ipl_key_targets);
	conPrintf(
"objects that have to be evaluated. Format of \"%s\" section:\n",
		ipl_key_targets);
	conPrintf(
"\n%s\n"
"{\n",
		ipl_key_targets);
	conPuts(
"\t<ipl_object_class> <object_name>\n"
"\t<ipl_object_class> <object_name>\n"
"\t...\n");
	conPrintf(
"\t%s <file_name> <colorspace> <channel 0> ... <channel N>\n"
"\t%s <file_name> <colorspace> <channel 0> ... <channel N>\n"
"\t...\n"
"}\n\n",
		ipl_key_output,ipl_key_output);
	conPuts(
"where\n"
"\t<ipl_object_class> - class of IPL object (see below);\n"
"\t<object_name> - unique identifier of object;\n"
"\t<file_name> - name of output raster image file;\n"
"\t<colorspace> - string that specifies how to handle color channels;\n"
"\t<channel 0...N> - matrices containing data of color channels 0...N.\n"
"\nInternal format of the raster image file is determined by its extension.\n"
"Supported formats:");
#ifdef  CONFIG_RASTER_BITMAP
	conPuts("\n\tWindows bitmap (*.bmp)");
#endif  /* CONFIG_RASTER_BITMAP */
#ifdef  CONFIG_RASTER_TARGA
	conPuts("\n\tTrueVision TARGA (*.tga)");
#endif  /* CONFIG_RASTER_TARGA */
#ifdef  CONFIG_RASTER_JPEG
	conPuts("\n\tJPEG (*.jpg) (input only)");
#endif  /* CONFIG_RASTER_JPEG */
	conPuts("\n\n"
"The <colorspace> parameter can be one of the following:\n");
	cspaceListSpaces();
	conPuts(
"\nThe format of IPL object definition:\n"
"<ipl_object_class> <object_name>\n"
"{\n");
	conPrintf(
"\t%s <state_field> <field_value>\n"
"\t%s <state_field> <field_value>\n",
		ipl_key_state,ipl_key_state);
	conPuts(
"\t...\n"
"\t<operation> <argument 1> ... <argument N>\n"
"\t<operation> <argument 1> ... <argument N>\n"
"\t...\n"
"}\n\nwhere\n");
	conPuts(
"\t<state_field> - name of state field to be set to <field_value>;\n"
"\t<operation> - some operation on current data of object.\n"
"\nThe <state_field> may be one of the following:\n");
	stateHelp();
	conPuts("\nThe <ipl_object_class> may be one of the following:\n");
	evalListClasses();
	evalListClassOperations();
	conPrintf("\nValid channel names for matrix \"%s\" operation\n",
		ipl_key_matrix_input);
	cspaceListChannels();
	conPuts("\nFormat of transform definition:\n"
"<ipl_transform_class> <transform_name>(void|[arg1,arg2,...,argN])\n"
"{\n");
	conPrintf(
"\t%s|%s\n"
"\t\t<transform_body>\n"
"\t%s|%s\n",
		ipl_key_step,ipl_key_pass,ipl_key_step,ipl_key_pass);
	conPuts(
"\t\t<transform_body>\n"
"\t...\n"
"}\n"
"\nwhere\n"
"\t<transform_body> - NSL compound statement (see source/examples :(... );\n"
"\t<transform_name> - unique identifier of transform.\n\n");
	conPrintf(
"If the <transform_body> follows \"%s\", it will be executed once;\n",
		ipl_key_step);
	conPrintf(
"if it follows \"%s\", it will be executed for every element of the\n"
"current IPL object.\n",
		ipl_key_pass);
	conPuts(
"\nThe <ipl_transform_class> may be one of the following:\n\n");
	iplListTransformTypes();
	conPuts("\nBuilt-in variables valid for each type of transform:\n");
	iplListBuiltinVariables();
	conPuts("\nBuilt-in constants valid for any transform and function:\n\n");
	iplListBuiltinConstants();
	conPuts("\nFormat of function definition:\n");
	conPrintf("%s <function_name>\n<function_body>\n",ipl_key_function);
	conPuts("\nwhere\n"
"\t<function_name> - unique identifier of function;\n"
"\t<function_body> - NSL compound statement, which should contain\n"
"\t'return' statement (or the assignment to '%' variable).\n\n");
}
