/*class*/ StorageCookie = function (name/*:String*/, fields/*:Array*/) {
	if (!arguments.length) return;

	this.name = name;
	this.fields = fields;
	this.records = {};

	var value = getCookie(name);
	if (!value) return;

	// Получаем записи из куки.
	var record, id;
	var values = value.split("&");
	while (values.length > 0) {
		record = {};
		for (var i = 0; i < this.fields.length; i++) {
			record[fields[i]] = unescape(values.shift());
		}
		this.records["_" + record.id] = record;
	}
}

/**
 * Вставляет запись, если id существует, то запись не замещается.
 * Возвращает истину, если новая запись вставлена.
 */
StorageCookie.prototype.insert = function (record/*:Record*/)/*:Boolean*/ {
	if (this.records["_" + record.id] != null) return false;
	this.records["_" + record.id] = record;
	return true;
}

/**
 * Вставляет запись, если id существует, то запись замещается.
 */
StorageCookie.prototype.replace = function (record/*:Record*/)/*:Void*/ {
	this.records["_" + record.id] = record;
}

StorageCookie.prototype.getLength = function ()/*:Number*/ {
	var result = 0;
	for (record in this.records) result++;
	return result;
}

/**
 * Удаляет запись с определенным id. Если id не указан, удаляет все.
 */
StorageCookie.prototype.remove = function (id/*:Number*/)/*:Void*/ {
	if (id)
		delete this.records["_" + id]
	else
		this.records = {};
}

/**
 * Возврвщает объект объектов, соответствующих условию,
 * Если id не указан, возвращаются все записи.
 */
StorageCookie.prototype.select = function (id)/*:Object*/ {
	return id ? this.records["_" + id] : this.records;
}

//name, value, seconds, path, domain, secure

StorageCookie.prototype.set = function (path/*:String*/, seconds/*:Number*/, domain/*:String*/, secure)/*:Void*/ {
	var value = "";

	for (recordName in this.records)
		for (var i = 0; i < this.fields.length; i++)
			value += "&" + escape(this.records[recordName][this.fields[i]]);

	setCookie(this.name, value.substring(1), seconds, path, domain, secure);
}

///*****************************************************************************\
//  DataCookie
//
//  Представляет собой нупорядоченное множество однотипных объектов
//  с заранне указанными полями. Напоминает таблицу в релеационной
//  базе данных. Первое поле в таблице обязательно должно быть "id"
//  и быть типа nomber.
//\*****************************************************************************/
//
///*class*/ DataCookie = function (/*string*/ name, /*string[]*/ fields) {
//	this.name = name;
//	this.value = getCookie(name);
//
//	this.records = {};
//
//	if (!this.value) return;
//
//	// Получаем записи из куки.
//	var record, id;
//	var values = this.value.split("&");
//	while (values.length > 0) {
//		record = {};
//		for (var i = 0; i < this.fields.length; i++)
//			record[fields[i]] = unescape(values.shift());
//		this.records["_" + record.id] = record;
//	}
//}
//
///**
// * Вставляет запись, если id существует, то запись не замещается.
// */
///*public boolean*/ DataCookie.prototype.insert = function (/*Record*/ record) {
//	if (this.records["_" + record.id] != null) return false;
//	this.records["_" + record.id] = record;
//	return true;
//}
//
///**
// * Вставляет запись, если id существует, то запись замещается.
// */
///*public void*/ DataCookie.prototype.replace = function (/*Record*/ record) {
//	this.records["_" + record.id] = record;
//}
//
///**
// * Обновляет записи. Функция where одновременно выбирает и обновляет поля.
// */
///*public void*/ DataCookie.prototype.update = function (/*Callback*/ where) {
//	for (record in records) where(record);
//}
//
///*public int*/ DataCookie.prototype.getLength = function () {
//	var result = 0;
//	for (record in records) result++;
//	return result;
//}
//
///**
// * Удаляет записи. Возвращается количество удаленных записей,
// * если null - удаляется все.
// */
///*public int*/ DataCookie.prototype.remove = function (/*callback*/ where) {
//	var length = this.getLength();
//	switch (typeof where) {
//		case 'undefined': this.records = {}; break;
//		case 'string':
//		case 'number':    delete this.records["_" + where]; break;
//		case 'function':  for (record in records) if (where(record)) delete this.records["_" + where]; break;
//		default
//			alert('Wrong type!');
//
//	}
//	return length - this.getLength();
//}
//
///**
// * Возврвщает объект объектов, соответствующих условию,
// * проверяемому в функции [where].
// * function where(object record) {
// *     return boolean ;
// * }
// * Если where не указана, возвращаются все записи.
// */
///*public Record{}*/ DataCookie.prototype.select = function (/*callback*/ where) {
//	switch (typeof where) {
//		case 'undefined': return this.records;
//		case 'string':
//		case 'number':    return this.records["_" + where];
//		case 'function':
//			var result = {};
//			for (record in records) if (where(record)) result["_" + record.id] = record;
//		default
//			alert('Wrong type!');
//	}
//}
//
///*public void*/ DataCookie.prototype.set = function () {
//	var value = "";
//
//	for (record in records)
//		for (field in record)
//			value += "&" + escape(field);
//
//	value = this.value.substring(1);
//	setCookie(this.name,  value); /*TODO*/
//}


var WRONG_INDEX = -1;

function getCookie(name/*:String*/)/*:String*/ {
	var result = document.cookie.match(new RegExp(name + "=([^;]*)"));
	if (result) {
		return result[1];
	} else {
		return "";
	}
}

function setCookie(name/*:String*/, value/*:String*/, seconds/*:Number*/,
		path/*:String*/, domain/*:String*/, secure/*:Boolean*/)/*:Void*/ {
	if (seconds) {
		var expires = new Date;
		expires.setTime(expires.getTime() + seconds * 1000);
	}

	var cookieValue = name + "=" + /*escape(*/value/*)*/ +
			((expires) ? "; expires=" + expires.toGMTString() : "") +
			((path)    ? "; path="    + path                  : "") +
			((domain)  ? "; domain="  + domain                : "") +
			((secure)  ? "; secure"                           : "");

	if (cookieValue.length > 4096) {
		throw "Cookie size more then 4 Kb";
	}

	document.cookie = cookieValue;
}

function deleteCookie(name/*:String*/, path/*:String*/, domain/*:String*/)/*:Void*/ {
	document.cookie = name + "=" +
			((path)   ? "; path="   + path   : "") +
			((domain) ? "; domain=" + domain : "") +
			"; expires=Thu, 01-Jan-70 00:00:01 GMT"
}

var COOKIES_JS = true;