/** @file params.cpp
 *
 *	Definition of program parameters parsing function.
 *
 *	(C) Ceslav Przywara 2008, MFF UK Prague
 *
 */

#include <cstdlib>

#include "config.h"

namespace ace {

/** Performs "safe" conversion from C-string to size_t type.
 *	@param str String to be converted.
 *	@return Unsigned number represented by string or 0, if string does not
 *		represent valid number or is negative.
 */
size_t _ascii2size_t(const char *str) {
	int i = atoi(str);
	return (i < 0) ? 0 : i;
}

void parse_params(int argc, char** argv) {
	for ( int i = 0; i < argc; ++i ) {
		if ( argv[i][0] == '-' ) {
			switch ( argv[i][1] ) {
				case 'c':
					// Context window.
					switch ( argv[i][2] ) {
						case 'f':
							settings::context_filter_file = argv[++i];
							break;
						case 's':
							settings::context_window.mode = ContextWindow::SENTENCE_MODE;
							settings::context_window.radius = _ascii2size_t(argv[++i]);
							break;
//						case 't':
//							settings::context_tag_mask = argv[++i];
//							break;
						case 'w':
							settings::context_window.mode = ContextWindow::WORD_MODE;
							settings::context_window.radius = _ascii2size_t(argv[++i]);
							break;
						case constants::null_char:
							// Output file.
							settings::context_output_file = argv[++i];
							break;
					}					
					break;
				case 'd':
					// Directory with input datafiles.
					settings::dir = argv[++i];
					break;
				case 'f':
					// Morphologic filter...
					switch ( argv[i][2] ) {
						case 's':
							// ...stats (output) filename.
							settings::morphologic_filter_stats_file = argv[++i];
							break;
						case constants::null_char:
							// ...rules (input) filename.
							settings::morphologic_filter_file = argv[++i];
							break;
					}
					break;
				case 'i':
					// Input filename.
					settings::input_file = argv[++i];
					break;
				case 'm':
					// Bitmask for morphologic tags.
					settings::morphologic_tag_mask = argv[++i];
					break;
				case 'n':					
					// N for N-gram.
					settings::n = static_cast<ngram_size_t>(_ascii2size_t(argv[++i]));
					break;
				case 'o':
					// Output filename.
					settings::output_file = argv[++i];
					break;
				case 'p':
					// Output statistics precision.
					settings::precision = _ascii2size_t(argv[++i]);
					break;
				case 's':
					// Stats output filename.
					settings::stats_file = argv[++i];
					break;
				case 't':
					// Threshold (for pre-evaluation or post-evaluation filter)
					switch ( argv[i][2] ) {
						case 'a':
							settings::all_thresholds_together = true;
							break;
						case 'c':
							settings::thresholds.chi_square_test = atof(argv[++i]);
							break;
						case 'e':
							settings::sieves.expected_frequency = atof(argv[++i]);
							break;
						case 'f':
							settings::sieves.frequency = _ascii2size_t(argv[++i]);
							break;
						case 'l':
							settings::thresholds.log_likelihood_ratio = atof(argv[++i]);
							break;
						case 'm':
							settings::thresholds.mutual_information = atof(argv[++i]);
							break;
						case 'o':
							settings::all_thresholds_together = false;
							break;
						case 'p':
							settings::thresholds.pearsons_coefficient = atof(argv[++i]);
							break;
						case 't':
							settings::thresholds.t_test = atof(argv[++i]);
							break;
						case 'z':
							settings::thresholds.z_score = atof(argv[++i]);
							break;
					}
					break;
// TODO: Implement or drop.
//				case 'v':
//					// Verbose.
//					settings::verbose = true;
//					break;
#ifdef _SURFACE_MODE
				case 'w':
					// Collocation window size.
					settings::collocation_window_size = _ascii2size_t(argv[++i]);
					break;
#endif
#ifndef _USE_HASHSET
				case 'x':
					// Performance-related settings.
					switch ( argv[i][2] ) {
						case 'b':
							settings::bucket_size = _ascii2size_t(argv[++i]);
							break;
						case 'c':
							settings::crop_ratio = _ascii2size_t(argv[++i]);
							break;
						case 's':
							settings::sort = (_ascii2size_t(argv[++i]) != 0);
							break;
					}
#endif
				default:
					// TODO: Warn?
					;
			}
		}
	}
}

} // namespace ace
