function SimpleGrid($id_prefix, $field_mask, $show_order) {
	this.ItemIDs = new Array ();
	this.NextNumber = 0;
	this.IDPrefix = $id_prefix;
	this.FieldMask = $field_mask;
	this.Container = this.getControl('container');
	this.ShowOrder = $show_order;
}

SimpleGrid.prototype.registerRecord = function ($id) {
	var $prev_id = this.lastID();
	if ($prev_id !== false) {
		this.getControl('button_' + $prev_id).value = '-';
	}

	$id = parseInt($id);
	this.ItemIDs.push($id);

	if ($id < 0 && Math.abs($id) > Math.abs(this.NextNumber)) {
		this.NextNumber = $id;
	}

	if (this.ShowOrder) {
		this.getControl('number_'+$id).innerHTML = this.ItemIDs.length;
	}

	this.processRecordDependancies($id);
}

SimpleGrid.prototype.renumberRecords = function () {
	if (!this.ShowOrder) {
		return ;
	}

	var $me = this;
	var $number = 1;

	$('> div', this.getControl('container')).each(
		function () {
			var $div_id = $(this).attr('id');

			if ( !$div_id.match( new RegExp('^' + $me.IDPrefix + '_(.*)') ) ) {
				return ;
			}

			$('#' + jq($me.IDPrefix + '_number_' + RegExp.$1)).html($number);
			$number++;
		}
	);
}

SimpleGrid.prototype.nextNumber = function () {
	return --this.NextNumber;
}

SimpleGrid.prototype.lastID = function () {
	return this.ItemIDs.length ? this.ItemIDs.slice(this.ItemIDs.length - 1)[0] : false;
}

SimpleGrid.prototype.toggleRecord = function ($item_id) {
	if (this.lastID() == $item_id) {
		this.addRecord();
	}
	else {
		this.removeRecord($item_id);
	}
}

SimpleGrid.prototype.getControl = function ($name) {
	return document.getElementById(this.IDPrefix + '_' + $name);
}

SimpleGrid.prototype.getField = function ($id, $field_name, $prepend, $append) {
	$prepend = isset($prepend) ? $prepend + '_' : '';
	$append = isset($append) ? '_' + $append : '';

	return document.getElementById($prepend + this.FieldMask.replace('#FIELD#', $field_name).replace('#ID#', $id) + $append);
}

SimpleGrid.prototype.markError = function ($item_id, $field_name, $error_found, $error_message) {
	if (!isset($error_found)) {
		$error_found = true;
	}

	var $field = $( this.getField($item_id, $field_name) );

	if ($error_found) {
		$field.css('background-color', '#EF2C2C').attr('title', $error_message === undefined ? '' : $error_message)

		// TODO: duplicate focus events possible on one element, fix this later
		.focus(
			function($e) {
				$(this).css('background-color', '').attr('title', '');
			}
		);
	}
	else {
		$field.css('background-color', '').attr('title', '');
	}
}

SimpleGrid.prototype.validateRecord = function ($item_id) {
	return true;
}

SimpleGrid.prototype.validate = function () {
	var $i = 0;
	var $is_valid = true;
	while ($i < this.ItemIDs.length) {
		if (!this.validateRecord(this.ItemIDs[$i])) {
			$is_valid = false;
		}
		$i++;
	}

	return $is_valid;
}

SimpleGrid.prototype.addRecord = function ($after_item_id) {
	var new_item_number = this.nextNumber();

	var $item_mask = this.getControl('mask').value;
	var $result_html = $item_mask.replace(/#NUMBER#/g, new_item_number);

	var $div = document.createElement('DIV');
	$div.id = this.IDPrefix + '_' + new_item_number;

	if ($after_item_id === undefined) {
		this.getControl('container').appendChild($div);
	}
	else {
		$('#' + jq(this.IDPrefix + '_' + $after_item_id)).after($div);
	}

	$div.innerHTML = $result_html;

	var $js_mask = this.getControl('js_mask').value;
	var result_js = $js_mask.replace(/#NUMBER#/g, new_item_number);
	eval(result_js);

	this.renumberRecords();
	this.updateTotals();
	this.processOddEven();

	return new_item_number;
}

SimpleGrid.prototype.removeRecord = function ($number) {
	var $index = array_search($number, this.ItemIDs);

	if ($index == -1) {
		// don't allow to delete missing rows
		return false;
	}

	this.getControl('container').removeChild( this.getControl($number) );

	this.ItemIDs.splice($index, 1);

	this.renumberRecords();
	this.updateTotals();
	this.processOddEven();

	return true;
}

SimpleGrid.prototype.processOddEven = function () {
	var $me = this,
		$prev_class_name = 'even',
		$next_class_name = 'odd';

	$('> div', this.getControl('container')).each(
		function () {
			var $div_id = $(this).attr('id');

			if ( !$div_id.match( new RegExp('^' + $me.IDPrefix + '_(.*)') ) ) {
				return ;
			}

			$prev_class_name = $next_class_name == 'odd' ? 'even' : 'odd';

			$($me.getControl(RegExp.$1)).removeClass($prev_class_name).addClass($next_class_name);
			$next_class_name = $prev_class_name;
		}
	);
}

SimpleGrid.prototype.removeRecords = function () {
	while (this.ItemIDs.length > 0) {
		var $item_id = this.ItemIDs[this.ItemIDs.length - 1];
		this.removeRecord($item_id);
	}
}

SimpleGrid.prototype.updateTotals = function () {
	// prototype
}

SimpleGrid.prototype.processRecordDependancies = function ($id) {
	// prototype
}

SimpleGrid.prototype.each = function($callback) {
	var $result = null;

	for (var $i = 0; $i < this.ItemIDs.length; $i++) {
		$result = $callback.call(this, this.ItemIDs[$i]);

		if ($result === false) {
			break;
		}
	}
}
