/* ГАДЖЕТ ФАЙЛОВОГО ХРАНИЛИЩА */
function __Filestore(id)
{
//НЕОБХОДИМО СОБЫТИЕ, ВОЗНИКАЮЩЕЕ ПРИ ИЗМЕНЕНИИ this.cName, чтобы менять вид гаджета
	this.lang = Locale.Gadgets.Filestore;
	this.Core = new __StdModuleCore(this, id, 'filestore', this.lang.title, this.lang.desc);
	if(!isEmpty(SProfile.user) && SProfile.user.id)
	{	//пользователь авторизован
		Update.request('Filestore', 'module', 'startup', {id: this.id}, null, true);
		this.finput = {};
		this.fpanel = {};
		this.tabIds = {viewer: this.id +'_fViewer_tab', files: this.id +'_fFile_tab', groups: this.id +'_fGroup_tab'};

		this.current = {
			folder: {id: null, sortBy: 'name', sortOrder: 1},
			viewer: 'list'
		}
		this.constants = {navAreaMinHeight: 50, navAreaMaxHeight: 200}
		this.sortBy = 'name';	//иначе этот параметр внутрь не передать :(
		this.sortOrder = 1;	//иначе этот параметр внутрь не передать :(
		this.declareSortFunctions();	//Функции сортировки, используемые в методах sort повсеместно
		this.preload();
	}
	else
	{//неавторизованным юзерам мы показываем пустышку
        this.Content.innerHTML = '<strong>'+ Locale['AuthNeed'] +'</strong><br><div align="center"><img src="/img/tpl/'+Skin+'/toolbar/register.gif" title="'+ Locale['Registration'] +'" class="href" onclick="Startup.DrawRegisterForm()"><img src="/img/tpl/'+Skin+'/toolbar/login.gif" title="'+ Locale['Enter'] +'" class="href" onclick="Startup.DrawLoginForm()" style="margin-left: 20px"></div>';
	}
}

/**************v Традиционные для гаджетов функции v**/
__Filestore.prototype.Relay = function(data, part)
{
	if(data.variables.errors && data.variables.type=='error' && data.variables.message=='denied')
	{
		window.alert(this.lang.msg['AuthNeedForUse']);
		return;
	}

	switch(data.event.action)
	{
		case 'startup':
			this.current.viewer = data.variables.settings.viewer;
			if(data.variables.settings.cFolder)
				this.current.folder.id = data.variables.settings.cFolder;
			break;

		case 'fileStructure':
			if(data.variables.status && data.variables.status == 'error')
			{
				window.alert(this.lang.msg['ErrorWhenRegister']);
				ModManager.Delete(this.id);
			}
			FSDATA.load(data.variables);
			break;

		case 'createFolder':
			var f = data.variables.folders;
			for(var i in f)
			{
				FSDATA.folders[i] = {
					name: f[i].name,
					parent: f[i].parent,
					created: f[i].created
				}
			}
			this.refreshAll();
			break;

		case 'createSet':
			if(data.variables.status == 'ok')
			{
				this.initFormSets();
			}
			else
			{
				this.reInit();
				window.alert(this.lang.msg['ErrorWhenGroupCreate']);
			}

		case 'moveFolders':
			if(data.variables.status != 'ok')
			{
				this.reInit();
				window.alert(this.lang.msg['ErrorWhenFoldersMove']);
			}
			break;

		case 'moveFiles':
			if(data.variables.status != 'ok')
			{
				this.reInit();
				window.alert(this.lang.msg['ErrorWhenFilesMove']);
			}
			break;

		case 'addBookmark':
			if(data.variables.status == 'ok')
			{
				if(!isEmpty(data.variables.files))
				{
					for(var i in data.variables.files)
					{
						FSDATA.files[i] = data.variables.files[i];
						if(!FSDATA.fStructure[FSDATA.files[i].folderId])
							FSDATA.fStructure[FSDATA.files[i].folderId] = [];
						FSDATA.fStructure[FSDATA.files[i].folderId].push(i);
					}
					this.refresh();
				}
			}
			else
			{
				this.reInit();
				window.alert(this.lang.msg['ErrorWhenLinkAdd']);
			}
			break;

		default:
			break;
	}
}

__Filestore.prototype.onDelete = function()
{
	if(this.workspaceId && Desktop.State.cMain.content[this.workspaceId])
		Desktop.DeleteTabByID('cMain', this.workspaceId);
}

__Filestore.prototype.initTab = function()
{
	if(!this.workspaceId || !Desktop.State.cMain.content[this.workspaceId])
	{
		this.workspaceId = Desktop.NewTab('cMain', 'Файлы', 'filestore', null, null, null)
		var t = Desktop.State.cMain.content[this.workspaceId].content;
		t.style.overflow = 'auto';
		this.workspace = ce('LI', t);
	}
	else
	{
		this.workspace.innerHTML = '';
	}
	Desktop.SetActiveByID('cMain', this.workspaceId);
}

__Filestore.prototype.declareSortFunctions = function()
{
	this.sortFilesAsStr = function(a,b)
	{
	  if (String(a[self.sortBy]) > String(b[self.sortBy]))
		return 1*self.sortOrder;
	  if (String(a[self.sortBy]) < String(b[self.sortBy]))
		return -1*self.sortOrder;
	  return 0;
	}
	this.sortFilesAsNum = function(a,b)
	{
	  if (a[self.sortBy] > b[self.sortBy])
		return 1*self.sortOrder;
	  if (a[self.sortBy] < b[self.sortBy])
		return -1*self.sortOrder;
	  return 0;
	}

	this.fileSortFunctions = {
		'name': this.sortFilesAsStr,
		'ext': this.sortFilesAsStr,
		'size': this.sortFilesAsNum,
		'created': this.sortFilesAsNum
	}
}

/**************v Инициализирующие функции v**/
//(Ре-)Инициализация гаджета
__Filestore.prototype.reInit = function()
{
	FSDATA.init();	//обнуляем хранилище данных
	this.preload();	//и приступаем к загрузке данных
}

//Предварительная загрузка файловой структуры
__Filestore.prototype.preload = function()
{
	var self = this;
	if(!FSDATA.loadComplete)
	{
		if(!FSDATA.loadInProgress)
		{
			FSDATA.loadInProgress = true;
			Update.request('Filestore', 'module', 'fileStructure', {id: self.id}, null, true);
		}
		var timer = window.setInterval(
			function() {
				if(FSDATA.loadComplete)
				{
					window.clearInterval(timer);
					self.start();
				}
			}, 500
		);
	}
	else
		this.start();
}

//Сюда из конструктора переброшены действия, которым необходим флаг structureLoadComplete
__Filestore.prototype.start = function()
{
	this.Options.innerHTML = '';
	this.createPanelSettings();
	this.Content.style.padding = '10px';
	this.createAreaTools();
	this.createAreaNav();
	this.refresh();
}

//Обновление гаджета в случае изменений в файловой структуре
__Filestore.prototype.refresh = function()
{
	var fid = this.current.folder.id;
	this.fpanel.folders.innerHTML = '';
	this.fpanel.files.innerHTML = '';
	this.fSizeInfo();
	this.goToFolder(fid);
	this.setCurrentPath(fid);
}

//Обновляет все родственные гаджеты, включая самого себя
__Filestore.prototype.refreshAll = function()
{
	for(var i in Modules)
	{	//обновляем все гаджеты файлового хранилища
		if(Modules[i].Object.type == this.type)
		{
			Modules[i].Object.refresh();
		}
	}
}

//Устанавливает текущую папку
__Filestore.prototype.setCurrentFolder = function(fid)
{
	if(!fid || fid == 0)
		this.current.folder.id = FSDATA.topFolderId;
	else
		this.current.folder.id = fid;
	this.setCurrentPath();
	Update.request(this.type, 'module', 'changeSettings', {id: this.id}, {cFolder: fid}, false);
}

/**************v Создание управляющих панелей v**/

__Filestore.prototype.createPanelSettings = function()
{
	var self = this;
	this.Tabs = new __Tabs(this.Options, 'gadget');
	this.Tabs.create(this.tabIds.viewer, this.lang['Navigator']);
	this.Tabs.create(this.tabIds.files, this.lang['Files']);
	this.Tabs.create(this.tabIds.groups, this.lang['Sets']);
	this.initFormViewer();
	this.initFormFileUpload();
	this.initFormSets();
	this.Tabs.show(this.tabIds.viewer);
	ce('DIV', this.Options, {innerHTML: '<iframe name="'+ this.id +'_fileDownloadFrame" id="'+ this.id +'_fileDownloadFrame" style="display: none"></iframe>'});
	this.fpanel.frameFileDownload = document.getElementById(this.id +'_fileDownloadFrame');
}

//Создаёт панель инструментов
__Filestore.prototype.createAreaTools = function()
{
	var self = this;
	this.fpanel.tools = ce('DIV', this.Content, null, {marginBottom: '10px'});
	this.fSizeInfo();
	this.fpanel.formSearch = ce('FORM', this.fpanel.tools);
	this.finput.searchQuery = ce('INPUT', this.fpanel.formSearch, {type: 'text'});
	ce('INPUT', this.fpanel.formSearch, {type: 'image', src: '/img/icons/zoom.gif', title: Locale['Search'], align: 'absMiddle'}, {marginLeft: '5px'});
	this.fpanel.search = ce('DIV', this.fpanel.tools, null, {paddingTop: '4px'});
	this.fpanel.formSearch.onsubmit = function()
	{
		if(self.finput.searchQuery.value != '')
			self.search(self.finput.searchQuery.value);
		return false;
	}
}

//Создаёт панель отображения и управления папками и файлами
__Filestore.prototype.createAreaNav = function()
{
	var self = this;
	ce('IMG', this.Content, {src: '/img/filestore/file_add.gif', title: this.lang['ToAddFile'], className: 'href', onclick: function(){self.initFormFileUpload(); self.Options.style.display = '';}}, {marginLeft: '5px', marginRight: '5px'});
	ce('IMG', this.Content, {src: '/img/filestore/folder_add.gif', title: this.lang['ToAddFolder'], className: 'href', onclick: addFolder}, {marginLeft: '5px', marginRight: '5px'});
	ce('IMG', this.Content, {src: '/img/filestore/bookm_add.gif', title: this.lang['ToAddLink'], className: 'href', onclick: function(){self.initFormBookmarkAdd()}}, {marginLeft: '5px', marginRight: '5px'});

	ce('IMG', this.Content, {src: '/img/filestore/f_move.gif', title: Locale['ToMove'], className: 'href', onclick: move});
	ce('IMG', this.Content, {src: '/img/filestore/f_edit.gif', title: Locale['ToRename'], className: 'href', onclick: rename}, {marginLeft: '5px', marginRight: '5px'});
	ce('IMG', this.Content, {src: '/img/filestore/f_del.gif', title: Locale['ToDelete'], className: 'href', onclick: del});

	ce('IMG', this.Content, {src: '/img/filestore/set_add.gif', title: this.lang['ToAddInSet'], className: 'href', onclick: function(e) {self.showMenuAddToSets(e, getChecked())}}, {marginLeft: '10px'});

	this.createAreaPath();
	this.fpanel.nav = ce('DIV', this.Content, null, {border: '1px #00CC00 solid', padding: '5px 0px', width: '99%', margin: '5px 0px', maxHeight: '250px', overflow: 'auto'});
	this.fpanel.folders = ce('DIV', this.fpanel.nav, null, {padding: '0px 10px'});
	this.fpanel.files = ce('DIV', this.fpanel.nav, null, {padding: '0px 10px'});


	function addFolder()
	{
		if(sizeof(FSDATA.folders) > FSDATA.constants.maxFolders)
		{
			window.alert(self.lang.msg['ReachedMaxNumDirs'] +' ('+FSDATA.constants.maxFolders+')');
		}
		var fName = window.prompt(self.lang.msg['EnterDirName'], self.lang['NewFolder']);
		if(fName)
		{
			if(fName.length > FSDATA.constants.maxLenFolderName)
				fName = fName.substr(0, FSDATA.constants.maxLenFolderName);
			Update.request(self.type, 'module', 'createFolder', {id: self.id}, {parentId: self.current.folder.id, name: fName}, true);
		}
	}

	function getChecked()
	{
		var t = self.fpanel.nav.getElementsByTagName('INPUT');
		var folders = [];
		var files = [];
		for(var i=0; i<t.length; i++)
		{
			if(t[i].checked && !t[i].disabled)
			{
				if(t[i].folderId) folders.push(t[i].folderId);
				else if(t[i].fileId) files.push(t[i].fileId);
			}
		}
		return {folders: folders, files: files};
	}

	function del()
	{
		var s = '';
		var obj = getChecked();
		if(obj.folders.length + obj.files.length > 0)
		{
			for(var i=0; i<obj.folders.length; i++)
			{
				if(obj.folders[i] == FSDATA.topFolderId)
				{
					alert(self.lang.msg['NADelTopFolder']);
					return;
				}
			}
			if(window.confirm(self.lang.msg['DeleteTheseObjs']))
			{
				//сервер пусть сам разбирается, что и как лучше удалять
				Update.request(self.type, 'module', 'delFnF', {id: self.id}, {folders: obj.folders, files: obj.files}, true);
				var reserveFolder = FSDATA.folders[self.current.folder.id].parent;
				if(obj.files.length) self.deleteFiles(obj.files);
				if(obj.folders.length) self.deleteFolders(obj.folders);
				if(!FSDATA.folders[self.current.folder.id])
					self.setCurrentFolder(reserveFolder);
				self.refresh();
				self.updateSets();
			}
		}
		else
		{
			window.alert(self.lang.msg['NotSelectedObjForDel']);
		}
	}

	function move(e)
	{
		var obj = getChecked();
		if(obj.folders.length + obj.files.length < 1)
		{
			window.alert(self.lang.msg['NotSelectedObjForMove']);
		}
		else
		{
			self.showPanelTree({
				e: e,
				type: 'move',
				title: self.lang.msg['MoveObjsTo'],
				oParent: self.Content,
				data: {folders: obj.folders, files: obj.files},
				fsubmit: function(oThis, data) {
					var t = oThis.getElementsByTagName('INPUT');
					for(var i=0; i<t.length; i++)
					{
						if(t[i].type == 'radio' && t[i].checked)
						{
							Update.request('Filestore', 'module', 'move', {id: self.id}, {toF: t[i].fid, folders: data.folders, files: data.files}, true);
							for(var j=0; j<data.files.length; j++)
							{	//перемещаем файлы
								var tmp = FSDATA.fStructure[FSDATA.files[data.files[j]].folderId];
								for(var k=0; k<tmp.length; k++)
								{
									if(tmp[k] == data.files[j])
									{
										tmp.splice(k, 1);	//удаляем файл из ветки прошлой папки
										break;
									}
								}
								if(!FSDATA.fStructure[t[i].fid])
									FSDATA.fStructure[t[i].fid] = [];
								FSDATA.fStructure[t[i].fid].push(data.files[j]);
								FSDATA.files[data.files[j]].folderId = t[i].fid;
							}

							for(var j=0; j<data.folders.length; j++)
							{
								//перемещаем папки
								FSDATA.folders[data.folders[j]].parent = t[i].fid;
							}

							self.refresh();
							break;
						}
					}
					}
			});
		}
	}

	function rename()
	{
		var obj = getChecked();
		var k = obj.folders.length + obj.files.length;
		if(k > 1)
		{
			window.alert(self.lang.msg['ForRenameSelectOnlyOneObj']);
		}
		else if(k==0)
		{
			window.alert(self.lang.msg['NotSelectedObjForRename']);
		}
		else if(obj.folders.length>0)
		{
			var fName = window.prompt(self.lang.msg['EnterNewDirName'], FSDATA.folders[obj.folders[0]].name);
			if(fName && fName != FSDATA.folders[obj.folders[0]].name)
			{
				if(fName.length > FSDATA.constants.maxLenFolderName)
					fName = fName.substr(0, FSDATA.constants.maxLenFolderName);
				FSDATA.folders[obj.folders[0]].name = fName;
				Update.request(self.type, 'module', 'renameFolder', {id: self.id}, {id: obj.folders[0], name: fName}, true);
				self.refresh();
			}
		}
		else if(obj.files.length>0)
		{
			var tmp = FSDATA.files[obj.files[0]].name +'.'+ FSDATA.files[obj.files[0]].ext;
			var fName = window.prompt(self.lang.msg['EnterNewFileName'], tmp);
			if(fName)
			{
				var fTitle = window.prompt(self.lang.msg['NewFileDesc'], FSDATA.files[obj.files[0]].title);
				if(fName != tmp || fTitle != FSDATA.files[obj.files[0]].title)
				{
					var ar = self.parseFileName(fName);
					if(ar[0].length > FSDATA.constants.maxLenFileName)
						ar[0] = ar[0].substr(0, FSDATA.constants.maxLenFileName);
					if(ar[1].length > FSDATA.constants.maxLenFileExt)
						ar[1] = ar[1].substr(0, FSDATA.constants.maxLenFileExt);
					if(fTitle && fTitle.length > FSDATA.maxLenFileTitle)
						fTitle = fTitle.substr(0, FSDATA.maxLenFileTitle);
					FSDATA.files[obj.files[0]].name = ar[0];
					FSDATA.files[obj.files[0]].ext = ar[1];
					FSDATA.files[obj.files[0]].title = fTitle;
					Update.request(self.type, 'module', 'renameFile', {id: self.id}, {id: obj.files[0], name: ar[0], ext: ar[1], title: fTitle}, true);
					self.refresh();
					self.updateSets();
				}
			}
		}
	}

}

//Создаёт панель "хлебных крошек"
__Filestore.prototype.createAreaPath = function()
{
	this.fpanel.path = ce('DIV', this.Content, null, {marginTop: '5px', paddingLeft: '12px', background: 'url(/img/icons/blt1.gif) no-repeat top', backgroundPosition: '0px 2px'});
}

/**************v Формы управления файловым хранилищем и их обработка v**/

//Форма опций навигатора
__Filestore.prototype.initFormViewer = function()
{
	var self = this;
	this.finput.formViewer = {};
	this.fpanel.formViewer = ce('FORM', this.Tabs.data[this.tabIds.viewer].content);
	this.fpanel.formViewer.innerHTML = '<input type="radio" name="'+ self.id +'_viewerType" id="'+ self.id +'_viewerType1"/> '+ Locale['List'] +'<br/><input type="radio" name="'+ self.id +'_viewerType" id="'+ self.id +'_viewerType2"/> '+ Locale['Tree'] +'<br/>'
	this.finput.formViewer.asList = document.getElementById(self.id +'_viewerType1');
	this.finput.formViewer.asTree = document.getElementById(self.id +'_viewerType2');
	if(this.current.viewer == 'tree')
		this.finput.formViewer.asTree.checked = true;
	else
		this.finput.formViewer.asList.checked = true;
/*	self.finput.formViewer.asTypes = ce('INPUT', this.fpanel.formViewer, {type: 'radio', name: self.id+'_viewerType'});
	ce('SPAN', this.fpanel.formViewer, {innerHTML: ' Тематически<br/>'});
*/	ce('INPUT', this.fpanel.formViewer, {type: 'submit', value: 'OK', className: 'std_button'});
	self.fpanel.formViewer.onsubmit = function()
	{
		if(self.finput.formViewer.asList.checked)
		{
			self.current.viewer = 'list';
			self.showFoldersByList(self.current.folder.id);
		}
		else if(self.finput.formViewer.asTree.checked)
		{
			self.current.viewer = 'tree';
			self.showFoldersTree(self.current.folder.id, self.fpanel.folders);
		}
		Update.request(self.type, 'module', 'changeSettings', {id: self.id}, {viewer: self.current.viewer}, false);
		return false;
	}
}

//Форма загрузки файлов
__Filestore.prototype.initFormFileUpload = function(folderId)
{
	var self = this;
	this.Tabs.data[this.tabIds.files].content.innerHTML = '<form method="post" enctype="multipart/form-data" target="'+ this.id +'_fileUploadFrame" action="/gateway/filestore/upload_files.php" id="'+ this.id +'_fileUploadForm" style=""><iframe name="'+ this.id +'_fileUploadFrame" id="'+ this.id +'_fileUploadFrame" style="display: none;"></iframe></form>';
	this.fpanel.formFileUpload = document.getElementById(this.id +'_fileUploadForm');

//	this.fpanel.formFileUpload = ce('FORM', this.Tabs.data[this.tabIds.files].content, {method: 'post', 'enctype': 'multipart/form-data', target: this.id+'_fileUploadFrame', action: '/gateway/filestore/upload_files.php'}, {display: 'none'});
	this.fpanel.frameFileUpload = document.getElementById(this.id +'_fileUploadFrame');

	this.finput.fileUpload = {} ;	//хранилище объектов формы закачки файлов
	ce('H4', this.fpanel.formFileUpload, {innerHTML: this.lang['FileUploading']});
	this.finput.fileUpload.folderId = ce('INPUT', this.fpanel.formFileUpload, {type: 'hidden', name: 'folder_id'});
	this.finput.fileUpload.file = ce('INPUT', ce('DIV', this.fpanel.formFileUpload, null, {width: '80px'}), {type: 'file', name: 'testfile'});
	this.finput.fileUpload.file.onchange = function()
	{
		var ar = self.parseFileName(this.value);
		self.finput.fileUpload.fileTitle.value = ar[0];
		self.finput.fileUpload.fileName.value = ar[0];
		if(ar[1])
			self.finput.fileUpload.fileExt.value = ar[1];
		else
			self.finput.fileUpload.fileExt.value = '';
	}
	ce('SPAN', this.fpanel.formFileUpload, {innerHTML: '<br/>'+ this.lang['FileName'] +':<br/>'});
	this.finput.fileUpload.fileName = ce('INPUT', this.fpanel.formFileUpload, {type: 'text', name: 'file_name', maxLength: '63'}, {width: '150px'});
	ce('SPAN', this.fpanel.formFileUpload, {innerHTML: '.'});
	this.finput.fileUpload.fileExt = ce('INPUT', this.fpanel.formFileUpload, {type: 'text', name: 'file_ext', maxLength: '15'}, {width: '25px'});
	ce('SPAN', this.fpanel.formFileUpload, {innerHTML: '<br/>'+ this.lang['FileTitle'] +': '});
	this.finput.fileUpload.fileTitle = ce('INPUT', this.fpanel.formFileUpload, {type: 'text', name: 'file_title'})
	ce('SPAN', this.fpanel.formFileUpload, {innerHTML: '<br/>'});
	ce('INPUT', this.fpanel.formFileUpload, {type: 'hidden', name: 'gadget_id', value: this.id});
	this.fpanel.fileUploadIndicator = ce('DIV', this.fpanel.formFileUpload, null, {margin: '6px', display: 'none'});
	ce('IMG', this.fpanel.fileUploadIndicator, {src: '/img/actions/loading.gif'});
	ce('INPUT', this.fpanel.formFileUpload, {type: 'submit', value: Locale['ToUpload'], className: 'std_button'});

	this.Tabs.show(this.tabIds.files);

	//предварительные действия перед отправкой данных серверу
	this.fpanel.formFileUpload.onsubmit = function()
	{
		if(FSDATA.fCommonSize > (FSDATA.fCommonSizeQuota-10))
		{
			window.alert(self.lang.msg['ReachedLimitQuota']);
			return false;
		}
		self.finput.fileUpload.folderId.value = self.current.folder.id;
		self.fpanel.fileUploadIndicator.style.display = '';
		return true;
	}
}

//Обрабатывает результаты закачки файла, полученные от сервера
__Filestore.prototype.processAnswerFileUpload = function(fileObj, errs)
{
	this.fpanel.fileUploadIndicator.style.display = 'none';
//	this.fpanel.formFileUpload.style.display = 'none';
	if(fileObj)
	{
		//'Файл успешно загружен.';
		FSDATA.files[fileObj.id] = fileObj;
		if(!FSDATA.fStructure[fileObj.folderId])
			FSDATA.fStructure[fileObj.folderId] = [];
		FSDATA.fStructure[fileObj.folderId].push(fileObj.id);
		this.refreshAll();
		window.alert(this.lang.msg['FileUploaded']);
	}
	if(!isEmpty(errs))
		for(var i in errs)
			window.alert(errs[i]);
}

//Форма добавления ссылок
__Filestore.prototype.initFormBookmarkAdd = function()
{
	var self = this;
	this.Tabs.data[this.tabIds.files].content.innerHTML = '';

	var defaultUrl = 'http://www.krozilo.com/';
	this.finput.bookmark = {};
	this.fpanel.formBookmarkAdd = ce('FORM', this.Tabs.data[this.tabIds.files].content, null);
	ce('H4', this.fpanel.formBookmarkAdd, {innerHTML: this.lang['ToAddLink']});
	this.finput.bookmark.url = ce('INPUT', this.fpanel.formBookmarkAdd, {type: 'text', maxLength: 255, defaultValue: defaultUrl, onfocus: function(){if(this.value==defaultUrl) this.value='';}});
	ce('SPAN', this.fpanel.formBookmarkAdd, {innerHTML: '<br/>'+ Locale['Title'] +': '});
	this.finput.bookmark.title = ce('INPUT', this.fpanel.formBookmarkAdd, {type: 'text', maxLength: 127});
	ce('SPAN', this.fpanel.formBookmarkAdd, {innerHTML: '<br/>'+ Locale['Description'] +': '});
	this.finput.bookmark.desc = ce('INPUT', this.fpanel.formBookmarkAdd, {type: 'text', maxLength: 255});
	ce('INPUT', this.fpanel.formBookmarkAdd, {type: 'submit', value: 'OK', className: 'std_button'});

	this.Options.style.display = '';
	this.Tabs.show(this.tabIds.files);

	this.fpanel.formBookmarkAdd.onsubmit = function()
	{
		Update.request(self.type, 'module', 'addBookmark', {id: self.id}, {folderId: self.current.folder.id, url: self.finput.bookmark.url.value, title: self.finput.bookmark.title.value, desc: self.finput.bookmark.desc.value}, true);
		return false;
	}
}

/**************v Традиционные операции с файлами и папками v**/

//Удаляет файлы по массиву id. Обращение к серверу не выполняет
__Filestore.prototype.deleteFiles = function(files)
{
	for(var i=0; i<files.length; i++)
	{
		if(FSDATA.fStructure[FSDATA.files[files[i]].folderId])
		for(var j=0; FSDATA.fStructure[FSDATA.files[files[i]].folderId].length; j++)
		{
			if(FSDATA.fStructure[FSDATA.files[files[i]].folderId][j] == files[i])
			{
				FSDATA.fStructure[FSDATA.files[files[i]].folderId].splice(j, 1);
				break;
			}
		}
		if(FSDATA.files[files[i]])
			delete FSDATA.files[files[i]];
		de(document.getElementById(this.id +'_fileItem_'+ files[i]));
	}
}

//Удаляет папки по массиву id. Обращение к серверу не выполняет
__Filestore.prototype.deleteFolders = function(folders)
{
	for(i=0; i<folders.length; i++)
	{
		if(FSDATA.folders[folders[i]])
		{
			delete FSDATA.folders[folders[i]];
		}
		if(FSDATA.fStructure[folders[i]])
		{
			for(var j=0; j<FSDATA.fStructure[folders[i]].length; j++)
			{
				delete FSDATA.files[FSDATA.fStructure[folders[i]][j]];
			}
			delete FSDATA.fStructure[folders[i]];
		}
	}
}

//Ищет файлы и папки
__Filestore.prototype.search = function(q)
{
	var self = this;
	this.fpanel.search.innerHTML = '';	//НАДО ДОБАВИТЬ КЭШ!!!!!
	var oTbody = ce('TBODY', ce('TABLE', this.fpanel.search));
	var regx = new RegExp();
	regx.compile('.*?'+q+'.*', 'i');

	for(var i in FSDATA.folders)
	{
		var n = FSDATA.folders[i].name.search(regx);
		if(n > -1)
		{
			var oTr = ce('TR', oTbody);
			ce('IMG', ce('TD', oTr), {src: '/img/filestore/fold.gif'});
			ce('SPAN', ce('TD', oTr), {className: 'href', innerHTML: FSDATA.folders[i].name, fid: i, onclick: toFolder});
		}
	}
	for(i in FSDATA.files)
	{
		if(!FSDATA.files[i].name) continue;
		n = FSDATA.files[i].name.search(regx);
		if(n > -1)
		{
			var oTr = ce('TR', oTbody);
			ce('IMG', ce('TD', oTr), {src: '/img/filestore/file.gif'});
			ce('SPAN', ce('TD', oTr), {className: 'href', innerHTML: FSDATA.files[i].name, fid: FSDATA.files[i].folderId, onclick: toFolder});
		}
	}

	function toFolder()
	{
		self.showFoldersByList(this.fid);
	}
}

/**************v Навигация v**/

//Переход к указанной папке с учётом типа навигатора
__Filestore.prototype.goToFolder = function(folderId)
{
	if(!FSDATA.folders[folderId])
		folderId = FSDATA.topFolderId;
	switch(this.current.viewer)
	{
		case 'list':
			this.showFoldersByList(folderId);
			break;
		case 'tree':
			if(folderId != this.current.folder.id)	//необходимо для различия первичной загрузки и перехода по "хлебным крошкам"
				this.setCurrentFolder(folderId);
			this.showFoldersTree(folderId, this.fpanel.folders);
			break;
	}
	resizeBlockByContent(this.fpanel.nav, this.constants.navAreaMinHeight, this.constants.navAreaMaxHeight);
}

//Отображает список папок на основе линейного представления дерева каталогов из БД
__Filestore.prototype.showFoldersByList = function(parentId)
{
	var self = this;

	this.fpanel.folders.innerHTML = '';
	this.setCurrentFolder(parentId);

	//Строим линейное представление одного уровня от заданной папки-родителя; необходим, в сущности, для организации сортировки папок
	var list = [];
	for(var fid in FSDATA.folders)
	{
		if(FSDATA.folders[fid].parent == parentId)
		{
			list.push({
				id: fid,
				name: FSDATA.folders[fid].name,
				parent: FSDATA.folders[fid].parent,
				created: FSDATA.folders[fid].created
			});
		}
	}

	var oTbody = ce('TBODY', ce('TABLE', this.fpanel.folders));
	if(FSDATA.folders[parentId])
	{	//навигация на уровень выше
		var oTr = ce('TR', oTbody);
		var oTd = ce('TD', oTr, {colSpan: 3}, {verticalAlign: 'middle'});
		ce('IMG', oTd, {src: '/img/filestore/fold_up.gif', className: 'href', title: Locale['Upward'], fid: FSDATA.folders[parentId].parent, onclick: toFolder});
		ce('SPAN', oTd, {className: 'href', title: 'наверх', fid: FSDATA.folders[parentId].parent, onclick: toFolder, innerHTML: '..'});
	}

	this.sortBy = this.current.folder.sortBy;
	this.sortOrder = this.current.folder.sortOrder;
	list.sort(this.fileSortFunctions[this.sortBy]);

	for(var i=0; i<list.length; i++)
	{
		oTr = ce('TR', oTbody);
		ce('INPUT', ce('TD', oTr, null, {paddingRight: '5px', verticalAlign: 'middle'}), {type: 'checkbox', folderId: list[i].id}, {margin: '0px'});
		ce('IMG', ce('TD', oTr, null, {paddingRight: '5px', verticalAlign: 'middle'}), {src: '/img/filestore/fold.gif'});
		var t = ce('SPAN', ce('TD', oTr, null, {verticalAlign: 'middle', padding: '2px 0px'}), {fid: list[i].id, className: 'href', innerHTML: list[i].name, onclick: toFolder});
		if(parentId==0) t.style.fontWeight = 'bold';
	}
	this.showFilesByFolder(parentId, this.fpanel.files);
	resizeBlockByContent(this.fpanel.nav, this.constants.navAreaMinHeight, this.constants.navAreaMaxHeight);

	function toFolder()
	{
		self.showFoldersByList(this.fid);
	}
}

//Строит дерево каталогов
__Filestore.prototype.showFoldersTree = function(fid, oParent, deepFid)
{
	var self = this;
	if(fid == FSDATA.topFolderId)
	{
		this.fpanel.folders.innerHTML = '';
		this.fpanel.files.innerHTML = '';
		var Li = ce('LI', ce('UL', this.fpanel.folders), {folderId: fid});
		ce('INPUT', Li, {type: 'checkbox', align: 'absMiddle', folderId: fid, onchange: folderMark}, {marginRight: '5px'});
		ce('IMG', Li, {src: '/img/filestore/fold_op.gif', align: 'absMiddle'}, {marginRight: '5px'});
		var selectedHrefFolder = ce('SPAN', Li, {id: 'folderInTree_'+ fid, fid: fid, open: true, className: 'href', innerHTML: FSDATA.folders[fid].name, onclick: folderClick}, {fontWeight: 'bold'});
//		this.setCurrentFolder(fid);	//Ы?
		oParent = Li;
	}
	else if(!oParent.folderId || oParent.folderId != fid)	//мы либо ввообще в голом DIV, либо ещё не достигли родителя
	{	//если мы в процессе первоначального построения дерева, а передана как текущая одна из глубоко заложенных папок
		if(!deepFid)
		{
			deepFid = fid;	//это первый заход в рекурсии; deepFid будет содержать целевую "глубинную" папку
			if(!oParent.folderId) this.showFoldersTree(FSDATA.topFolderId, oParent, deepFid);
			return;
		}
	}
	if(deepFid && deepFid != fid)
		var deepFidCParent = getDeepFolderCurrentParent(deepFid);
	var UL = ce('UL', oParent, null, {marginLeft: '15px'});
	var LIs = {};

	//С помощью двух вспомогательных одномерных хранилищ обходимся всего лишь одной итерацией по FSDATA.folders
	for(var i in FSDATA.folders)
	{
		if(FSDATA.folders[i].parent != fid) continue;
		LIs[i] = ce('LI', UL, {folderId: i});
		LIs[i].sortf = FSDATA.folders[i][this.current.folder.sortBy];	//поле, по которому будем сортировать
		//элемент порождён. осталось привязать его к родительскому списку UL, с учётом сортировки
		var tmp = UL.childNodes;

		//что ж, пока используем простейший туповатенький способ; вполне, впрочем, может оказаться, что он и есть оптимальный
		var m = tmp.length-1;	//просто для изъятия операции tmp.length-1 в каждой итерации
		if(tmp.length == 0)
		{
			UL.appendChild(LIs[i]);
		}
		else if(this.current.folder.sortOrder >= 0)	//удивительно, но ничего умнее такого ветвления мне в голову не пришло :)
		{
			for(var j=0; j<tmp.length; j++)
			{
				if(LIs[i].sortf <= tmp[j].sortf)
				{
					UL.insertBefore(LIs[i], tmp[j]);
					break;
				}
				if(j == m)
					UL.appendChild(LIs[i]);	//мы в конце массива, условие ни разу не выполнилось
			}
		}
		else	//просто обратный порядок сортировки; массив обходим с конца
		{
			for(var j=m; j>=0; j--)
			{
				if(LIs[i].sortf >= tmp[j].sortf || j == 0)
				{
					if(j != m)
						UL.insertBefore(LIs[i], tmp[j+1]);
					else
						UL.appendChild(LIs[i]);	//мы в конце массива
					break;
				}
			}
		}

		var f = null;
		ce('INPUT', LIs[i], {type: 'checkbox', folderId: i, onchange: folderMark}, {marginRight: '5px'});
		ce('IMG', LIs[i], {src: '/img/filestore/fold.gif'}, {marginRight: '5px'});
		var oHref = ce('SPAN', LIs[i], {id: 'folderInTree_'+ i, fid: i, open: false, className: 'href', innerHTML: FSDATA.folders[i].name, onclick: folderClick});
		if((this.current.folder.id == i) || (deepFidCParent && deepFidCParent == i))
			folderClick(null, oHref);
	}
	//выводим файлы данной папки
	this.showFilesByFolder(fid, ce('LI', UL));
	resizeBlockByContent(this.fpanel.nav, this.constants.navAreaMinHeight, this.constants.navAreaMaxHeight);

	function folderClick(e, obj)
	{
	/*
	Клик по папке:
		- прежняя текущая папка перестаёт быть выделенной жирным, её свойство раскрытости закрытости остаётся не тронутым
		- папка становится текущей, выделяется жирным
		- отображаются или уничтожаются дочерние ветви, инвертируется свойство open и иконка папки
	*/
		var t = null;
		if(t = document.getElementById('folderInTree_'+ self.current.folder.id))
			t.style.fontWeight = 'normal';
		if(t = document.getElementById('folderInTree_'+ fid))
			t.style.fontWeight = 'normal';

		if(!obj)
		{
			var obj = this;	//если функция вызвана не сторонним объектом, а прямым событием onclick
			deepFid = null;
//			if(!obj.open)
			self.setCurrentFolder(obj.fid);
		}

		if(!obj.open)
		{	//папка была закрыта
			obj.open = true;
			if(!deepFid) deepFid = null;
			self.showFoldersTree(obj.fid, obj.parentNode, deepFid);
			if(obj.previousSibling)
				obj.previousSibling.src = '/img/filestore/fold_op.gif';
		}
		else
		{	//была открыта
			obj.open = false;
			var tmp = obj.parentNode.getElementsByTagName('UL');
			for(var i=0; i<tmp.length; i++)
			{
				de(tmp[i]);
			}
			obj.previousSibling.src = '/img/filestore/fold.gif';
		}

		if(obj.fid == self.current.folder.id)
		{
			obj.style.fontWeight = 'bold';
		}
//		self.showFilesByFolder(obj.fid);
		return false;
	}

	function folderMark()
	{
		var t = this.parentNode.getElementsByTagName('INPUT');
		for(var i=0; i<t.length; i++)
		{
			if(t[i].folderId && t[i].folderId == this.folderId) continue; //попали на текущий
			if(this.checked == true)
			{
//				t[i].checked = false;
				t[i].disabled = true;
			}
			else
			{
				t[i].disabled = false;
			}
		}
	}

	function getDeepFolderCurrentParent(fid)	//текущий (пра-)родитель папки deepFid
	{
		if(oParent.folderId == FSDATA.folders[fid].parent)
			return fid;
		else
			return getDeepFolderCurrentParent(FSDATA.folders[fid].parent);
	}
}

//Отображает список файлов для указанной папки
__Filestore.prototype.showFilesByFolder = function(folderId, oDiv)
{
	var self = this;
	if(!oDiv) oDiv = this.fpanel.files;
	oDiv.innerHTML = '';
	this.fpanel.filesList = ce('TBODY', ce('TABLE', oDiv));

	if(!FSDATA.fStructure[folderId]) return false;

	this.sortBy = this.current.folder.sortBy;
	this.sortOrder = this.current.folder.sortOrder;
	FSDATA.fStructure[folderId].sort(this.fileSortFunctions[this.current.folder.sortBy]);	//сортируем файлы по нужному критерию

	for(var i=0; i<FSDATA.fStructure[folderId].length; i++)
	{
		this.printFileItem(FSDATA.fStructure[folderId][i]);
	}
}

//Показывает элемент списка с информацией об очередном файле
__Filestore.prototype.printFileItem = function(fileId)
{
	var self = this;
	var fnameLength = 20;
	var oTr = ce('TR', this.fpanel.filesList, {id: this.id +'_fileItem_'+ fileId});
	ce('INPUT', ce('TD', oTr, null, {paddingRight: '5px', verticalAlign: 'middle'}), {type: 'checkbox', fileId: fileId}, {margin: '0px'});
	switch(FSDATA.files[fileId].kind)
	{
		case 'custom':
			var fname = FSDATA.files[fileId].name;
			if(fname.length > fnameLength) fname = fname.substr(0, fnameLength-3) +'...';
			ce('A', ce('TD', oTr, null, {padding: '2px 5px 2px 0px', verticalAlign: 'middle'}), {href: '#', fid: fileId, title: FSDATA.files[fileId].title, innerHTML: fname +'.'+ FSDATA.files[fileId].ext,
				href: '/gateway/filestore/download_files.php?fid='+fileId,
				target: this.id +'_fileDownloadFrame',
				oncontextmenu: fileHrefOncontext
			});
			ce('SMALL', ce('TD', oTr, null, {paddingRight: '5px', verticalAlign: 'middle'}), {innerHTML: ' <em>('+ FSDATA.formatFileSize(FSDATA.files[fileId].size) +')</em>'});
			var oHrefDDrop = new __DDrop(true, 'horizontal');
			//oHrefDDrop.AddContainer(this.workspace.id);
			//oHrefDDrop.AddItem(this.id +'_fileHref'+ fileId);
			break;
		case 'url':
			var fname = FSDATA.files[fileId].title;
			if(fname.length > fnameLength) fname = fname.substr(0, fnameLength-3) +'...';
			ce('A', ce('TD', oTr, null, {padding: '2px 5px 2px 0px', verticalAlign: 'middle'}), {href: FSDATA.files[fileId].url, target: '_blank', fid: fileId, title: FSDATA.files[fileId].desc, innerHTML: fname});
			ce('SMALL', ce('TD', oTr, null, {verticalAlign: 'middle'}), {innerHTML: ' <em>(html)</em>'});
			break;
		case 'mail':
			break;
	}

/*
	function fileHrefOnclick()
	{
		self.fpanel.frameFileDownload.src = '/gateway/filestore/download_files.php?fid='+this.fid;
		return false;
	}
*/
	function fileHrefOncontext()
	{
//		console.info('Must be menu!');
		return false;
	}
}

//Строит дерево каталогов в выпадающей панели
__Filestore.prototype.showPanelTree = function(oData)
{
/* Объект oData содержит в себе всеразличные параметры, универсализирующие применимость функции:
- e: встроенный объект Event, на который вешается выпад панели
- type: тип применения панели;
	несмотря на всё удобство объекта oData (он лишь позволяет не создавать в данной функции не используемые подфункции и тотальные условия),
	для некоторых участков кода всё же придётся сделать ветвление
- title: заголовок панели
- oParent: родительский объект DOM, в котором мы порождаем панель
- fsubmit: функция на сабмит формы
- data: произвольные данные, которые относятся только к одному типу
*/
	var self = this;

	var oForm = ce('FORM', oData.oParent, null, {position: 'absolute', left: Event.pointerX(oData.e)+'px', top: Event.pointerY(oData.e)+'px', width: '200px', height: '400px', border: '2px solid #992222', backgroundColor: '#EEEEEE', overflow: 'scroll', padding: '5px'});

	switch(oData.type)
	{
		case 'toSet':
			var folders = FSDATA.groups;
			oForm.sid = oData.data.sid;
			break;
		case 'move':
			var folders = FSDATA.folders;
			break;
	}

	ce('IMG', oForm, {src: '/img/icons/x.gif', className: 'href', onclick: function() {de(oForm);}}, {position: 'absolute', right: '10px'});
	ce('H4', oForm, {innerHTML: oData.title}, {width: '150px'});
	ce('INPUT', oForm, {type: 'submit', value: Locale['OK'], className: 'std_button'});

	var ULs = {0: ce('UL', oForm)};

	var LIs = {};
	var selectedHrefFolder = null;	//хранит выделенную ссылку-папку для последующего снятия "выделения"

	for(var i in folders)
	{
		if(!ULs[folders[i].parent])
			ULs[folders[i].parent] = ce('UL', LIs[folders[i].parent], {className: 'tree'});
		LIs[i] = ce('LI', null, null);
		LIs[i].sortf = folders[i][this.current.folder.sortBy];
		var tmp = ULs[folders[i].parent].childNodes;

		var m = tmp.length-1;
		if(tmp.length == 0)
		{
			ULs[folders[i].parent].appendChild(LIs[i]);
		}
		else if(this.current.folder.sortOrder >= 0)
		{
			for(var j=0; j<tmp.length; j++)
			{
				if(LIs[i].sortf <= tmp[j].sortf)
				{
					ULs[folders[i].parent].insertBefore(LIs[i], tmp[j]);
					break;
				}
				if(j == m)
					ULs[folders[i].parent].appendChild(LIs[i]);
			}
		}
		else
		{
			for(var j=m; j>=0; j--)
			{
				if(LIs[i].sortf >= tmp[j].sortf || j == 0)
				{
					if(j != m)
						ULs[folders[i].parent].insertBefore(LIs[i], tmp[j+1]);
					else
						ULs[folders[i].parent].appendChild(LIs[i]);
					break;
				}
			}
		}

		ce('INPUT', LIs[i], {type: 'radio', name: 'tree', fid: i}, {marginRight: '5px'});
		ce('IMG', LIs[i], {src: '/img/filestore/fold.gif'}, {marginRight: '5px'});
		ce('SPAN', LIs[i], {innerHTML: folders[i].name});

		switch(oData.type)
		{
			case 'toSet':
				ce('IMG', LIs[i], {className: 'href', src: '/img/filestore/fold_add.gif', title: self.lang['NewGroup'], onclick: function() {window.prompt(self.lang.msg['EnterNewGroupName'], self.lang['NewGroup']);}}, {marginLeft: '10px'});
				break;
			case 'move':
				break;
		}
	}

	oForm.onsubmit = function() {oData.fsubmit(this, oData.data); return false;};

}

//Выводит или обновляет информацию о размерах файлов
__Filestore.prototype.fSizeInfo = function()
{
	FSDATA.fCommonSizeCalculate();
	var levelColors = ['#00F300', '#C9F300', '#F3F100', '#F3A200', '#F30000'];	//цвета уровня заполненности квоты
	if(!this.fpanel.fSizeInfo) this.fpanel.fSizeInfo = ce('DIV', this.fpanel.tools, {align: 'right'});
	else this.fpanel.fSizeInfo.innerHTML = '';
	ce('SMALL', this.fpanel.fSizeInfo, {innerHTML: FSDATA.formatFileSize(FSDATA.nums.fCommonSize) +' '+ this.lang['FSizeOf'] +' '+ FSDATA.formatFileSize(FSDATA.constants.fCommonSizeQuota)});
	var t1 = ce('DIV', this.fpanel.fSizeInfo, null, {width: '40%', height: '5px', overflowY: 'hidden', backgroundColor: '#DDDDEE', border: '#BBBBBB 1px solid', textAlign: 'left'});

	var prc = Math.round(FSDATA.nums.fCommonSize / FSDATA.constants.fCommonSizeQuota * 100);
	var k = Math.floor((prc-1) / Math.floor(100 / levelColors.length))
	if(k > levelColors.length-1) k--;
	else if(k<0) k++;
	ce('DIV', t1, null, {width: prc+'%', height: '5px', backgroundColor: levelColors[k]});
}

//Парсит имя файла и возвращает массив {0 => имя, 1 => расширение}
__Filestore.prototype.parseFileName = function(path)
{
	var ar = ['',''];
	var t = /([^\\\/\.]*)(\.[^\\\/\.]*)?$/.exec(path);
	if(t[1]) ar[0] = t[1];
	if(t[2]) ar[1] = t[2].substr(1);
	return ar;
}

//Выводит/актализирует "хлебные крошки"
__Filestore.prototype.setCurrentPath = function()
{
	var self = this;
	var ar = [];
	this.fpanel.path.innerHTML = '';
	fillAr(this.current.folder.id);

	for(var i=ar.length-1; i>=0; i--)
	{
		var tname = FSDATA.folders[ar[i]].name;
		if(tname.length > 30)
			tname = tname.substr(0, 27) +'...';
		if(i != 0)
		{
			ce('SPAN', this.fpanel.path, {innerHTML: tname, fid: ar[i], onclick: go, className: 'href'}, {color: '#020094'});
			ce('SPAN', this.fpanel.path, {innerHTML: '&nbsp;/ '});
		}
		else
		{
			ce('SPAN', this.fpanel.path, {innerHTML: tname});
		}
	}

	function fillAr(fid)
	{	//заполняет массив, рекурсивно следуя вверх по иерархии папок
		ar.push(fid);
		if(fid != FSDATA.topFolderId)
			fillAr(FSDATA.folders[fid].parent);
		return;
	}

	function go()
	{
		self.goToFolder(this.fid);
	}
}

/**************v Наборы файлов v**/

//Обновляет все гаджеты-наборы; обычно вызывается при совершении операций с файлами или папками
__Filestore.prototype.updateSets = function()
{
}

//Регистрирует новый набор
__Filestore.prototype.createSet = function(files)
{
	if(!files) files = [];
	var setName = window.prompt(this.lang.msg['EnterNewSetName'], this.lang['NewSet']);
	if(setName)
	{
		setName.substr(0, FSDATA.constants.maxLenSetName);
		for(var i in FSDATA.sets)
		{
			if(setName == FSDATA.sets[i].name)
			{
				window.alert(this.lang.msg['ErrorSetNameIsDublic']);
				return;
			}
		}
		Update.request(this.type, 'module', 'createSet', {id: this.id}, {id: FSDATA.nextSetId, name: setName, files: files}, true);
		FSDATA.sets[FSDATA.nextSetId] = {name: setName, files: files};
		FSDATA.nextSetId++;
		return true;
	}
	else return false;
}

//Создаёт в панели настроек форму управления группами
__Filestore.prototype.initFormSets = function()
{
	var fileTypes = {
		'text': ['doc', 'rtf', 'pdf', 'txt', 'odt', 'sxw', 'ott', 'sdw', 'pdb', 'psw'],
		'tables': ['xls', 'xlt', 'ods', 'sxc', 'sdc', 'slk', 'csv', 'pxl'],
		'xml': ['html', 'htm', 'xml'],
		'images': ['gif', 'jpg', 'png', 'bmp', 'tiff', 'psd', 'ai', 'eps'],
		'video': ['avi', 'mov', 'wmv', 'mpeg'],
		'audio': ['mp3', 'mid', 'wma', 'wav'],
		'presennts': ['ppt'],
		'archives': ['zip', 'rar', 'arj', '7z', 'ha']
	};
	var self = this;
	this.Tabs.data[this.tabIds.groups].content.innerHTML = '';
	this.fpanel.formSets = ce('FORM', this.Tabs.data[this.tabIds.groups].content);
	ce('H4', this.fpanel.formSets, {innerHTML: this.lang['TypicalSets']});
	this.finput.newTypicalSetKind = ce('SELECT', null);
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'bookmarks', innerHTML: this.lang.fileKinds['bookmarks']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'text', innerHTML: this.lang.fileKinds['text']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'tables', innerHTML: this.lang.fileKinds['tables']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'xml', innerHTML: this.lang.fileKinds['xml']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'images', innerHTML: this.lang.fileKinds['images']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'video', innerHTML: this.lang.fileKinds['video']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'audio', innerHTML: this.lang.fileKinds['audio']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'presents', innerHTML: this.lang.fileKinds['presents']});
		ce('OPTION', this.finput.newTypicalSetKind, {value: 'archives', innerHTML: this.lang.fileKinds['archives']});
	this.fpanel.formSets.appendChild(this.finput.newTypicalSetKind);
	ce('BR', this.fpanel.formSets);
	ce('SPAN', this.fpanel.formSets, {innerHTML: Locale['Placed'] +': '});
	this.finput.newTypicalSetUploaded = ce('SELECT', null);
		ce('OPTION', this.finput.newTypicalSetUploaded, {value: 0, innerHTML: this.lang.timeCrit['notImp']});
		ce('OPTION', this.finput.newTypicalSetUploaded, {value: 1, innerHTML: this.lang.timeCrit['durDay']});
		ce('OPTION', this.finput.newTypicalSetUploaded, {value: 3, innerHTML: this.lang.timeCrit['dur3Day']});
		ce('OPTION', this.finput.newTypicalSetUploaded, {value: 30, innerHTML: this.lang.timeCrit['dur30Day']});
	this.fpanel.formSets.appendChild(this.finput.newTypicalSetUploaded);

	ce('INPUT', this.fpanel.formSets, {type: 'submit', value: Locale['ToCreate'], className: 'std_button'});
	this.fpanel.formSets.onsubmit = function()
	{
		var files = [];
		if(self.finput.newTypicalSetKind.value == 'bookmarks')
		{
			for(var i in FSDATA.files)
			{
				if(FSDATA.files[i].kind == 'url')
				{
					files.push(i);
				}
			}
		}
		else if(fileTypes[self.finput.newTypicalSetKind.value])
		{
			for(var i in FSDATA.files)
			{
				if(typeof(arraySearch(fileTypes[self.finput.newTypicalSetKind.value], FSDATA.files[i].ext)) != 'boolean')
				{
					files.push(i);
				}
			}
		}
		//теперь проверяем на дату размещения
		if(files.length == 0)
		{
			window.alert(self.lang.msg['NotFoundFilesByType']);
			return false;
		}
		var created = self.finput.newTypicalSetUploaded.value - 0;
		if(created==1 || created==3 || created==30)
		{
			var cdata = new Date();
			var ctstamp = Math.round(cdata.getTime()/1000);
			var secLimit = created*86400;
			for(var i=0; i<files.length; i++)
			{	//ПОКА РАЗНИЦА В ЧАСОВЫХ ПОЯСАХ МЕЖДУ КЛИЕНТОМ И СЕРВЕРОМ НЕ УЧИТЫВАЕТСЯ
				if(Math.abs(ctstamp - FSDATA.files[files[i]].created) > secLimit)
				{
					files.splice(i, 1);
					i--;
				}
			}
		}
		if(files.length == 0)
		{
			window.alert(self.lang.msg['NotFoundFilesByDate']);
			return false;
		}
		self.createSet(files);
		return false;
	}

	ce('H4', this.Tabs.data[this.tabIds.groups].content, {innerHTML: this.lang['ExistSets']}, {marginTop: '12px'});
	this.fpanel.sets = ce('UL', this.Tabs.data[this.tabIds.groups].content);
	for(var i in FSDATA.sets)
	{
		var oLi = ce('LI', this.fpanel.sets, {sid: i});
		ce('IMG', oLi, {src: '/img/icons/x2.gif', title: this.lang['ToDelSet'], className: 'href', align: 'absmiddle', onclick: deleteSet}, {margin: '0px 5px 3px 10px'});
		ce('SPAN', oLi, {innerHTML: FSDATA.sets[i].name, className: 'href', onclick: showSet});
	}

	function showSet()
	{
		self.createGadgetSet(this.parentNode.sid);
	}

	function deleteSet()
	{
		if(window.confirm(self.lang.msg['SureToDelThisSet']))
		{
			var LIs = self.fpanel.sets.childNodes;
			for(var i=0; i<LIs.length; i++)
			{
				if(LIs[i].sid == this.parentNode.sid)
				{
					//Надо будет удалить ещё и гаджет, если он есть
					delete FSDATA.sets[LIs[i].sid];
					for(var j in Modules)
					{
						if(Modules[j].Object.setId && Modules[j].Object.setId == LIs[i].sid)
							ModManager.Delete(j)
					}
					Update.request('Filestore', 'module', 'deleteSet', {id: self.id}, {set: LIs[i].sid}, true);
					de(LIs[i]);
					break;
				}
			}
		}
	}
}

//Показывает меню добавления папок и файлов к группам
__Filestore.prototype.showMenuAddToSets = function(e, obj)
{
	var self = this;
	var fids = obj.files;
	for(var i=0; i<obj.folders.length; i++)
	{
		if(FSDATA.fStructure[obj.folders[i]])
			for(var j=0; j<FSDATA.fStructure[obj.folders[i]].length; j++)
			{
				fids.push(FSDATA.fStructure[obj.folders[i]][j]);
			}
	}

	if(fids.length == 0)
	{
		window.alert(this.lang.msg['NotSelectedFiles']);
		return;
	}
	var oDiv = ce('FORM', document.body, null, {position: 'absolute', left: Event.pointerX(e)+'px', top: Event.pointerY(e)+'px', width: '200px', height: '200px', border: '2px solid #992222', backgroundColor: '#EEEEEE', padding: '5px'});
	ce('IMG', oDiv, {src: '/img/icons/x.gif', className: 'href', onclick: function() {de(oDiv);}}, {position: 'absolute', right: '10px'});
	ce('H4', oDiv, {innerHTML: this.lang.msg['ChooseSet']}, {width: '150px'});
	var oUl = ce('UL', oDiv, {className: 'menu'});
	ce('LI', oUl, {sid: i, innerHTML: '['+ this.lang['NewSet'] +']', onclick: newSet, onmouseover: enLight, onmouseout: offLight});
	for(var i in FSDATA.sets)
	{
		ce('LI', oUl, {sid: i, innerHTML: FSDATA.sets[i].name, onclick: chooseSet, onmouseover: enLight, onmouseout: offLight})
	}

	function enLight()
	{
		this.style.backgroundColor = '#EEDDDD';
	}
	function offLight()
	{
		this.style.backgroundColor = '';
	}

	function newSet()
	{
		if(self.createSet())
		{
			var sid = FSDATA.nextSetId-1;
			var t = ce('LI', null, {sid: sid, innerHTML: FSDATA.sets[sid].name, onclick: chooseSet, onmouseover: enLight, onmouseout: offLight});
			if(this.nextSibling)
				oUl.insertBefore(t, this.nextSibling);
			else
				oUl.appendChild(t);
		}
	}

	function chooseSet()
	{
		Update.request('Filestore', 'module', 'addFilesToSet', {id: self.id}, {toSet: this.sid, files: fids}, true);	//запрос на создание группы в БД
		for(var i=0; i<fids.length; i++)
		{
			FSDATA.sets[this.sid].files.push(fids[i]);
		}
		de(oDiv);
	}
}

//Создаёт гаджет представления заданного набора
__Filestore.prototype.createGadgetSet = function(setId)
{
	this.initTab();
	var moduleId = ModManager.Create('FilestoreSet', 'cMain', this.workspaceId);
	Modules[moduleId].Object.create(setId);
}
