/*
Copyright (c) 2008, Security2day

Внимание! В приложении не должно быть объектов/функций с одинаковыми именами

Порядок работы с карточками:
Работа с вкладками, кнопками, состояниями приложения ведётся по порядковому номеру карточки в списке cards.
Для взаимодействия с сервером используется ID карточки. Получается из списка cards.

@package Security2day
@author Semen Shekhovtsov
@version 2008/04/03
*/ 

var pm_domain = "moiparoli.ru";
var debugging = false;

// aid идентификатор пользователя
var aid; //account id
var accountType;
var state; 
var order_by;
var selected_catalog_id;

var messageDigest;
var crypt;
var serverRequest;
var cards; // карчточки текущего каталога
var catalogs;
var passTools;
var all_cards; // все карточки пользователя, должны быть синхронизированы с cards

var logreader;
var wait;
var wrongAid;
var cardsTabs;
var toolsTabs;
var passDialog;
var errorDialog;
var catalogDialog;
var restore_backup_id;

var printableWindow;

// возможные состояния приложения, подсостояния отделяются "_"
STATE_LOGIN 		= "login";
STATE_REGISTRATION	= "registration";
STATE_CARDS			= "cards", // формат: cards_cardid_cardedit, где cardid-id активной карточки, cardedit - флаг редактирования карточки
//STATE_USERS			= "users"; // substate: 0-активные, 1-нет
STATE_TOOLS			= "tools"; 

// список параметров, которые шифруются при отправке запроса
var cryptParams = [ "reg_name" ];

var ignoreTabChange;

// константы
RECORD_TYPE_TEXT 		= "text";
RECORD_TYPE_PASSWORD 	= "password";
RECORD_TYPE_WEBADDRESS 	= "webaddress";
RECORD_TYPE_ADDRESS 	= "address";
// период времени, через который будет выполнены автоматический логаут
AUTO_LOGOUT_TIMEOUT = 15*60*1000;

DEMO_AID = '6e1ac09d6925f5b66c3160d91a538f4d'; // id демо-аккаунта

// ID таймера для автологаута
var auto_logout_timer;

// новый метод для String
String.prototype.replaceAll = function(search, replace){
  return this.split(search).join(replace);
}

/**
 * Инициализация приложения
 */
function init() {		
	
	// настройка режима отладки
	YAHOO.security2day.debugging = debugging;
	logreader = new YAHOO.widget.LogReader("collapsed");  	
	logreader.collapse(); 
	if (!YAHOO.security2day.debugging) {
		logreader.hide();
	}	
	
	// настройка модального окна "Загрузка"
	wait = waitInit();
	
	// настройка навигации в браузере	
	var defaultState	 = STATE_LOGIN; 	
	var bookmarkedState  = YAHOO.util.History.getBookmarkedState( "security2day" );  
	state 				 = bookmarkedState || defaultState; 

	if ( state != STATE_LOGIN && state != STATE_REGISTRATION && (typeof aid=="undefined" || aid=="") ) {
		state = STATE_LOGIN;
	}
	YAHOO.util.History.register( "security2day", state, function( history_state ) {
			// показываем нужную страницу приложения
			if ( history_state != state ) { 
				state = history_state;
				
				if ( getSubState() > cards.list.length ) {
					state = STATE_CARDS;
				}
				if (YAHOO.security2day.debugging) {
					YAHOO.log("Осуществлена навигация в состояние: " + history_state, "info");					
				}
				// показать приложение			
				showApplication();				
			}
	} );
	try {
		YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");
	} catch(o) {
		// показываем приложение в состоянии по умолчанию		
	}

	// инициализация объекта для симметричного шифрования по Blowfish
	crypt = new YAHOO.security2day.Crypt();
	
	// инициализация объекта для создания усиленных MD5-хэшей
	messageDigest = new YAHOO.security2day.MyMD5();
	
	// инициализация объекта хранения информации о карточках текущего каталога
	cards = new YAHOO.security2day.Cards();
	
	// инициализация объекта хранения информации о карточках
	all_cards = new YAHOO.security2day.Cards();	
	
	// инициализация объекта хранения информации о каталогах
	catalogs = new YAHOO.security2day.Catalogs();
		
	// инициализация объекта для работы с паролями
	passTools = new YAHOO.security2day.PassTools();
		
	// инициализация объекта асинхронных запросов к серверу
	serverRequest = new YAHOO.security2day.ServerRequest();
	serverRequest.initServerRequest('php/controller.php', crypt, cryptParams, showLoading, hideLoading);	
	
	// настройка интерфейса
	var registrationTabs 	= new YAHOO.widget.TabView("registration_tabs");
	var usersTabs 			= new YAHOO.widget.TabView('users_tabs'); 		
	cardsTabs 			    = new YAHOO.widget.TabView('cards_tabs', { orientation : 'left' } ); 
	toolsTabs 			= new YAHOO.widget.TabView('tools_tabs', { orientation : 'left' } );

	
	// диалоговое окно, информирующее о неверном aid,
	// установленном в приложении
	wrongAid = 
		new YAHOO.widget.SimpleDialog("wrong_aid_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: false,			   
			   text: "Неверный логин. <br/>Пожалуйста войдите повторно.",
			   icon: YAHOO.widget.SimpleDialog.ICON_WARN,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"OK", handler:handleLogout } ]
			 } );	
	wrongAid.setHeader("Ошибка");
	wrongAid.render(document.body);
	
	// обработчики событий	
	cardsTabs.addListener( 'activeTabChange', cards_tabs_active_tab_change );
	cardsTabs.addListener( 'beforeActiveTabChange', cards_tabs_before_active_tab_change );	
	YAHOO.util.Event.addListener("registerration_button_ind", "click", registerration_button_ind_click);
	YAHOO.util.Event.addListener("login_button", "click", login_button_click);
	YAHOO.util.Event.addListener("add_card_button", "click", add_card_button_click);
	YAHOO.util.Event.addListener("del_card_button", "click", del_card_button_click);	
	YAHOO.util.Event.addListener("move_card_button", "click", move_card_button_click);	
	YAHOO.util.Event.addListener("new_pass_apply_button", "click", new_pass_apply_button_click);	
	YAHOO.util.Event.addListener("del_account_button", "click", del_account_button_click);		
	YAHOO.util.Event.addListener("pass_generate", "keyup", pass_generate_change);
	YAHOO.util.Event.addListener("pass_generate", "change", pass_generate_change);	
	YAHOO.util.Event.addListener("create_catalog_button", "click", create_catalog_button_click);	
	YAHOO.util.Event.addListener("del_catalog_button", "click", del_catalog_button_click);
	YAHOO.util.Event.addListener("rename_catalog_button", "click", rename_catalog_button_click);
	
	// инициализация переменных
	ignoreTabChange = false;
	
	// скрываем окно "Загрузка"
	YAHOO.util.Dom.setStyle( "waitPageLoading", "display", "none" );
	// отображение приложения
	showApplication();		
}


/**
 * Настройка модального окна "Загрузка"
 */
function waitInit() {
	var wait = 
		new YAHOO.widget.Panel("wait",  
			{ width:"240px", 
			  fixedcenter:true, 
			  close:false, 
			  draggable:true, 
			  zindex:4,			  
			  modal:true,
			  visible:false
			} 
		);		
	wait.setHeader("Загрузка...");
	wait.setBody('<img src="img/rel_interstitial_loading.gif" />');
	wait.render(document.body);
	
	return wait;
}
		

function OpenPassGenDialog( inputID, cIndex, rIndex ) {
	
	passDialog = 
		new YAHOO.widget.Panel("passdialog",  
			{ width:"400px", 
			  fixedcenter:true, 
			  close:false, 
			  draggable:true, 
			  zindex:4,			  
			  modal:true,
			  visible:false
			} 
		);		
	passDialog.setHeader("Генератор паролей");
	passDialog.setBody(     '<br/><center>'+
					   		'<div class="pass_input_container center" style="width:249px;">'+
                            	'<input type="text" id="dialog_pass_generate" style="width: 244px" onkeyup="dialog_pass_generate_change();passTools.checkPass(this, \'dialog_pass_indicator_passgen\', 248)"/>&nbsp;'+					   										
                                '<div id="dialog_pass_indicator_passgen" class="pass_indicator"></div>'+
                            '</div>'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button" onclick="dialog_generate_password_button_click(); passTools.checkPass(document.getElementById\(\'dialog_pass_generate\'), \'dialog_pass_indicator_passgen\', 248)">Генерировать</button>'+
                                '</span>'+
                            '</span>'+							
                            '<br /><br />'+
							'Длина: <input id="dialog_pass_length" maxlength="3" value="14" />&nbsp;&nbsp;&nbsp;&nbsp;'+
                            '<input type="checkbox" checked="checked" id="dialog_lower_case_checkbox"/>abc&nbsp;'+                      
                            '<input type="checkbox" checked="checked" id="dialog_upper_case_checkbox"/>ABC&nbsp;'+
                            '<input type="checkbox" checked="checked" id="dialog_numbers_case_checkbox"/>012&nbsp;'+
                            '<input type="checkbox" checked="checked" id="dialog_punctuation_case_checkbox" />@#$'+                           
							'<br/><br/>'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button"'+
									'onclick="javascript:YAHOO.util.Dom.get(\''+inputID+'\').value=YAHOO.util.Dom.get(\'dialog_pass_generate\').value;'+
									'cardRecordDataChange(\''+inputID+'\','+cIndex+','+rIndex+');passDialog.hide();void(0)">OK</button>'+
                                '</span>'+
                            '</span>'+
							'&nbsp;'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button" onclick="javascript:passDialog.hide();void(0)">Отмена</button>'+
                                '</span>'+
                            '</span>'+						
                            '</center>'+									
                         '</div>');
	passDialog.render(document.body);
	
	passDialog.show();		
}

/**
 * Показывает значёк "Загрузка"
 */
function showLoading() {
	YAHOO.util.Dom.setStyle( "load_indicator", "display", "block" );
}


/**
 * Скрывает значёк "Загрузка"
 */
function hideLoading() {
	YAHOO.util.Dom.setStyle( "load_indicator", "display", "none" );
	YAHOO.security2day.Wait.hide();	
}

// автоматический логаут через AUTO_LOGOUT_TIMEOUT
function autoLogoutStart() {
	
	if ( state != STATE_LOGIN && state != STATE_REGISTRATION ) {
		clearTimeout(auto_logout_timer);
		auto_logout_timer = setTimeout('autoLogoutFinish()',AUTO_LOGOUT_TIMEOUT);		
	} else {
		clearTimeout(auto_logout_timer);
	}
}

/**
 * Переход в новый режим.
 */
function shiftState( newState, dontUpdateApplication, dontnavigate ) {
	if ( state==newState ) return;
	state = newState; 
	if ( !dontnavigate ) {
		YAHOO.util.History.navigate("security2day", newState); 
		if (YAHOO.security2day.debugging) {
			YAHOO.log("В историю браузера записано состояние: " + newState, "info");					
		}	
	}
	if ( !dontUpdateApplication ) {
		showApplication();
	}
	autoLogoutStart();
}

function getState() {
	return state.split('_')[0] + "";
}

function getSubState() {
	var subState = state.split('_')[1];
	if (typeof subState == "undefined") {
		subState = 0;
	} else {
		subState = parseInt(subState);
	}
	return subState;
}

function getSubSubState() {
	var subSubState = state.split('_')[2];
	if (typeof subSubState == "undefined") {
		subSubState = 0;
	} else {
		subSubState = parseInt(subSubState);
	}
	return subSubState;
}


/**
 * Log Out
 */
function logOut() {

	if (waitUser()) return;
	
	errorDialog = 
		new YAHOO.widget.SimpleDialog("logout_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Вы действительно хотите выйти из менеджера паролей?",
			   icon: YAHOO.widget.SimpleDialog.ICON_HELP ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"Да", handler:handleLogout },
  						  { text:"Нет", handler:handleOK }]
			 } );	
	errorDialog.setHeader("Выход");
	errorDialog.render(document.body);
	errorDialog.show();
}


/**
 * Заход клиента в свой аккаунт.
 */
function loginUser(userLogin, userPass, newAccountType) {
	
	wait.show();
	
	var tempassword = messageDigest.getMyMD5(userPass);
	
	//crypt.initCrypt( userLogin );
	setCryptKey( userLogin, tempassword );
	
	aid		 		= messageDigest.getMyMD5(userLogin);
	accountType		= newAccountType;	
	serverRequest.setAidPassword( aid, tempassword );
	
	shiftState( STATE_CARDS );
	
	wait.hide();	
}



/**
 * Функции проверки полей форм
 */
 
// Проверка полей форм регистраций
function checkRegistrationForm( loginID, passID, passAgainID, passRestoreID, nameID, 
							    loginErrorID, passErrorID, passAgainErrorID, passRestoreErrorID, nameErrorID ) {	
	result = false;
	
	var loginVal 			= YAHOO.util.Dom.get( loginID ).value;
	var passVal 			= YAHOO.util.Dom.get( passID ).value;	
	var passAgainVal 		= YAHOO.util.Dom.get( passAgainID ).value;		
	var passRestoreChecked 	= YAHOO.util.Dom.get( passRestoreID ).checked;	
	if (nameID) var nameVal = YAHOO.util.Dom.get( nameID ).value;	
	
	if (loginVal == "") {
		YAHOO.util.Dom.get( loginErrorID ).innerHTML = "Введите логин";
	} else {
		YAHOO.util.Dom.get( loginErrorID ).innerHTML = "";
	}
	if (passVal == "") {
		YAHOO.util.Dom.get( passErrorID ).innerHTML = "Введите пароль";
		YAHOO.util.Dom.get( passAgainErrorID ).innerHTML = "";
	} else {
		YAHOO.util.Dom.get( passErrorID ).innerHTML = "";
	}
	if (!passRestoreChecked) {
		YAHOO.util.Dom.get( passRestoreErrorID ).innerHTML = "Подтвердите, что вы согласны";
	} else {
		YAHOO.util.Dom.get( passRestoreErrorID ).innerHTML = "&nbsp;";
	}
	if (nameID) {
		if (nameVal=="") {
			YAHOO.util.Dom.get( nameErrorID ).innerHTML = "Введите имя";
		} else {
			YAHOO.util.Dom.get( nameErrorID ).innerHTML = "";
		}	
	}
	
	if (loginVal != "" && passVal != "") {
		if (passAgainVal == passVal) {
			YAHOO.util.Dom.get( passAgainErrorID ).innerHTML = "";
			if ( passRestoreChecked && ((nameID && nameVal!="") || !nameID ) ) {				
				result = true;
			}
		} else {
			YAHOO.util.Dom.get( passAgainErrorID ).innerHTML = "Пароли не совпадают";
		}
	}
	return result;
}

// Проверка формы login
function checkLoginForm() {
	result = false;
	if ( YAHOO.util.Dom.get("login_input").value == "" ) {
		YAHOO.util.Dom.get("login_error").innerHTML = "Введите логин";
	} else {
		YAHOO.util.Dom.get("login_error").innerHTML = "";
	}
	if ( YAHOO.util.Dom.get("pass_input").value == "" ) {
		YAHOO.util.Dom.get("pass_error").innerHTML = "Введите пароль";
	} else {
		YAHOO.util.Dom.get("pass_error").innerHTML = "";
	}	
	
	if ( YAHOO.util.Dom.get("login_input").value != "" && 
		 YAHOO.util.Dom.get("pass_input").value != "" ) {
		result = true;
	}
	return result;
}



/**
 * Обработчики диалоговых окон
 */

// Закрытие любого диалогового окна
function handleOK() {
	this.hide();
}

// выход из аккаунта
function handleLogout() {
	aid = "";
	this.hide();
	window.location.href = 'http://'+pm_domain;
}

// автологаут
function handleAutoLogout() {
	this.hide();
	window.location.href = 'http://'+pm_domain;
}

// Удаление карточки
function handleDelCard() {
	this.hide();
	serverRequest.send('action=delcard&cardid='+getCardIDByIndex(getSubState()), callbackDelCard, callbackFailure );
}

// Удаление карточки
function handleDelCatalog() {
	this.hide();
	serverRequest.send('action=delcatalog&catalog_id='+selected_catalog_id, callbackDelCatalog, callbackFailure );
}

// Удаление аккаунта
function handleDelAccount() {
	serverRequest.send('action=delaccount', callbackDelAccount, callbackFailure );
}


/**
 * Показывает все карточки в соответствии с текущим состоянием
 */
function showCards( do_not_sort ) {
			
	var curCard;
	var delTab;
	var editMode;
	
	var activeIndex = getSubState(); 	 // из состояния
	var editActive  = getSubSubState();  // из состояния				
	
	// получение карточек каталога, кроме режима редактирования карточки
	if ( editActive!=1 ) {
		getCardsFromCatalog( );
	}
	
	// если activeIndex больше, чем карточек в каталоге, то устанавливаем на последнюю
	if (activeIndex >= cards.list.length) {
		activeIndex = cards.list.length-1;
		if (cards.list.length==0) {
			shiftState( STATE_CARDS, true, false );	
		} else {
			shiftState( STATE_CARDS+"_" + (cards.list.length-1) + "_" + editActive, true, false );	
		}
	}	
	
	// удаление карточек	
	ignoreTabChange = true;
	while ( delTab=cardsTabs.getTab(0) ) {
		cardsTabs.removeTab( delTab );
	}
	ignoreTabChange = false;
	
	if (!do_not_sort)
	{
		cards.sortCards( order_by );
	}
	
	// добавление карточек
	for ( cIndex=0; cIndex<cards.list.length; cIndex++ ) {
		
		if (activeIndex==cIndex) {
			isactive = true;
			editMode = editActive;
		} else {
			isactive = false;
			editMode = false;
		}		
		cardsTabs.addTab( new YAHOO.widget.Tab(getCardAttributes(cIndex, isactive, editMode)) );
		
		if (!editMode) {
			YAHOO.util.Event.removeListener("edit_card_button_"+cIndex, "click");
			YAHOO.util.Event.addListener("edit_card_button_"+cIndex, "click", edit_card_button_click );
		} else {	
			showEditCardRecords( cIndex );
			//YAHOO.util.Event.removeListener("ok_card_button", "click");
			YAHOO.util.Event.addListener("ok_card_button", "click", ok_card_button_click );		
			//YAHOO.util.Event.removeListener("cancel_card_button", "click");			
			YAHOO.util.Event.addListener("cancel_card_button", "click", cancel_card_button_click );					
			//YAHOO.util.Event.removeListener("addrecord_card_button", "click");					
			YAHOO.util.Event.addListener("addrecord_card_button", "click", addrecord_card_button_click );		
		}
		
	}	
	
	if (editActive==1) {
		disableAllCards();
	} else {
		enableAllCards();
	}
	
	if (cards.list.length==0) {
		YAHOO.util.Dom.setStyle( "cards_tabs", "display", "none" );
		YAHOO.util.Dom.setStyle( "nocards_error", "display", "block" );
		YAHOO.util.Dom.get( "del_card_button" ).disabled = true;
		YAHOO.util.Dom.get( "move_card_button" ).disabled = true;
	} else {
		YAHOO.util.Dom.setStyle( "cards_tabs", "display", "block" );
		YAHOO.util.Dom.setStyle( "nocards_error", "display", "none" );
		YAHOO.util.Dom.get( "del_card_button" ).disabled = false;
		if (catalogs.list.length>1) {
			YAHOO.util.Dom.get( "move_card_button" ).disabled = false;
		} else {
			YAHOO.util.Dom.get( "move_card_button" ).disabled = true;
		}
	}
	
	showOrderBy();
	showCatalogs();
}

/**
 * Показывает карточку cIndex в режиме редактирования если editMode=true,
 * иначе в обычном.
 */
function getCardAttributes( cIndex, isactive, editMode ) {

	if (YAHOO.security2day.debugging) {
		if (typeof cIndex=="undefined") {
			YAHOO.log("Не передан cIndex в showCard()", "error");	
		} else {			
			if (cIndex<0 || cIndex>cards.list.length) {
				YAHOO.log("Неверный cIndex в showCard()", "error");				
			}
		}
	}
	
	var curCard = cards.list[cIndex];
	var cardHTML;
	var card_name;
	
	card_name = splitString( curCard.Name, 56 );
	card_name = htmlEscape(card_name);	
	
	if ( typeof editMode!="undefined" && editMode) {
		// редактирование
							
		cardHTML = "<div id=\"edit_card_top\"><input type=\"text\" value=\""+curCard.Name+"\" id=\"card_name_input\" onchange=\"cardNameInputChange(this)\"/>";		
		cardHTML += "<br/>Заметки";				
		cardHTML += "<br/><textarea id=\"card_note_textarea\" onchange=\"cardNoteTextareaChange(this)\" >"+curCard.Note+"</textarea></div>";
		
		cardHTML += "<table id=\"edit_records_table\"><thead><tr class=\"data_header\"><th width=\"24\"></th><th width=\"146\">Название записи</th><th width=\"248\">Значение</th><th width=\"66\">Тип</th</tr></thead><tbody></tbody></table>";
		
		cardHTML += '<p>'+
						'<span class="yui-button yui-push-button" >'+
							'<span class="first-child">'+
								'<button type="button" id="addrecord_card_button">Добавить запись</button>'+
							'</span>'+
						 '</span>'+
					 '</p>';
		cardHTML += "<hr class=\"dots\">";					 
		cardHTML += '<p class="center_text">'+
						'<span class="yui-button yui-push-button" >'+
							'<span class="first-child">'+
								'<button type="button" id="ok_card_button">OK</button>'+
							'</span>'+
						 '</span>'+
						 '<span class="yui-button yui-push-button" >'+
							'<span class="first-child">'+
								'<button type="button" id="cancel_card_button">Отмена</button>'+
							'</span>'+
						 '</span>'+
					 '</p>';					 
	} else {
		// обычнай вид
		
		var card_note;
		var rec_label;
		var rec_data;
		
		cardHTML  = "<h2>"+card_name+"</h2>";

		if (curCard.Note!="") {
			card_note = splitString( curCard.Note, 55 );
			card_note = htmlEscape(card_note);
			
			cardHTML += "<dl class='card_note'><dt>Заметки</dt><dd>"+card_note+"</dd></dl><br/>";
		}
		
		cardHTML += "<dl class='card_records data_header'><dt>Название записи</dt><dd>Значение</dd></dl>";
		for( rIndex=0; rIndex<curCard.Records.length; rIndex++) {										
		
			curRecord = curCard.Records[rIndex];
			
			// разрыв названия и значение
			rec_label = splitString( curRecord.Label, 18 );
			rec_data  = splitString( curRecord.Data, 35 );
			
			rec_label = htmlEscape(rec_label);
			rec_data  = htmlEscape(rec_data);
			
			cardHTML += "<dl class='card_records'><dt>"+rec_label+"</dt>";
			switch (curRecord.Type) {
				case RECORD_TYPE_TEXT: 	
					cardHTML += "<dd>"+rec_data+"&nbsp;</dd>";
					break;
				case RECORD_TYPE_PASSWORD:
					cardHTML += "<dd>";
					cardHTML += "<div id='card_"+cIndex+"_record_"+rIndex+"_pass_hidden' style='display:block'>";					
					cardHTML += "<span>*****</span>";
					cardHTML += "<br/><a href=\"javascript:openPassword('card_"+cIndex+"_record_"+rIndex+"_pass'); void(0)\">показать</a>";						
					cardHTML += "</div>";		
					cardHTML += "<div id='card_"+cIndex+"_record_"+rIndex+"_pass_open' style='display:none'>";					
					cardHTML += "<input type='text' id='card_"+cIndex+"_record_"+rIndex+"_pass_open' value='"+curRecord.Data+"' readonly/>";	
					cardHTML += "<br/><a href=\"javascript:hidePassword('card_"+cIndex+"_record_"+rIndex+"_pass'); void(0)\">скрыть</a>";
					cardHTML += "</div>";							
					cardHTML += "&nbsp;</dd>";
					break;
				case RECORD_TYPE_WEBADDRESS: 	
					cardHTML += "<dd><a href='http://"+curRecord.Data+"' target='_blank'>"+rec_data+"</a>&nbsp;</dd>";
					break;
				case RECORD_TYPE_ADDRESS: 	
					cardHTML += "<dd><a href='http://maps.google.com/maps?q="+curRecord.Data+"' target='_blank'/>"+rec_data+"</a>&nbsp;</dd>";
					break;		
				default:
					cardHTML += "<dd>"+curRecord.Data+"</dd>";					
			}
			cardHTML += "</dl>";
		}
		cardHTML += '<p class="center_text">'+
						'<span class="yui-button yui-push-button" >'+
							'<span class="first-child">'+
								'<button type="button" id="edit_card_button_'+cIndex+'">Редактировать</button>'+
							'</span>'+
						 '</span>'+
					 '</p>';
	}	

	card_name = splitString( card_name, 16 );
	return { 
		label: card_name,
		content: cardHTML,
		active: isactive
	};
}


// splits string into piece with length - len, separated by spaces
function splitString( str, len )
{
	var piece_count; 
	var word;
	var arrayOfWords;
	
	arrayOfWords = str.split(" ");

	result_str = "";
	for (i=0; i<arrayOfWords.length; i++) {
	
		word = arrayOfWords[ i ];
		piece_count = Math.ceil( word.length / len );
		
		for (j=0; j<piece_count; j++)
		{
			if (result_str!="") result_str = result_str + ' ';
			
			result_str = result_str + word.substring( j*len, (j+1)*len );
		}
	}
	return result_str;
}

function showEditCardRecords( cIndex ) {
	
	if (cIndex<0 || cIndex>cards.list.length) {
		if (YAHOO.security2day.debugging) {
			YAHOO.log("Показ записей несуществующей карточки: "+cIndex, "error");
		}
		return;
	}
			
	recordsTable = YAHOO.util.Dom.get("edit_records_table");
	// удаление прежних полей
	
	while ( recordsTable.tBodies[0].rows.length != 0 ) {		
		recordsTable.tBodies[0].deleteRow(-1);
	}
	
	var curCard = cards.list[cIndex];
	for( rIndex=0; rIndex<curCard.Records.length; rIndex++) {		
		// добавление записи
		showEditCardRecord( cIndex, rIndex );		
	}				

}


function showEditCardRecord(cIndex, rIndex) {
	
	var curCard 	= cards.list[cIndex];
	var curRecord 	= curCard.Records[rIndex];
	var recordsHTML;
	var select_box_options; // list of all record labels

	select_box_options = getSelectBoxOptions();
	
	recordsHTML = "<tr>";

	cellHTML_1 = "<span class=\"yui-button yui-push-button\" ><span class=\"first-child\"><button type=\"button\" onclick=\"removeRecord('"+rIndex+"')\">-</button></span></span>";
	
	cellHTML_2 = "<input type=\"text\" value=\""+curRecord.Label+"\" class=\"card_record_label\" onchange=\"cardRecordLabelChange(this, "+cIndex+","+rIndex+")\" id=\"card_record_label_"+cIndex+"_"+rIndex+"\" ";
	cellHTML_2 += " selectBoxOptions=\"" + select_box_options + "\"/>";
					
	cellHTML_3 ="<div class=\"pass_input_container\">";	     	                            	                                           
                         
	if ( curRecord.Type == RECORD_TYPE_PASSWORD ) {
		var input_type 			= "password";
		var input_type_hidden 	= "text";
		var opt_display 		= "inline";
	} else {
		var input_type 			= "text";
		var input_type_hidden 	= "password";
		var opt_display 		= "none";		
	}
	cellHTML_3 += "<input type=\""+input_type+"\" value=\""+curRecord.Data+"\" id=\"card_"+cIndex+"_record_"+rIndex+"_record_data\" class=\"card_record_data\" onchange=\"cardRecordDataChange(this, "+cIndex+","+rIndex+")\" onkeyup=\"passTools.checkPass(this, 'pass_indicator_card_"+cIndex+"_record_"+rIndex+"', 248)\" onfocus=\"passTools.checkPass(this, 'pass_indicator_card_"+cIndex+"_record_"+rIndex+"', 248)\" />";		
	
	cellHTML_3 += "<input type=\""+input_type_hidden+"\" value=\""+curRecord.Data+"\" id=\"card_"+cIndex+"_record_"+rIndex+"_record_data_hidden\" class=\"card_record_data\" onchange=\"cardRecordDataChange(this, "+cIndex+","+rIndex+")\" onkeyup=\"passTools.checkPass(this, 'pass_indicator_card_"+cIndex+"_record_"+rIndex+"', 248)\" onfocus=\"passTools.checkPass(this, 'pass_indicator_card_"+cIndex+"_record_"+rIndex+"', 248)\" style=\"display:none\"/>";	
	
	cellHTML_3 += "<div id=\"card_"+cIndex+"_record_"+rIndex+"_pass_options\" style=\"display:"+opt_display+"\" >";
	cellHTML_3 += "<div id=\"pass_indicator_card_"+cIndex+"_record_"+rIndex+"\" class=\"pass_indicator\"></div>";	
	
	cellHTML_3 += "<span style=\"display:block;\">";
	cellHTML_3 += "<a href=\"javascript:openhidePassword('card_"+cIndex+"_record_"+rIndex+"'); void(0)\" class=\"little_text\" id=\"card_"+cIndex+"_record_"+rIndex+"_record_data_switch\">показать</a>";			
	cellHTML_3 += "&nbsp;&nbsp;&nbsp;<a href=\"javascript:OpenPassGenDialog('card_"+cIndex+"_record_"+rIndex+"_record_data', "+cIndex+","+rIndex+"); void(0)\" class=\"little_text\">генерировать</a>";
	cellHTML_3 += "</span>";	
	
	cellHTML_3 += "</div></div>";	
	
	cellHTML_4 = "<td style=\"padding:0;\"><select onchange=\"recordTypeChange(this, 'card_"+cIndex+"_record_"+rIndex+"', "+cIndex+","+rIndex+")\" id=\"card_"+cIndex+"_record_"+rIndex+"_select\">";
	recordTypeSelected = ["","","",""];
	switch (curRecord.Type) {
		case RECORD_TYPE_TEXT: 	
			recordTypeSelected[0] = "selected=\"selected\"";
			break;
		case RECORD_TYPE_PASSWORD:
			recordTypeSelected[1] = "selected=\"selected\"";
			break;				
		case RECORD_TYPE_WEBADDRESS: 	
			recordTypeSelected[2] = "selected=\"selected\"";
			break;				
		case RECORD_TYPE_ADDRESS: 	
			recordTypeSelected[3] = "selected=\"selected\"";
			break;				
	}
	cellHTML_4 += "<option "+recordTypeSelected[0]+">текст</option>";
	cellHTML_4 += "<option "+recordTypeSelected[1]+">пароль</option>";
	cellHTML_4 += "<option "+recordTypeSelected[2]+">веб-адрес</option>";
	cellHTML_4 += "<option "+recordTypeSelected[3]+">адрес</option>";				
	
		
	recordsTable 	= YAHOO.util.Dom.get("edit_records_table");
	var newRow 		= recordsTable.tBodies[0].insertRow(-1);
	
	var newCell 	= newRow.insertCell(-1);
    newCell.innerHTML = cellHTML_1;
	
	newCell 	= newRow.insertCell(-1);
    newCell.innerHTML = cellHTML_2;	
	
	newCell 	= newRow.insertCell(-1);
    newCell.innerHTML = cellHTML_3;		
	
	newCell 	= newRow.insertCell(-1);
    newCell.innerHTML = cellHTML_4;		

	// create editable select
	createEditableSelect( document.getElementById("card_record_label_"+cIndex+"_"+rIndex) );	
}

/**
 * Деактивация всех карточек кроме редактируемой карточек
 */
function disableAllCards() {
	YAHOO.util.Dom.setStyle( "cards_mask", "display", "block" );	
}

/**
 * Активация всех карточек
 */
function enableAllCards() {	
	YAHOO.util.Dom.setStyle( "cards_mask", "display", "none" );	
}

/**
 *Показывает пароль за *
 */
function openPassword( passID ) {
	YAHOO.util.Dom.setStyle( passID+"_open", "display", "block" );		
	YAHOO.util.Dom.setStyle( passID+"_hidden", "display", "none" );			
	return false; // т.к. вызов из ссылки
}

/**
 * Скрывает пароль за *
 */
function hidePassword( passID ) {
	YAHOO.util.Dom.setStyle( passID+"_open", "display", "none" );		
	YAHOO.util.Dom.setStyle( passID+"_hidden", "display", "block" );			
	return false; // т.к. вызов из ссылки
}
 

/**
 * Отображение приложения в зависимости от текущего состояния state
 */
function showApplication() {
	
	var curState 	= getState();
	//var curSubState = state.split('_')[1]
	
	// для некоторых страниц требуется обновление содержимого
	switch( curState ) {	
		case STATE_CARDS:
			serverRequest.send('action=getcards', callbackGetCards, callbackFailure );	
			break;	
		case STATE_TOOLS:
			serverRequest.send('action=preparetools', callbackPrepareTools, callbackFailure );	
			break;
	}

	// отображение страницы
	YAHOO.util.Dom.setStyle( "container_login", "display", "none" );
	YAHOO.util.Dom.setStyle( "container_registration", "display", "none" );
	YAHOO.util.Dom.setStyle( "container_cards", "display", "none" );
	YAHOO.util.Dom.setStyle( "container_users", "display", "none" );
	YAHOO.util.Dom.setStyle( "container_tools", "display", "none" );	
	switch( curState ) {	
		case STATE_LOGIN:
			YAHOO.util.Dom.setStyle( "container_login", "display", "block" );
			break;		
		case STATE_REGISTRATION: 
			YAHOO.util.Dom.setStyle( "container_registration", "display", "block" );
			break;
		case STATE_CARDS: 
			YAHOO.util.Dom.setStyle( "container_cards", "display", "block" );
			break;	
		case STATE_TOOLS: 
			YAHOO.util.Dom.setStyle( "container_tools", "display", "block" );
			break;				
	}

	// отображение меню	
	var menuItemMainEl 			= YAHOO.util.Dom.get("menu_item_main");
	var menuItemLoginEl 		= YAHOO.util.Dom.get("menu_item_login");	
	var menuItemRegistrationEl 	= YAHOO.util.Dom.get("menu_item_registration");	
	var menuItemCardsEl 		= YAHOO.util.Dom.get("menu_item_cards");		
	var menuItemToolsEl 		= YAHOO.util.Dom.get("menu_item_tools");	
	var menuItemLogoutEl 		= YAHOO.util.Dom.get("menu_item_logout");	
	
	if (typeof aid=="undefined" || aid=="") {
		menuItemMainEl.style.display 			= "block";
		menuItemLoginEl.style.display 			= "block";		
		menuItemRegistrationEl.style.display 	= "block";		
		menuItemCardsEl.style.display 			= "none";				
		menuItemToolsEl.style.display 			= "none";		
		menuItemLogoutEl.style.display 			= "none";					
	} else {
		menuItemMainEl.style.display 			= "none";
		menuItemLoginEl.style.display 			= "none";		
		menuItemRegistrationEl.style.display 	= "none";		
		menuItemCardsEl.style.display 			= "block";	
		menuItemToolsEl.style.display 			= "block";		
		menuItemLogoutEl.style.display 			= "block";		
	}	

	menuItemMainEl.className 		= "";
	menuItemLoginEl.className 		= "";		
	menuItemRegistrationEl.className= "";		
	menuItemCardsEl.className 		= "";			
	menuItemToolsEl.className 		= "";
	
	switch( curState ) {
		case STATE_LOGIN:
			menuItemLoginEl.className = "current";
			break;
		case STATE_REGISTRATION:
			menuItemRegistrationEl.className = "current";
			break;
		case STATE_CARDS:
			menuItemCardsEl.className = "current";
			break;			
		case STATE_TOOLS:
			menuItemToolsEl.className = "current";
			break;			
	}
	
}

function encryptCard( cIndex ) {
	var Card = cards.list[cIndex];
	var encryptedCard = cards.getNewCard(Card.Catalog);
	
	encryptedCard.ID        = Card.ID;
	encryptedCard.Catalog   = Card.Catalog;	
	encryptedCard.Name      = crypt.encrypt(Card.Name);
	encryptedCard.Note      = crypt.encrypt(Card.Note);	
	//encryptedCard.Catalog = Card.Catalog;	
	for( i=0; i<Card.Records.length; i++ ) {
		encryptedCard.Records[i] 		= cards.getNewRecord();
		encryptedCard.Records[i].Label 	= crypt.encrypt(Card.Records[i].Label);
		encryptedCard.Records[i].Data 	= crypt.encrypt(Card.Records[i].Data);
		encryptedCard.Records[i].Type 	= crypt.encrypt(Card.Records[i].Type);				
	}
	
	return encryptedCard;
}

function encryptAllCard( cIndex ) {
	var Card = all_cards.list[cIndex];
	var encryptedCard = all_cards.getNewCard(Card.Catalog);
	
	encryptedCard.ID        = Card.ID;
	encryptedCard.Catalog   = Card.Catalog;	
	encryptedCard.Name      = crypt.encrypt(Card.Name);
	encryptedCard.Note      = crypt.encrypt(Card.Note);	
	//encryptedCard.Catalog = Card.Catalog;	
	for( i=0; i<Card.Records.length; i++ ) {
		encryptedCard.Records[i] 		= cards.getNewRecord();
		encryptedCard.Records[i].Label 	= crypt.encrypt(Card.Records[i].Label);
		encryptedCard.Records[i].Data 	= crypt.encrypt(Card.Records[i].Data);
		encryptedCard.Records[i].Type 	= crypt.encrypt(Card.Records[i].Type);				
	}
	
	return encryptedCard;
}


function encryptCatalog( index ) {
	var Catalog = catalogs.list[index];
	var encryptedCatalog = catalogs.getNewCatalog();
	
	encryptedCatalog.ID        = Catalog.ID;
	encryptedCatalog.Name      = crypt.encrypt(Catalog.Name);
	
	return encryptedCatalog;
}

function decryptCards() {
	
	var bufCards = new YAHOO.security2day.Cards();	
	for( cIndex=0; cIndex<cards.list.length; cIndex++ ) {
		cards.list[cIndex].Name = crypt.decrypt(cards.list[cIndex].Name);
		cards.list[cIndex].Note = crypt.decrypt(cards.list[cIndex].Note);

		for( rIndex=0; rIndex<cards.list[cIndex].Records.length; rIndex++ ) {
			cards.list[cIndex].Records[rIndex].Label 	= crypt.decrypt(cards.list[cIndex].Records[rIndex].Label);
			cards.list[cIndex].Records[rIndex].Data 	= crypt.decrypt(cards.list[cIndex].Records[rIndex].Data);
			cards.list[cIndex].Records[rIndex].Type 	= crypt.decrypt(cards.list[cIndex].Records[rIndex].Type);			
		}	
	}	
}

function autoLogoutFinish() {
	
	aid   = "";	
	state = STATE_LOGIN;
	clearTimeout(auto_logout_timer);
	
//	if (waitUser()) return;	
	errorDialog = 
		new YAHOO.widget.SimpleDialog("auto_logout_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: false,			   
			   text: "Вы не пользовались менеджером паролей более 15 минут. В целях безопасности Ваш сеанс завершён.<br/><br/><br/>Пожалуйста, войдите повторно.",
			   icon: YAHOO.widget.SimpleDialog.ICON_WARN ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"OK", handler:handleAutoLogout } ]
			 } );	
	errorDialog.setHeader("Сеанс завершён");
	errorDialog.render(document.body);
	errorDialog.show();
}



/**
 * Обработчики событий
 */
function registerration_button_ind_click() {
	if ( checkRegistrationForm("registration_login_ind",
							   "registration_pass_ind",
							   "registration_pass_again_ind",
							   "registration_pass_restore_ind",
							   "",
							   "registration_login_ind_error",
							   "registration_pass_ind_error",
							   "registration_pass_again_ind_error",
							   "registration_pass_restore_ind_error",
							   "") ) 
	{
		wait.show(); // при получении ответа от сервера окно должно быть закрыто
		var tempLogin 		= messageDigest.getMyMD5( YAHOO.util.Dom.get("registration_login_ind").value ); 
		var tempPassword 	= messageDigest.getMyMD5( YAHOO.util.Dom.get("registration_pass_ind").value ); 	
		serverRequest.send('action=registration&'+
						   'reg_type=ind&'+
						   'reg_login=' + tempLogin + "&" +
						   'reg_pass=' + tempPassword
						   , callbackRegistrationInd, callbackFailure );	
	}	
}

function login_button_click() {

	if (waitUser()) return;

	if (checkLoginForm()) {		
		tempLogin 		= messageDigest.getMyMD5( YAHOO.util.Dom.get( "login_input" ).value ); 		
		tempPassword 	= messageDigest.getMyMD5( YAHOO.util.Dom.get( "pass_input" ).value ); 
		setCryptKey( YAHOO.util.Dom.get( "login_input" ).value, tempPassword );
		tempCatalog	= crypt.encrypt( "Основной" );
		serverRequest.send('action=login&'+						   
						   'log_login=' + tempLogin + "&" +
						   'log_pass=' + tempPassword + "&" +
						   'catalog_name=' + tempCatalog
						   , callbackLogin, callbackFailure );	
	}	
}

function add_card_button_click() {
	if (catalogs.list.length == 0) return;
	YAHOO.util.Dom.setStyle( "cards_tabs", "display", "block" );
	YAHOO.util.Dom.setStyle( "nocards_error", "display", "none" );		
	disableAllCards();
	
	cards.newCard(selected_catalog_id); // добавление карточки
	shiftState( STATE_CARDS+"_" + (cards.list.length-1) + "_1", true, true );	
	showCards( true );	
}

function del_card_button_click() {

	if (waitUser()) return;
	
	errorDialog = 
		new YAHOO.widget.SimpleDialog("logout_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Вы действительно хотите удалить карточку \"" + htmlEscape( splitString(cards.list[getSubState()].Name, 40) ) + "\"?",
			   icon: YAHOO.widget.SimpleDialog.ICON_HELP ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"Да", handler:handleDelCard },
  						  { text:"Нет", handler:handleOK }]
			 } );	
	errorDialog.setHeader("Удаление карточки");
	errorDialog.render(document.body);
	errorDialog.show();	
}

function move_card_button_click() {

	if (waitUser() || catalogs.list.length < 2) return;
	
	var select_options_html = "";
	for( i=0; i<catalogs.list.length; i++ ) {
		if (catalogs.list[i].ID == selected_catalog_id) {
			continue;
		}
		select_options_html += "<option value=\""+catalogs.list[i].ID+"\">"+catalogs.list[i].Name+"</option>";		
	}
	
	catalogDialog = 
		new YAHOO.widget.Panel("move_card_dialog",  
			{ width:"340px", 
			  fixedcenter:true, 
			  close:false, 
			  draggable:true, 
			  zindex:4,			  
			  modal:true,
			  visible:false
			} 
		);		
	catalogDialog.setHeader("Перемещение карточки");
	catalogDialog.setBody( '<center>'+					   		
                            'В каталог: <select id="new_catalog_select" style="width: 202px" />'+select_options_html+'</select>'+			   										                                                     
							'<br/><br/>'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button"'+
									'onclick="javascript:'+
									'serverRequest.send(\'action=movecard&card_id=\'+cards.list[getSubState()].ID+\'&catalog_id=\'+YAHOO.util.Dom.get(\'new_catalog_select\').value, callbackMoveCard, callbackFailure );void(0)">OK</button>'+
                                '</span>'+
                            '</span>'+
							'&nbsp;'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button" onclick="javascript:catalogDialog.hide();void(0)">Отмена</button>'+
                                '</span>'+
                            '</span>'+						
                            '</center>'+									
                         '</div>');
	catalogDialog.render(document.body);	
	catalogDialog.show();		
}

function edit_card_button_click() {	
	cards.editCard( getSubState() ); // начало редактирования карточки
	shiftState( STATE_CARDS+"_"+getSubState()+"_1", true, true );	
	showCards();
}

function create_catalog_button_click() {
	catalogDialog = 
		new YAHOO.widget.Panel("create_catalog_dialog",  
			{ width:"400px", 
			  fixedcenter:true, 
			  close:false, 
			  draggable:true, 
			  zindex:4,			  
			  modal:true,
			  visible:false
			} 
		);		
	catalogDialog.setHeader("Создание каталога");
	catalogDialog.setBody( '<center>'+					   		
                            'Название каталога: <input type="text" id="new_catalog_name_edit" style="width: 244px" />'+					   										                                                     
							'<br/><br/>'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button"'+
									'onclick="javascript:new_catalog_name=YAHOO.util.Dom.get(\'new_catalog_name_edit\').value;'+
									'if (new_catalog_name==\'\') { YAHOO.util.Dom.get(\'new_catalog_name_edit\').focus(); return; }'+
									'new_catalog_name=crypt.encrypt(new_catalog_name);serverRequest.send(\'action=createcatalog&catalog_name=\'+new_catalog_name, callbackCreateCatalog, callbackFailure );catalogDialog.hide();void(0)">OK</button>'+
                                '</span>'+
                            '</span>'+
							'&nbsp;'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button" onclick="javascript:catalogDialog.hide();void(0)">Отмена</button>'+
                                '</span>'+
                            '</span>'+						
                            '</center>'+									
                         '</div>');
	catalogDialog.render(document.body);	
	catalogDialog.show();	
}

function del_catalog_button_click() {
	errorDialog = 
		new YAHOO.widget.SimpleDialog("delete_catalog_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Вместе с каталогом будут удалены все содержащиеся в нём карточки.<br/><br/>Вы действительно хотите удалить каталог \"" + 
				htmlEscape( splitString(catalogs.list[getCatalogIndex()].Name, 40) ) + "\"?",
			   icon: YAHOO.widget.SimpleDialog.ICON_HELP ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"Да", handler:handleDelCatalog },
  						  { text:"Нет", handler:handleOK }]
			 } );	
	errorDialog.setHeader("Удаление каталога");
	errorDialog.render(document.body);
	errorDialog.show();	
}

function rename_catalog_button_click() {
	catalogDialog = 
		new YAHOO.widget.Panel("rename_catalog_dialog",  
			{ width:"400px", 
			  fixedcenter:true, 
			  close:false, 
			  draggable:true, 
			  zindex:4,			  
			  modal:true,
			  visible:false
			} 
		);		
	catalogDialog.setHeader("Изменение названия каталога");
	catalogDialog.setBody(  'Название каталога: <input type="text" id="rename_catalog_name_edit" style="width: 244px" value="'+catalogs.list[getCatalogIndex()].Name+'"/>'+					   										                                                     
							'<br/><br/>'+
							'<center>'+	
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button"'+
									'onclick="javascript:new_catalog_name=YAHOO.util.Dom.get(\'rename_catalog_name_edit\').value;'+
									'if (new_catalog_name==\'\') { YAHOO.util.Dom.get(\'rename_catalog_name_edit\').focus(); return; }'+
									'new_catalog_name=crypt.encrypt(new_catalog_name);serverRequest.send(\'action=renamecatalog&catalog_name=\'+new_catalog_name+\'&catalog_id=\'+selected_catalog_id, callbackRenameCatalog, callbackFailure );void(0)">OK</button>'+
                                '</span>'+
                            '</span>'+
							'&nbsp;'+
							'<span class="yui-button yui-push-button" >'+
                                '<span class="first-child">'+
                                    '<button type="button" onclick="javascript:catalogDialog.hide();void(0)">Отмена</button>'+
                                '</span>'+
                            '</span>'+						
                            '</center>'+									
                         '</div>');
	catalogDialog.render(document.body);	
	catalogDialog.show();	
}

function cards_tabs_active_tab_change( eventInfo ) {
	// срабатывает если ignoreTabChange = false
	if (ignoreTabChange) return;
	newCardIndex = cardsTabs.getTabIndex( eventInfo.newValue );
	shiftState( "cards_"+newCardIndex, true );
}

function cards_tabs_before_active_tab_change( eventInfo ) {
	if (getSubSubState()==1) {
		return false;
	}
}

function openhidePassword( fldID ) {
	
	var dataEl 		= YAHOO.util.Dom.get( fldID + "_record_data" );
	var dataElHidden= YAHOO.util.Dom.get( fldID + "_record_data_hidden" );
	var switchEl 	= YAHOO.util.Dom.get( fldID + "_record_data_switch" );	
	
	dataElHidden.value = dataEl.value;
	dataElHidden.style.display = 'block';
	dataEl.style.display = 'none';
	
	var tempID = dataElHidden.id;
	dataElHidden.id = dataEl.id;
	dataEl.id = tempID;	
	
	if ( dataEl.type == 'password' ){	
		switchEl.innerHTML = "скрыть";
	} else {	
		switchEl.innerHTML = "показать";		
	}
}

function recordTypeChange( selectEl, recID, cIndex, rIndex  ) {
	
	var dataInputEl 		= YAHOO.util.Dom.get( recID + "_record_data" );
	var switchEl 			= YAHOO.util.Dom.get( recID + "_record_data_switch" );	
	var passOptionsEl 		= YAHOO.util.Dom.get( recID + "_pass_options" );
	var selectEl			= YAHOO.util.Dom.get( recID + "_select" );	
		
	//var prevValue 		= dataInputEl.value;	
	//var newType;
	var swapFlag = false;
	
	if (selectEl.selectedIndex == 1) {
		// пароль		
		//newType	= 'password';
		//switchEl.innerHTML 	= "показать";
		passOptionsEl.style.display = "block";
		
		if ( dataInputEl.type == 'text' ) {
			// выбран тип пароль и надо показать поле со звёздочками		
			swapFlag = true;			
		}
	} else {
		//newType	= 'text';						
		//switchEl.innerHTML 	= "скрыть";
		passOptionsEl.style.display = "none";	

		if ( dataInputEl.type == 'password' ) {
			// выбран тип пароль и надо показать поле со звёздочками
			swapFlag = true;
		}		
	}

	if ( swapFlag ) {
		openhidePassword( recID );
	}
	
	/*
	if (isIE) {			
				
		var newInput = document.createElement( "input" );
		var prevID 	 = dataInputEl.id;
		
		dataInputEl.parentNode.insertBefore(newInput, dataInputEl.nextSibling);
		//dataInputEl.parentNode.appendChild( newInput );
		
		// копируем свойства
		newInput.setAttribute( 'class', dataInputEl.getAttribute('class') );
		newInput.setAttribute( 'onfocus', dataInputEl.getAttribute('onfocus') );
		newInput.setAttribute( 'onkeyup', dataInputEl.getAttribute('onkeyup') );
		newInput.setAttribute( 'onchange', dataInputEl.getAttribute('onchange') );
		newInput.setAttribute( 'value', dataInputEl.getAttribute('value') );		
		newInput.setAttribute( 'type', newType );
		
		dataInputEl.parentNode.removeChild(dataInputEl);
		
		newInput.id = prevID;		
	} else {
		dataInputEl.type 	= newType;	
	}*/

	
	// восстановление значения поля для Opera	
	/*
	if ( navigator.userAgent.toLowerCase().indexOf("opera") != -1 ) {		
		dataInputEl.value 	= prevValue;
	}	*/
	
	switch ( selectEl.selectedIndex ) {
		case 0:
			newRecordType = RECORD_TYPE_TEXT;			
			break;
		case 1:
			newRecordType = RECORD_TYPE_PASSWORD;
			break;				
		case 2: 	
			newRecordType = RECORD_TYPE_WEBADDRESS;
			break;				
		case 3: 	
			newRecordType = RECORD_TYPE_ADDRESS;
			break;				
	}
	cards.list[cIndex].Records[rIndex].Type = newRecordType;
	
}

function ok_card_button_click() {
	// запрос к серверу
	var cardJSON = YAHOO.lang.JSON.stringify( encryptCard(getSubState()) );
	serverRequest.send('action=savecards&cardid='+getCardIDByIndex(getSubState())+'&cardjson='+cardJSON, callbackSaveCard, callbackFailure );
}

function cancel_card_button_click() {
	cards.cancelEditCard();
	if ( cards.list.length-1 < getSubState() ) {
		// отмена добавления карточки
		shiftState( STATE_CARDS + '_0_0', true );	
	} else {
		// отмена редактирования карточки
		shiftState( STATE_CARDS + '_' + getSubState() + '_0', true );			
	}
	showCards();
}

function addrecord_card_button_click() {
	cards.newCardRecord();
	//YAHOO.util.Dom.get( "card_records_container" ).innerHTML = getEditCardRecords( getSubState() );
	showEditCardRecord( cards.getEditCardIndex(), cards.getEditCardRecordsCount()-1 );
}

function removeRecord( recordIndex ) {
	cards.removeEditCardRecord( recordIndex );
	//YAHOO.util.Dom.get( "card_records_container" ).innerHTML = getEditCardRecords( getSubState() );
	var recordsTableElem = YAHOO.util.Dom.get( "edit_records_table" );
	//recordsTableElem.tBodies[0].deleteRow( recordIndex );
	showEditCardRecords( cards.getEditCardIndex() );
}

function cardRecordLabelChange( inputElem, cIndex, rIndex ) {
	cards.list[cIndex].Records[rIndex].Label = inputElem.value;
}

function cardRecordDataChange( inputElem, cIndex, rIndex ) {
	if (typeof(inputElem) == "object") {
		cards.list[cIndex].Records[rIndex].Data = inputElem.value;
	} else {
		cards.list[cIndex].Records[rIndex].Data = YAHOO.util.Dom.get( inputElem ).value;		
	}
}

function cardNoteTextareaChange( TextareaElem ) {
	cards.list[ getSubState() ].Note = TextareaElem.value;
}


function cardNameInputChange( inputElem ) {
	cards.list[ getSubState() ].Name = inputElem.value;
}

function printableVersion() {
	var catalogs_id = new Array();
	var catalogs_list = YAHOO.util.Dom.get( "catalogs_container" ).childNodes;
	
	for( i=0; i<catalogs_list.length; i++ ) {
		if (catalogs_list[i].tagName == 'INPUT' && catalogs_list[i].checked == true) {
			catalogs_id.push(catalogs_list[i].value);
		}
	}
	
	if (catalogs_id.length==0) {
		YAHOO.util.Dom.setStyle( "select_catalog_error", "display", "inline" );
		return;
	}
	YAHOO.util.Dom.setStyle( "select_catalog_error", "display", "none" );
	
	serverRequest.send(
		'action=exportcards&catalogs_id='+
		YAHOO.lang.JSON.stringify(catalogs_id), 
		callbackExport, callbackFailure 
	);	
}

function new_pass_apply_button_click() {
	var realPass;
	var curPass 		= YAHOO.util.Dom.get( "cur_pass_input" ).value;
	var newPass 		= YAHOO.util.Dom.get( "new_pass_input" ).value;	
	var againnewPass	= YAHOO.util.Dom.get( "new_again_pass_input" ).value;
	
	
	YAHOO.util.Dom.setStyle( "cur_pass_input_error", "display", "none" );
	YAHOO.util.Dom.setStyle( "new_pass_input_error", "display", "none" );	
	YAHOO.util.Dom.setStyle( "new_again_pass_input_error", "display", "none" );	
	
	realPass = serverRequest.getPass();	
	if (curPass=="") {
		YAHOO.util.Dom.setStyle( "cur_pass_input_error", "display", "inline" );
		return;
	}
	if (messageDigest.getMyMD5(curPass) != realPass) {
		YAHOO.util.Dom.setStyle( "cur_pass_input_error", "display", "inline" );
		return;
	}
	if (newPass=="") {
		YAHOO.util.Dom.setStyle( "new_pass_input_error", "display", "inline" );
		return;
	}
	if (againnewPass != newPass ) {
		YAHOO.util.Dom.setStyle( "new_again_pass_input_error", "display", "inline" );
		return;
	}		
	
	newPass = messageDigest.getMyMD5(newPass);
		
	setCryptKey( userLogin, newPass );
	
	var cardsjson = new Array();
	for( c=0; c<all_cards.list.length; c++ ) {
		cardsjson[c] = encryptAllCard( c );
	}
	var catalogsjson = new Array();
	for( ct=0; ct<catalogs.list.length; ct++ ) {
		catalogsjson[ct] = encryptCatalog( ct );
	}	
	
	setCryptKey( userLogin, realPass );	
	
	serverRequest.send('action=changepass&curpass='+realPass+'&newpass='+newPass+'&cardsjson='+
		YAHOO.lang.JSON.stringify(cardsjson)+
		'&catalogsjson='+YAHOO.lang.JSON.stringify(catalogsjson), 
		callbackChangePass, callbackFailure );	
}

function del_account_button_click() {

	if (waitUser()) return;
	
	errorDialog = 
		new YAHOO.widget.SimpleDialog("logout_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Все данные будут безвозвратно утеряны. <br/>Вы дейстивтельно хотите удалить аккаунт?",
			   icon: YAHOO.widget.SimpleDialog.ICON_HELP ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"Да", handler:handleDelAccount },
  						  { text:"Нет", handler:handleOK }]
			 } );	
	errorDialog.setHeader("Удаление аккаунта");
	errorDialog.render(document.body);
	errorDialog.show();
}

function generate_password_button_click() {
	
	var LowerCase 	= YAHOO.util.Dom.get("lower_case_checkbox").checked;
	var UpperCase 	= YAHOO.util.Dom.get("upper_case_checkbox").checked;	
	var Numbers 	= YAHOO.util.Dom.get("numbers_case_checkbox").checked;	
	var Punctuation = YAHOO.util.Dom.get("punctuation_case_checkbox").checked;
	var len 		= YAHOO.util.Dom.get("pass_length").value;
	
	passTools.Generate( "pass_generate", LowerCase, UpperCase, Numbers, Punctuation, len );
	pass_generate_change();
}

function pass_generate_change() {
	YAHOO.util.Dom.get( "pass_length" ).value = YAHOO.util.Dom.get( "pass_generate" ).value.length;
}

function dialog_generate_password_button_click() {
	
	var LowerCase 	= YAHOO.util.Dom.get("dialog_lower_case_checkbox").checked;
	var UpperCase 	= YAHOO.util.Dom.get("dialog_upper_case_checkbox").checked;	
	var Numbers 	= YAHOO.util.Dom.get("dialog_numbers_case_checkbox").checked;	
	var Punctuation = YAHOO.util.Dom.get("dialog_punctuation_case_checkbox").checked;
	var len 		= YAHOO.util.Dom.get("dialog_pass_length").value;
	
	passTools.Generate( "dialog_pass_generate", LowerCase, UpperCase, Numbers, Punctuation, len );
	dialog_pass_generate_change();
}

function dialog_pass_generate_change() {
	YAHOO.util.Dom.get( "dialog_pass_length" ).value = YAHOO.util.Dom.get( "dialog_pass_generate" ).value.length;
}

function sortCards( orderBySelect ) {
	
	if (orderBySelect.selectedIndex==0) {
		order_by = 'date';
	} else {
		order_by = 'name';
	}
	
	serverRequest.send('action=set_cards_order&order_by='+order_by, callbackSetOrderBy, callbackFailure );	
}

function showOrderBy() {
	if (order_by == 'name') {
		YAHOO.util.Dom.get( "order_by_select" ).selectedIndex = 1;
	} else {
		YAHOO.util.Dom.get( "order_by_select" ).selectedIndex = 0;
	}	
}

function showNotAccountPage( url ) {
	if ( aid == '' ||  aid == undefined ) {
		document.location.href = url;
	} else {
		new_window = window.open( url, 'non_account_window', 'scrollbars=yes,status=yes,width=780,height=500,resizable=yes' );
		new_window.focus();
	}
}

function setCryptKey( login, password, cryptedLogin ) {

	if ( cryptedLogin == '' || cryptedLogin == undefined ) {
		cryptedLogin = messageDigest.getMyMD5(login);
	} 
	if ( 	cryptedLogin == '07d9484fb4cbec8f6360db41f7534833' ||
			cryptedLogin == '07407fbd1308a32b2daff975463ba95b' ||
			cryptedLogin == '087c12dfa7c2a35a0beeaaddbe4bf5b6' ||			
			cryptedLogin == '1cdeffc534eef80122b1e740e5e2f841' ||
			cryptedLogin == '2c77230037cfccfc460b79d2ab141e99' ||
			cryptedLogin == '36d4dcb2df3a0915cf1be2e82f535009' ||
			cryptedLogin == '3c84f6c8f3501bcd76acfeaccde7167b' ||
			cryptedLogin == '411350da8364afb9dc1aee75b9a407cb' ||
			cryptedLogin == '420c50600b75fa8760571aa3090a30a4' ||
			cryptedLogin == '4dcb5770787d4a27081d0d3ee8d20e87' ||
			cryptedLogin == '654c22ae83934a06bc85cef561ffea02' ||
			cryptedLogin == '6fa0d057a71b62aa9006f6595320cad2' ||
			cryptedLogin == '7b3e6d91ea48455c16f86004cf8cda68' ||
			cryptedLogin == '99a3feb5d3c8299e525e41d1998d44d2' ||
			cryptedLogin == 'ce9d20429716854d9988bedd9d4b1618' ||
			cryptedLogin == 'ddde90fee98d8a79c8b49d439c378771' ||
			cryptedLogin == 'f876b6d4a18484398672e515f3e12ac6'
	) {
		crypt.initCrypt( login );
	} else {
		crypt.initCrypt( login+password );
	}
}

// получение ID карточки по её порядковому номеру
function getCardIDByIndex( index )
{
	return cards.list[index].ID;
}

// получение индекса карточки по ID
function getCardIndexByID( id )
{
	for (i=0; i<cards.list.length; i++) {
		if (cards.list[i].ID == id) {
			return i;
		}
	}
	return 0;
}

function htmlEscape(string) {
	var div = document.createElement('div');
	div.appendChild(document.createTextNode(string));
	return div.innerHTML;
}

function waitUser() {

	if ( typeof errorDialog != "undefined" && errorDialog.cfg.config.visible.value == true ) {
		return true;
	} else {
		return false;
	}
}

function submit_login(e) {
	var keynum;
	if (window.event) // IE
	{
	  keynum = e.keyCode;
	}
	else if (e.which) // Netscape/Firefox/Opera
	{
	  keynum = e.which;
	}
	
	if (keynum == 13) {
		login_button_click();
	}
}

// Path to arrow images
var arrowImage = '/img/editable_select/select_arrow.gif';	// Regular arrow
var arrowImageOver = '/img/editable_select/select_arrow_over.gif';	// Mouse over
var arrowImageDown = '/img/editable_select/select_arrow_down.gif';	// Mouse down

var selectBoxIds = 0;
var currentlyOpenedOptionBox = false;
var editableSelect_activeArrow = false;

function selectBox_switchImageUrl()
{
	if(this.src.indexOf(arrowImage)>=0){
		this.src = this.src.replace(arrowImage,arrowImageOver);	
	}else{
		this.src = this.src.replace(arrowImageOver,arrowImage);
	}		
}

function selectBox_showOptions()
{
	if(editableSelect_activeArrow && editableSelect_activeArrow!=this){
		editableSelect_activeArrow.src = arrowImage;
		
	}
	editableSelect_activeArrow = this;
	
	var numId = this.id.replace(/[^\d]/g,'');
	var optionDiv = document.getElementById('selectBoxOptions' + numId);
	if(optionDiv.style.display=='block'){
		optionDiv.style.display='none';
		if(navigator.userAgent.indexOf('MSIE')>=0)document.getElementById('selectBoxIframe' + numId).style.display='none';
		this.src = arrowImageOver;	
	}else{			
		optionDiv.style.display='block';
		if(navigator.userAgent.indexOf('MSIE')>=0)document.getElementById('selectBoxIframe' + numId).style.display='block';
		this.src = arrowImageDown;	
		if(currentlyOpenedOptionBox && currentlyOpenedOptionBox!=optionDiv)currentlyOpenedOptionBox.style.display='none';	
		currentlyOpenedOptionBox= optionDiv;			
	}
}

function selectOptionValue()
{
	var parentNode = this.parentNode.parentNode;
	var textInput = parentNode.getElementsByTagName('INPUT')[0];
	textInput.value = this.innerHTML;
	textInput.onchange();
	this.parentNode.style.display='none';	
	document.getElementById('arrowSelectBox' + parentNode.id.replace(/[^\d]/g,'')).src = arrowImageOver;
	
	if(navigator.userAgent.indexOf('MSIE')>=0)document.getElementById('selectBoxIframe' + parentNode.id.replace(/[^\d]/g,'')).style.display='none';
	
}
var activeOption;
function highlightSelectBoxOption()
{
	if(this.style.backgroundColor=='#316AC5'){
		this.style.backgroundColor='';
		this.style.color='';
	}else{
		this.style.backgroundColor='#316AC5';
		this.style.color='#FFF';			
	}	
	
	if(activeOption){
		activeOption.style.backgroundColor='';
		activeOption.style.color='';			
	}
	activeOption = this;
	
}

function createEditableSelect(dest, cIndex, rIndex )
{
	dest.className = dest.className + ' selectBoxInput';		
	var div = document.createElement('DIV');
	div.style.styleFloat = 'left';
	div.style.width = dest.offsetWidth + 16 + 'px';
	div.style.position = 'relative';
	div.id = 'selectBox' + selectBoxIds;
	var parent = dest.parentNode;
	parent.insertBefore(div,dest);
	div.appendChild(dest);	
	div.className = 'selectBox';
	if (navigator.userAgent.indexOf('MSIE')>=0) {
		div.style.zIndex = 10000 - selectBoxIds;
	}

	var img = document.createElement('IMG');
	img.src = arrowImage;
	img.className = 'selectBoxArrow';
	
	img.onmouseover = selectBox_switchImageUrl;
	img.onmouseout = selectBox_switchImageUrl;
	img.onclick = selectBox_showOptions;
	img.id = 'arrowSelectBox' + selectBoxIds;

	div.appendChild(img);
	
	var optionDiv = document.createElement('DIV');
	optionDiv.id = 'selectBoxOptions' + selectBoxIds;
	optionDiv.className='selectBoxOptionContainer';	
	optionDiv.style.width = div.offsetWidth-2 + 'px';
	div.appendChild(optionDiv);
	
	if(navigator.userAgent.indexOf('MSIE')>=0){
		var iframe = document.createElement('<IFRAME src="about:blank" frameborder=0>');
		iframe.style.width = optionDiv.style.width;
		iframe.style.height = optionDiv.offsetHeight + 'px';
		iframe.style.display='none';
		iframe.id = 'selectBoxIframe' + selectBoxIds;
		div.appendChild(iframe);
	}
	
	if(dest.getAttribute('selectBoxOptions')){
		var options = dest.getAttribute('selectBoxOptions').split(';');
		var optionsTotalHeight = 0;
		var optionArray = new Array();
		for(var no=0;no<options.length;no++){
			var anOption = document.createElement('DIV');
			anOption.innerHTML = options[no];
			anOption.className='selectBoxAnOption';
			anOption.onclick = selectOptionValue;
			anOption.style.width = optionDiv.style.width.replace('px','') - 2 + 'px'; 
			anOption.onmouseover = highlightSelectBoxOption;
			optionDiv.appendChild(anOption);	
			optionsTotalHeight = optionsTotalHeight + anOption.offsetHeight;
			optionArray.push(anOption);
		}
		if(optionsTotalHeight > optionDiv.offsetHeight){				
			for(var no=0;no<optionArray.length;no++){
				optionArray[no].style.width = optionDiv.style.width.replace('px','') - 22 + 'px'; 	
			}	
		}		
		optionDiv.style.display='none';
		optionDiv.style.visibility='visible';
	}
	
	selectBoxIds = selectBoxIds + 1;
}	

function getSelectBoxOptions() {
	var select_box_options_array = new Array();
	var select_box_options;
	var label;
	
	for( c=0; c<all_cards.list.length; c++ ) {
		for( r=0; r<all_cards.list[c].Records.length; r++ ) {
			label = all_cards.list[c].Records[r].Label;
			add_flag = true;
			for( l=0; l<select_box_options_array.length; l++ ) {
				if ( label == select_box_options_array[l] ) {
					add_flag = false;
					break;
				}
			}
			if (add_flag == true) {
				select_box_options_array[select_box_options_array.length] = label;
			}
		}
	}
	select_box_options = select_box_options_array.join( ";" );
	return select_box_options;
}

// возвращает ID каталога по индексу, 
function getCatalogID( catalog_index ) {

	if (catalog_index < 0 || catalog_index > catalogs.list.length ) {
		if ( typeof catalogs.list[0].ID != "undefined" ) {
			return catalogs.list[catalog_index].ID;
		} else {
			return -1;
		}
	} else {
		return catalogs.list[catalog_index].ID;
	}
}

// возвращает Index выбранного каталога по ID
function getCatalogIndex( ) {
	for( i=0; i<catalogs.list.length; i++ ) {
		if (catalogs.list[i].ID == selected_catalog_id) {
			return i;
		}
	}
	return 0;
}

// выбирает из all_cards в cards карчточки, принадлежащие выбранному каталогу
function getCardsFromCatalog() {
	var catalogID;
	var catalog_exists = false;

	// если в catalogs не найдена карточка с ID = selected_catalog_id
	for( i=0; i<catalogs.list.length; i++ ) {
		if (catalogs.list[i].ID == selected_catalog_id) {
			catalog_exists = true;
			break;
		}
	}
	if (!catalog_exists) {
		if (typeof catalogs.list[0] != "undefined" ) {
			selected_catalog_id = catalogs.list[0].ID;
		} else {
			selected_catalog_id = -1;
		}
	}

	cards.init();
	
	for( i=0; i<all_cards.list.length; i++ ) {
		if (all_cards.list[i].Catalog == selected_catalog_id) {
			cards.addNewCard(selected_catalog_id);
			cards.list[cards.list.length-1] = all_cards.list[i];
		}
	}

}	

function setCatalog(catalogs_el) {
	selected_catalog_id = getCatalogID( catalogs_el.selectedIndex );
	shiftState( STATE_CARDS+"_0", true, true );	
	//getCardsFromCatalog();
	showCards();
}

function showCatalogs() {
	var select_options_html = "";
	for( i=0; i<catalogs.list.length; i++ ) {
		select_options_html += "<option>"+catalogs.list[i].Name+"</option>";
	}
	
	var isIE = navigator.userAgent.toLowerCase().indexOf("msie") != -1;
	if (isIE) { // Or any IE testing
		if (catalogs.list.length != 0) {
			select_options_html = "<option>"+catalogs.list[0].Name+"</option>"+select_options_html;
		}
	}
	YAHOO.util.Dom.get( "catalogs_select" ).innerHTML = select_options_html;
	//if (isIE) { // Or any IE testing
	   YAHOO.util.Dom.get( "catalogs_select" ).outerHTML = YAHOO.util.Dom.get( "catalogs_select" ).outerHTML;
	//}
	
	YAHOO.util.Dom.get( "catalogs_select" ).selectedIndex = getCatalogIndex();
	
	if (catalogs.list.length == 0) {
		YAHOO.util.Dom.get( "rename_catalog_button" ).disabled = true;
		YAHOO.util.Dom.get( "del_catalog_button" ).disabled = true;
		YAHOO.util.Dom.get( "add_card_button" ).disabled = true;
	} else {
		YAHOO.util.Dom.get( "rename_catalog_button" ).disabled = false;
		YAHOO.util.Dom.get( "del_catalog_button" ).disabled = false;
		YAHOO.util.Dom.get( "add_card_button" ).disabled = false;
	}
}

function decryptCatalogs() {
	for ( var i=0; i<catalogs.list.length; i++ ) {
		catalogs.list[i].Name = crypt.decrypt( catalogs.list[i].Name );
	}
}


function markAllCatalogs(el) {
	var catalogs_list = YAHOO.util.Dom.get( "catalogs_container" ).childNodes;
	var new_state     = el.checked;
	
	for( i=0; i<catalogs_list.length; i++ ) {
		if (catalogs_list[i].tagName != 'INPUT') continue;
		catalogs_list[i].checked = new_state;
	}
}

function createBackup() {
	serverRequest.send('action=createbackup', callbackCreateBackup, callbackFailure );
}

function backupRestore(backup_id) {
	if (waitUser()) return;
	restore_backup_id = backup_id;
	errorDialog = 
		new YAHOO.widget.SimpleDialog("logout_dlg", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Вы действительно хотите восстановить данные из резервной копии?",
			   icon: YAHOO.widget.SimpleDialog.ICON_HELP ,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"Да", handler:handleBackupRestore },
  						  { text:"Нет", handler:handleOK }]
			 } );	
	errorDialog.setHeader("Восстановление данных");
	errorDialog.render(document.body);
	errorDialog.show();	

}

function updateBackupsTable(backupData, backupDates) {
		var ColumnDefs = [
			{key:"backup_date", label:"Резервная копия", sortable:true, resizeable:false},
			{key:"backup_type", label:"Тип резервирования", sortable:false, resizeable:false},
			{key:"backup_restore_key", label:"&nbsp;", sortable:false, resizeable:false}
		];
		var newData = [];
		var backupRow;
		var backupDates = [];
		if (typeof backupData != "undefined") {
			for( i=0; i<backupData.length; i++ ) {
				backupRow 				= backupData[i];
				newData[i] 				= {};
				newData[i].backup_date 	= 
					'<a href="javascript:showBackup('+backupRow.BackupID+');void(0);" '+
					'title="Просмотр резервной копии">'+backupRow.BackupDate+'</a>';
				newData[i].backup_restore_key = 
					'<span class="yui-button yui-push-button" >'+
					'<span class="first-child">'+
					'<button type="button" onclick="backupRestore('+backupRow.BackupID+'); ">Восстановить</button>'+
					'</span>'+
					'</span>';
				if (backupRow.BackupType == 0) {
					newData[i].backup_type 	= 'Авто';
				}  else {
					newData[i].backup_type 	= 'Вручную';
				}
				backupDates.push( backupRow.BackupDate );
			}
		}
		var BackupsDataSource = new YAHOO.util.DataSource( newData );
		BackupsDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
		BackupsDataSource.responseSchema = {
			fields: ["backup_date", "backup_restore_key", "backup_type"]
		};
		var LoginHistoryDataTable = new YAHOO.widget.DataTable("backup_table", ColumnDefs, BackupsDataSource );	
		// отображение выбора даты
		updateBackupDates(backupDates);		
}

function updateBackupDates(backupDates) {	
	var years = [];
	var yearExists;
	var backupDate;
	var backupYear;
	var yearsHTML;
	var backupMonth;
	for ( i=0; i<backupDates.length; i++ ) {
		backupDate    = new Date( 
								backupDates[i].substring(0,4), 
								backupDates[i].substring(5,7)-1, 
								backupDates[i].substring(8,10),
								backupDates[i].substring(11,13),
								backupDates[i].substring(14,16),
								backupDates[i].substring(17,19) 
		);
		backupYear    = backupDate.getYear();
		if (backupYear < 2000) {
			backupYear = backupYear + 1900;
		}
		yearExists = false;
		for (j=0; j<years.length; j++ ) {			
			if (years[j] == backupYear) {
				yearExists = true;
				break;
			}
		}
		if (!yearExists) {
			years.push(backupYear);
		}
		if (i==0) {
			backupMonth = backupDate.getMonth();
		}
	}
	if (years.length == 0) {
		curYear = (new Date()).getYear();
		if (curYear < 2000) {
			curYear = curYear + 1900;
		}		
		years.push( curYear );
	}
	yearsHTML = '<select id="backup_year" onchange="showBackupsOnDate()">';
	for (i=0; i<years.length; i++ ) {			
		yearsHTML = yearsHTML + '<option value="'+years[i]+'">'+years[i]+'</option>';
	}
	yearsHTML = yearsHTML + '</select>';
	
	YAHOO.util.Dom.get('backup_year_container').innerHTML = yearsHTML;
	if (typeof backupMonth != "undefined") {
		YAHOO.util.Dom.get('backup_month').selectedIndex = backupMonth;
	}
}

// Показывает окно с сообщением
function showMsg(text, title, icon) {
	wait.hide();
	if (waitUser()) return;
	errorDialog = 
		new YAHOO.widget.SimpleDialog("errorAJAX", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: text,
			   icon: icon,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"OK", handler:handleOK } ]
			 } );	
	errorDialog.setHeader(title);
	errorDialog.render(document.body);
	errorDialog.show();
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Сообщение пользователю: "+text, "error");	
	}
}

function handleBackupRestore() {
	this.hide();
	serverRequest.send('action=restorebackup&backup_id='+restore_backup_id, callbackBackupRestore, callbackFailure );
}

function showBackupsOnDate() {
	serverRequest.send( 
		'action=backupsbydate&month='+YAHOO.util.Dom.get('backup_month').value+'&year='+YAHOO.util.Dom.get('backup_year').value,
  		callbackBackupsByDate, callbackFailure 
	);
}

function exportToHTML() {
	var printHTML = '';
	var curCard;
	var curRecord;
	
	var card_note;
	var card_name;
	var card_data;
	var card_label;
	
	printHTML += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';	
	printHTML += '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
	printHTML += '<head>';
	printHTML += '<meta http-equiv="Content-type" content="text/html; charset=utf-8" />';
	printHTML += '<meta name="author" content="Shekhovtsov Semyon" />';
	printHTML += '<title>Мои Пароли</title>';
	printHTML += '<link rel="stylesheet" type="text/css" href="css/style.css" media="screen" />';
	printHTML += '<link rel="shortcut icon" href="http://' + pm_domain + '/favicon.ico" />';
	printHTML += '</head>';
	printHTML += '<body class="printable-version"><a href="http://' + pm_domain + '"><h1>Мои Пароли</h1></a><br/><br/>';	
	
	for( catIndex=0; catIndex<catalogs.list.length; catIndex++ ) {	
		curCatalog   = catalogs.list[ catIndex ];

		printHTML += '<div class="catalog_name">КАТАЛОГ: ' + htmlEscape(curCatalog.Name) + '</div>';
		for( cIndex=0; cIndex<cards.list.length; cIndex++ ) {				
			curCard = cards.list[ cIndex ];
			if (curCard.Catalog != curCatalog.ID) {
				continue;
			}
			
			card_name = splitString( curCard.Name, 75 );
			card_name = htmlEscape(card_name);
			
			printHTML += "<table border=\"1\" cellspacing=\"0\">";					
			printHTML += "<tr><th colspan=\"2\" width=\"620\"><center>" + card_name;
			
			if ( curCard.Note!="" ) {
				card_note = splitString( curCard.Note, 24 );
				card_note = htmlEscape(card_note);
				printHTML += " (" + card_note + ")";
			}
			printHTML += "</center></th></tr>";
			 
			for( rIndex=0; rIndex<curCard.Records.length; rIndex++ ) {	
					
				curRecord = curCard.Records[ rIndex ];
				
				card_label = splitString( curRecord.Label, 24 );
				card_label = htmlEscape(card_label);
				
				card_data = splitString( curRecord.Data, 49 );
				card_data = htmlEscape(card_data);						
								
				printHTML += "<tr><td width=\"200\">" + card_label + "&nbsp;</td><td width=\"400\">" + card_data + "&nbsp;</td></tr>";		
			}		
			printHTML += "</table>";			
		}
		
	}
	printHTML += "</body>";
	printHTML += "</html>";
	
	return printHTML;
}

function exportToPlain() {
	var crlf = "<br/>";
	var printHTML = '';
	var curCard;
	var curRecord;
	var index;
	var recordExtraIndex;
	
	for( catIndex=0; catIndex<catalogs.list.length; catIndex++ ) {	
		curCatalog = catalogs.list[ catIndex ];
		printHTML += 'КАТАЛОГ "' + htmlEscape(curCatalog.Name) + '".' + crlf + crlf;
		
		index = 1;
		for( cIndex=0; cIndex<cards.list.length; cIndex++ ) {				
			curCard = cards.list[ cIndex ];
			if (curCard.Catalog != curCatalog.ID) {
				continue;
			}										
			printHTML += "Карточка " + index + '. ' + curCard.Name;
			if ( curCard.Note!="" ) {
				printHTML += ' (' + curCard.Note + ')';
			}
			printHTML += ':' + crlf;
			for( rIndex=0; rIndex<curCard.Records.length; rIndex++ ) {
				curRecord = curCard.Records[ rIndex ];			
				recordExtraIndex = rIndex + 1;
				printHTML += recordExtraIndex + ') ' + curRecord.Label + " - " + curRecord.Data + crlf;				
			}	
			index++;
		}
		printHTML += crlf;
	}
	
	return printHTML;	
}

function exportToXML() {
	var crlf = "<br/>";
	var printHTML = '';
	var curCard;
	var curRecord;
	
	printHTML  = '&lt;?xml version="1.0" encoding="UTF-8"?&gt;' + crlf;
	printHTML += '&lt;moiparoli&gt;' + crlf;
	for( catIndex=0; catIndex<catalogs.list.length; catIndex++ ) {	
		curCatalog = catalogs.list[ catIndex ];
		printHTML += '&lt;catalog name="'+ htmlEscape(curCatalog.Name) + '"&gt;' + crlf;
		
		for( cIndex=0; cIndex<cards.list.length; cIndex++ ) {				
			curCard = cards.list[ cIndex ];
			if (curCard.Catalog != curCatalog.ID) {
				continue;
			}										
			printHTML += '&lt;card title="' + curCard.Name + '"';

			if ( curCard.Note!="" ) {
				printHTML += ' note="' + curCard.Note + '"';
			}
			printHTML += '>' + crlf;		
			for( rIndex=0; rIndex<curCard.Records.length; rIndex++ ) {
				curRecord = curCard.Records[ rIndex ];								
				printHTML += '&lt;record label="' + curRecord.Label + '"&gt;' + curRecord.Data + '&lt;/record&gt;' + crlf;		
			}	
			printHTML += '&lt;/card&gt;' + crlf;
		}
		printHTML += '&lt;/catalog&gt;' + crlf;
	}
	printHTML += '&lt;/moiparoli&gt;';
	
	return printHTML;	
}

function exportToJSON() {
	var crlf = "<br/>";
	var printHTML = '';
	var curCard;
	var curRecord;
	
	printHTML  = '{' + crlf;
	for( catIndex=0; catIndex<catalogs.list.length; catIndex++ ) {	
		curCatalog = catalogs.list[ catIndex ];
		printHTML += '"Catalog" : { "Name" : "'+ htmlEscape(curCatalog.Name) + '", " Cards" : [' + crlf;
		cardExists = false;
		for( cIndex=0; cIndex<cards.list.length; cIndex++ ) {				
			curCard = cards.list[ cIndex ];
			if (curCard.Catalog != curCatalog.ID) {
				continue;
			}										
			printHTML += '{ "Title" : "' + curCard.Name + '", ';

			if ( curCard.Note!="" ) {
				printHTML += '"Note" : "' + curCard.Note + '",';
			}
			printHTML += ' "Records" : [';	
			
			for( rIndex=0; rIndex<curCard.Records.length; rIndex++ ) {
				curRecord = curCard.Records[ rIndex ];								
				printHTML += ' {"Label" : "' + curRecord.Label + '", "Data" : "' + curRecord.Data + '" }';
				if (rIndex != curCard.Records.length-1) {
					printHTML += ',';
				}
			}	
			printHTML += ' ] },' + crlf;

			cardExists = true;
		}
		if (cardExists) {
			printHTML = printHTML.substring( 0, printHTML.length - crlf.length - 1 ) + crlf;
		}
		
		if (catIndex != catalogs.list.length-1) {
			printHTML += ' ] }, ' + crlf;
		} else {
			printHTML += ' ] } ' + crlf;
		}		
	}
	printHTML += ' }';
	
	return printHTML;	
}

function showBackup(backup_id) {
	serverRequest.send(
		'action=exportcards&backup_id='+backup_id, 
		callbackExport, callbackFailure 
	);	
}

/**
 * Функции обратного вызова.
 */

// Обработка ошибок клиента и сервера.
// Показывает сообщение об ошибке и перезагружает страницу.
function callbackFailure(o) {
	wait.hide();
	
	if (waitUser()) return;
	
	errorDialog = 
		new YAHOO.widget.SimpleDialog("errorAJAX", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: "Ошибка передачи данных! Пожалуйста, повторите операцию позже.",
			   icon: YAHOO.widget.SimpleDialog.ICON_WARN,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"OK", handler:handleOK } ]
			 } );	
	errorDialog.setHeader("Ошибка");
	errorDialog.render(document.body);
	errorDialog.show();
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Ошибка при запросе к серверу: "+o.statusText, "error");	
	}
}

// Индивидуальная регистрация
function callbackRegistrationInd(o) {	
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}
	wait.hide();	
	responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	if (responseObj.result == 1) {
		userLogin = YAHOO.util.Dom.get( "registration_login_ind" ).value;
		userPass  = YAHOO.util.Dom.get( "registration_pass_ind" ).value;
		loginUser(userLogin, userPass, responseObj.accountType);
	} else {
		YAHOO.util.Dom.get( "registration_login_ind_error" ).innerHTML = "Логин занят";
	}
}

// login
function callbackLogin(o) {
	if (waitUser()) return;
	
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	
	// 0 - OK
	// 1 - аккаунт не активирован
	// 2 - неверный логин или пароль
	responseObj = YAHOO.lang.JSON.parse(o.responseText); 
	
	if ( responseObj.result == 0 ) {		
		userLogin = YAHOO.util.Dom.get( "login_input" ).value;
		userPass  = YAHOO.util.Dom.get( "pass_input" ).value;
		loginUser(userLogin, userPass, responseObj.accountType );
		// удаление разделов "Смена пароля" и "Удаление аккаунта" в демо-режиме	
		if ( aid == DEMO_AID ) {
			var tab = toolsTabs.getTab( 4 );
			toolsTabs.removeTab( tab );
			tab = toolsTabs.getTab( 4 );
			toolsTabs.removeTab( tab );
		}
	} else {	
		var dlg_text;
		// ошибка
		if (responseObj.result == 1) {
			dlg_text = 'Ваша учётная запись ещё не активирована членами аккаунта ' + YAHOO.util.Dom.get( "login_input" ).value + '.';
		}
		// аккаунт неактивирован
		if (responseObj.result == 2) {
			dlg_text = 'Неверный логин или пароль.';
		}
		errorDialog = 
			new YAHOO.widget.SimpleDialog("error_login_dlg", 
				 { width: "300px",
				   fixedcenter: true,
				   visible: false,
				   draggable: true,
				   close: true,			   
				   text: dlg_text,
				   icon: YAHOO.widget.SimpleDialog.ICON_WARN,
				   constraintoviewport: true,
				   modal:true,
				   buttons: [ { text:"OK", handler:handleOK } ]
				 } );	
		errorDialog.setHeader("Ошибка");
		errorDialog.render(document.body);
		errorDialog.show();
	}
}

// загружает историю заходов клиента в свой аккаунт
function callbackPrepareTools(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}			
	responseObj = YAHOO.lang.JSON.parse(o.responseText);  
		
	
	if ( responseObj.result == 1 ) {		
		// история заходов
		var ColumnDefs = [
			{key:"date", label:"Дата", sortable:true, resizeable:false},
			{key:"ip", label:"IP", sortable:false, resizeable:false},
			{key:"country", label:"Страна", sortable:false, resizeable:false},	
			{key:"browser", label:"Браузер", sortable:false, resizeable:false}
		];
		
		var tableData = [];
		var tableRow;
		for( i=0; i<responseObj.loginData.length; i++ ) {
			tableRow = responseObj.loginData[i];
			tableData[i] = {};
			tableData[i].date = tableRow.date;
			tableData[i].ip = tableRow.ip;		
			if (tableData[i].country != '') {
				tableData[i].country = '<center><img src="img/flags/' + tableRow.country_code 
										+ '_flag.gif" title="' + tableRow.country + '" width="50" height="34" /></center>';
			}
			if (tableRow.browser != '') {
				tableData[i].browser = '<center><img src="img/browsers/' + tableRow.browser + 
									   '.png" title="' + tableRow.browser + '" width="50" height="34"/></center>';
			}
		}
	
		var DataSource = new YAHOO.util.DataSource( tableData );
		DataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
		DataSource.responseSchema = {
			fields: ["date", "ip", "country", "browser" ]
		};
	
		var LoginHistoryDataTable = new YAHOO.widget.DataTable("login_history_table", ColumnDefs, DataSource );
		
		// резервное копирование
		/*
		responseObj.backup_data = [
			{ backup_date: '21-07-2009 20:54:34', backup_id: '14' },
			{ backup_date: '21-07-2009 20:54:34', backup_id: '15' }
		];	*/
		updateBackupsTable(responseObj.backup_data, responseObj.backup_dates);
		
		// каталоги пользователя
		YAHOO.util.Dom.get( "select_all_catalogs" ).checked = false;
		YAHOO.util.Dom.setStyle( "select_catalog_error", "display", "none" );
		var catalogs_container_html = "";
		catalogs.loadCatalogs( responseObj.catalogs );
		decryptCatalogs();
		for( i=0; i<catalogs.list.length; i++ ) {
			catalogs_container_html += '<input type="checkbox" value="'+catalogs.list[i].ID+'" />&nbsp;'+
			htmlEscape(catalogs.list[i].Name)+'</input><br/>';
		}
		YAHOO.util.Dom.get( "catalogs_container" ).innerHTML = catalogs_container_html;
	} else {	
		var dlg_text = 'Произошла ошибка при получении истории заходов в учётную запись.';
		
		if (waitUser()) return;
		errorDialog = 
			new YAHOO.widget.SimpleDialog("error_login_history_dlg", 
				 { width: "300px",
				   fixedcenter: true,
				   visible: false,
				   draggable: true,
				   close: true,			   
				   text: dlg_text,
				   icon: YAHOO.widget.SimpleDialog.ICON_WARN,
				   constraintoviewport: true,
				   modal:true,
				   buttons: [ { text:"OK", handler:handleOK } ]
				 } );	
		errorDialog.setHeader("Ошибка");
		errorDialog.render(document.body);
		errorDialog.show();
	}
	
}

// загружает данные о карточках в cards.list
function callbackGetCards(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}
	
	responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	if (responseObj.result==0) { 
		wrongAid.show();
		return; 
	}
	
	cards.loadCards( responseObj.cards );
	catalogs.loadCatalogs( responseObj.catalogs );
	decryptCatalogs();
	if (responseObj.cards.length>0) {				
		order_by = responseObj.order_by;
		decryptCards();		
		all_cards.loadCards( cards.list );	
	}
	showCards();
}

function callbackSaveCard(o) {

	var cardIndex;
	var cardID;
	var isAddedNewCard = false;

	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}
	
	responseObj = YAHOO.lang.JSON.parse(o.responseText);
	if (responseObj.result==0) { 
		return; 
	}

	cardIndex = getSubState();
	
	isAddedNewCard = (typeof responseObj.cardid != "undefined");	
	// если производилось добавление карточки, то сервер должен вернуть ID новой карточки
	// и его необходимо записать в  поле ID редактируемой карточки
	if ( isAddedNewCard ) {
		cardID = responseObj.cardid;
		cards.list[ cardIndex ].ID = cardID;
		// добавление в список всех карточек all_cards новой
		all_cards.addNewCard(selected_catalog_id);
		all_cards.list[all_cards.list.length-1] = cards.list[ cardIndex ];
	} else {
		cardID = cards.list[ cardIndex ].ID;
	}
	
	cards.sortCards( order_by );
	cardIndex = getCardIndexByID( cardID );	
		
	cards.applyEditCard();
	shiftState( STATE_CARDS + '_' + cardIndex + '_0', true );	
	showCards();
	
}

function callbackDelCard() {
	var removeCardIndex = getSubState();
	
	// удалить из all_cards
	for( i=0; i<all_cards.list.length; i++ ) {
		if (all_cards.list[i].ID == cards.list[removeCardIndex].ID) {
			all_cards.removeCard( i );
			break;
		}
	}
	
	cards.removeCard( removeCardIndex );		
	shiftState( STATE_CARDS, true );
	showCards();
}

function callbackExport(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
		
	if (responseObj.catalogs.length>0) {			
	
		cards.loadCards( responseObj.cards );
		decryptCards();
		catalogs.loadCatalogs( responseObj.catalogs );
		decryptCatalogs();
		
		var printHTML = "";
		if (typeof YAHOO.util.Dom.get("export_format") != "undefined") {
			switch (YAHOO.util.Dom.get("export_format").value) {
				case 'html':
					printHTML = exportToHTML();
					break;
				case 'plain': 
					printHTML = exportToPlain();
					break;
				case 'xml': 
					printHTML = exportToXML();
					break;
				case 'json': 
					printHTML = exportToJSON();
					break;					
			}
		} else {
			printHTML = exportToHTML();
		}
		if (typeof printableWindow != "undefined") {
			printableWindow.close();
		}
		printableWindow = window.open( "", "printable_window" );		
		printableWindow.document.write( printHTML );
		printableWindow.focus();
	}
}

function callbackChangePass(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	var dlg_text;
	if (responseObj.result==0 && responseObj.newpass != "") { 
		dlg_text = "Ошибка! Пароль не был изменён.";			
	} else {		
		dlg_text = "Пароль был успешно изменён.";
		setCryptKey( userLogin, responseObj.newpass );
		serverRequest.setAidPassword( aid, responseObj.newpass );		
	}
	
	var Dialog = 
		new YAHOO.widget.SimpleDialog("error_deactivateuser", 
			 { width: "300px",
			   fixedcenter: true,
			   visible: false,
			   draggable: true,
			   close: true,			   
			   text: dlg_text,
			   icon: YAHOO.widget.SimpleDialog.ICON_WARN,
			   constraintoviewport: true,
			   modal:true,
			   buttons: [ { text:"OK", handler:handleOK } ]
			 } );	
	Dialog.setHeader("Сообщение");
	Dialog.render(document.body);		
	Dialog.show();	
}

function callbackDelAccount(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	if (responseObj.result==1) { 
		window.location.href = "http://"+pm_domain;		
	}
}


function callbackSetOrderBy(o) {
	
	var selectedCardID;
	var selectedCardIndex;
	
	if (cards.list.length==0) return;
	selectedCardID = cards.list[getSubState()].ID;
	cards.sortCards( order_by );
	selectedCardIndex = getCardIndexByID( selectedCardID );
	
	shiftState( STATE_CARDS + '_' + selectedCardIndex + '_0', true );
	
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	showCards();
}


function callbackCreateCatalog(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	//catalogDialog.hide();
	if (responseObj.result==1) { 
		catalogs.loadCatalogs( responseObj.catalogs );	
		decryptCatalogs();

		// здесь учитывается, что кталоги упорядочены по дате добавления
		selected_catalog_id = getCatalogID( catalogs.list.length-1 );
		//getCardsFromCatalog( );			
		showCards();	
	}	
}

function callbackDelCatalog(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	if (responseObj.result==1) { 
		catalogs.loadCatalogs( responseObj.catalogs );			
		decryptCatalogs();
		//getCardsFromCatalog( );			
		showCards();	
	}		
}

function callbackRenameCatalog(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	catalogDialog.hide();
	if (responseObj.result==1) { 
		catalogs.loadCatalogs( responseObj.catalogs );	
		decryptCatalogs();
		showCatalogs();
	}	
}

function callbackMoveCard(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);  
	
	catalogDialog.hide();
	if (responseObj.result==1) { 

		var moveCardIndex = getSubState();		
		cards.list[moveCardIndex].Catalog = responseObj.catalog_id;		
		showCards();
	}
}

function callbackCreateBackup(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText); 
	if (responseObj.result == 1) {
		showMsg( 
			'Резервирование данных прошло успешно.', 
			'Резервирование',
			YAHOO.widget.SimpleDialog.ICON_INFO
		);	
		updateBackupsTable(responseObj.backup_data, responseObj.backup_dates);
	} else if (responseObj.result == 2) {
			showMsg( 
			'Не заведено ни одного каталога.', 
			'Ошибка',
			YAHOO.widget.SimpleDialog.ICON_WARN
		);
	} else {
		showMsg( 
			'Произошла ошибка при создании резервной копии данных.', 
			'Ошибка',
			YAHOO.widget.SimpleDialog.ICON_WARN
		);
	}
}

function callbackBackupRestore(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);
	if (responseObj.result == 1) {
		showMsg( 
			'Восстановление данных прошло успешно.', 
			'Восстановление данных',
			YAHOO.widget.SimpleDialog.ICON_INFO
		);
		shiftState( STATE_CARDS );
		window.scroll(0,0);
	} else {
		showMsg( 
			'Произошла ошибка при восстановлении данных из резервной копии.', 
			'Ошибка',
			YAHOO.widget.SimpleDialog.ICON_WARN
		);
	}	
}

function callbackBackupsByDate(o) {
	if (YAHOO.security2day.debugging) {
		YAHOO.log("Получен ответ от сервера: "+o.responseText, "info");	
	}	
	var responseObj = YAHOO.lang.JSON.parse(o.responseText);
	updateBackupsTable(responseObj.backup_data, responseObj.backup_dates);
}
