//..............................................................................
//
// SSH connection user interface
//

import "ui_PropertyGrid.jnc"
import "ui_Dialog.jnc"
import "doc_Storage.jnc"

namespace ui {

//! \addtogroup common-ui
//! @{

//..............................................................................

class SshPropertySet
{
	bitflag enum PropertyId
	{
		UserName,
		AuthenticationMethod,
		PrivateKeyFile,
		RememberLastPassword,
		Process,
		PtyType,

		All =
			UserName |
			AuthenticationMethod |
			PrivateKeyFile |
			RememberLastPassword |
			Process |
			PtyType,
	}

	enum Defaults
	{
		AuthenticationMethod = ui.AuthenticationMethod.Password,
		RememberLastPassword = false,
		ProcessTypeIndex     = 0,
	}

	static char DefaultProcessType[] = "shell";
	static char DefaultPtyType[] = "xterm";

	StringProperty* m_userNameProp;
	EnumProperty* m_authenticationMethodProp;
	FileProperty* m_privateKeyFileProp;
	BoolProperty* m_rememberLastPasswordProp;
	EnumProperty* m_processTypeProp;
	StringProperty* m_processParamProp;
	StringProperty* m_ptyTypeProp;

	void createProperties(
		PropertyGrid* propertyGrid,
		GroupProperty* group = null,
		Property* insertBefore = null,
		PropertyId mask = PropertyId.All
		);

	void load(doc.Storage* storage);
	void save(doc.Storage* storage);
	void restoreDefaults();

	reactor m_uiReactor;
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

void SshPropertySet.createProperties(
	PropertyGrid* propertyGrid,
	GroupProperty* group,
	Property* insertBefore,
	PropertyId mask
	)
{
	static EnumPropertyOption authenticationMethodTable[] =
	{
		{ "Password",    AuthenticationMethod.Password },
		{ "Private key", AuthenticationMethod.PrivateKey },
	}

	if (mask & PropertyId.UserName)
		m_userNameProp = propertyGrid.createStringProperty(
			group,,
			"User name",
			"Enter a user name...",
			"User name for SSH authentification"
			);

	if (mask & PropertyId.AuthenticationMethod)
		m_authenticationMethodProp = propertyGrid.createEnumProperty(
			group,,
			"User authentication",
			"How to authentify a user (password / private key)",
			authenticationMethodTable,
			countof(authenticationMethodTable)
			);

	if (mask & PropertyId.PrivateKeyFile)
	{
		m_privateKeyFileProp = propertyGrid.createFileProperty(
			group,,
			"Private key file",
			"Private key file (PEM) for SSH authentification"
			);

		m_privateKeyFileProp.m_fileDialogTitle = "Select Private Key File";
		m_privateKeyFileProp.m_filter = "SSH identity files (id_dsa id_rsa);;PEM files (*.pem);;All files (*.*)";
	}

	if (mask & PropertyId.RememberLastPassword)
		m_rememberLastPasswordProp = propertyGrid.createBoolProperty(
			group,,
			"Remember last password",
			"Re-use the last entered password during subsequent connect attempts"
			);

	if (mask & PropertyId.Process)
	{
		static ui.EnumPropertyOption processTypeTable[] =
		{
			{ "shell",     "shell" },
			{ "exec",      "exec" },
			{ "subsystem", "subsystem" },
		}

		m_processTypeProp = propertyGrid.createEnumProperty(
			group,,
			"Process type",
			"Type of requested SSH process",
			processTypeTable,
			countof(processTypeTable)
			);

		m_processParamProp = propertyGrid.createStringProperty(
			group,,
			"Process parameter",
			"Enter remote process parameters...",
			"Parameter to pass to the remote process"
			);
	}

	if (mask & PropertyId.PtyType)
		m_ptyTypeProp = propertyGrid.createStringProperty(
			group,,
			"Pseudoterminal",
			"Enter a PTY type...",
			"Type of requested pseudoterminal (PTY)"
			);
}

void SshPropertySet.load(doc.Storage* storage)
{
	if (m_userNameProp)
		m_userNameProp.m_value = storage.readString("userName");

	if (m_authenticationMethodProp)
		m_authenticationMethodProp.m_value = storage.readInt("authenticationMethod", Defaults.AuthenticationMethod);

	if (m_privateKeyFileProp)
		m_privateKeyFileProp.m_value = storage.readString("privateKeyFile");

	if (m_rememberLastPasswordProp)
		m_rememberLastPasswordProp.m_value = storage.readBool("rememberLastPassword", Defaults.RememberLastPassword);

	if (m_processTypeProp)
		m_processTypeProp.m_value = storage.readString("processType", DefaultProcessType);

	if (m_processParamProp)
		m_processParamProp.m_value = storage.readString("processParam");

	if (m_ptyTypeProp)
		m_ptyTypeProp.m_value = storage.readString("ptyType", DefaultPtyType);
}

void SshPropertySet.save(doc.Storage* storage)
{
	if (m_userNameProp)
		storage.writeString("userName", m_userNameProp.m_value);

	if (m_authenticationMethodProp)
		storage.writeInt("authenticationMethod", m_authenticationMethodProp.m_value);

	if (m_privateKeyFileProp)
		storage.writeString("privateKeyFile", m_privateKeyFileProp.m_value);

	if (m_rememberLastPasswordProp)
		storage.writeBool("rememberLastPassword", m_rememberLastPasswordProp.m_value);

	if (m_processTypeProp)
		storage.writeString("processType", m_processTypeProp.m_value);

	if (m_processParamProp)
		storage.writeString("processParam", m_processParamProp.m_value);

	if (m_ptyTypeProp)
		storage.writeString("ptyType", m_ptyTypeProp.m_value);
}

void SshPropertySet.restoreDefaults()
{
	if (m_rememberLastPasswordProp)
		m_rememberLastPasswordProp.m_value = Defaults.RememberLastPassword;

	if (m_processTypeProp)
		m_processTypeProp.m_currentIndex = Defaults.ProcessTypeIndex;

	if (m_ptyTypeProp)
		m_ptyTypeProp.m_value = DefaultPtyType;
}

reactor SshPropertySet.m_uiReactor
{
	m_authenticationMethodProp && m_privateKeyFileProp ?
		m_privateKeyFileProp.m_isEnabled = m_authenticationMethodProp.m_value == ui.AuthenticationMethod.PrivateKey :
		0;

	m_processTypeProp ? m_processParamProp.m_isEnabled = strcmp(m_processTypeProp.m_value, "shell") != 0 : 0;

	m_processTypeProp ?
		strcmp(m_processTypeProp.m_value, "exec") == 0 ? m_processParamProp.m_placeholderText = "Enter command line..." :
		strcmp(m_processTypeProp.m_value, "subsystem") == 0 ? m_processParamProp.m_placeholderText = "Enter subsystem name..." :
		null : null;
}

//..............................................................................

//! @}

} // namespace ui
