// Preferences.cs
//
//  Copyright (C) 2008-2009 Christian Eide
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

using System;
using System.Collections.Generic;
using GConf;

namespace bareFTP.Preferences
{
	public class Config
	{
		private string GCONF_APP_PATH = "/apps/bareftp";
		private Dictionary<string, string> algorithms;
		private GConf.Client client;
		
		public event EventHandler DefaultProtocolChanged;
		public event EventHandler ShowHiddenFilesChanged;
		
		public Config(string prefix)
		{
			client = new GConf.Client();
			client.AddNotify(GCONF_APP_PATH, onConfigChanged);
			algorithms = CreateAlgorithmDictionary();
		}
		
		public void WriteConfig()
		{
			client.SuggestSync();
		}
		
		protected void onConfigChanged(object sender, NotifyEventArgs args)
		{
			if(DefaultProtocolChanged != null && args.Key == GCONF_APP_PATH + "/net/default_protocol")
			{
				DefaultProtocolChanged.Invoke(this, args);
			}
			else if(ShowHiddenFilesChanged != null && args.Key == GCONF_APP_PATH + "/general/show_hidden_files")
			{
				ShowHiddenFilesChanged.Invoke(this, args);
			}
			
		}
		
		// TODO: This one has to go.. hack for ssh
		public string getSSHAlgorithm(string key)
		{
			if(algorithms != null)
			{
				if(algorithms.ContainsKey(key))
					return algorithms[key];
				else
					return null;
			}
			
			return null;
		}
		
		public string General_RemoteCharset
		{
			get 
			{ 
				try {
					return (string)client.Get(GCONF_APP_PATH + "/general/remote_charset");
				} catch (GConf.NoSuchKeyException) {
					return string.Empty;
				}
			}
			set 
			{
				client.Set(GCONF_APP_PATH + "/general/remote_charset", value);
			}
		}
		
		public bool General_ShowHiddenFiles
		{
			get 
			{ 
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/general/show_hidden_files");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set 
			{
				client.Set(GCONF_APP_PATH + "/general/show_hidden_files", value);
			}
		}

		public bool General_PreserveFilePermissions
		{
			get 
			{ 
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/general/preserve_file_permissions");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set 
			{
				client.Set(GCONF_APP_PATH + "/general/preserve_file_permissions", value);
			}
		}
		
		public int GUI_VPanedPosition
		{
			get 
			{ 
				try {
					return (int)client.Get(GCONF_APP_PATH + "/gui/vpaned_pos");
				} catch (GConf.NoSuchKeyException) {
					return -1;
				}
			}
			set { client.Set(GCONF_APP_PATH + "/gui/vpaned_pos", value); }
		}
		
		public int GUI_HPanedPosition
		{
			get 
			{ 
				try {
					return (int)client.Get(GCONF_APP_PATH + "/gui/hpaned_pos");
				} catch (GConf.NoSuchKeyException) {
					return -1;
				}
			}
			set { client.Set(GCONF_APP_PATH + "/gui/hpaned_pos", value); }
		}
		
		public bool GUI_Maximized
		{
			get 
			{ 
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/gui/maximized");
				} catch (GConf.NoSuchKeyException) {
					return false;
				}
			}
			set { client.Set(GCONF_APP_PATH + "/gui/maximized", value); }
		}
		
		public string GUI_MessageFont
		{
			get 
			{ 
				try {
					return (string)client.Get(GCONF_APP_PATH + "/gui/message_font");
				} catch (GConf.NoSuchKeyException) {
					return "Monospace 8";
				}
			}
			set { client.Set(GCONF_APP_PATH + "/gui/message_font", value); }
		}
		
		public string SSHKnownHostsFile
		{
			get 
			{ 
				try {
					return (string)client.Get(GCONF_APP_PATH + "/ssh/known_hosts_file");
				} catch (GConf.NoSuchKeyException) {
					return System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), ".ssh/known_hosts");
				}
			}
			set 
			{
				client.Set(GCONF_APP_PATH + "/ssh/known_hosts_file", value);
			}
		}
		
		public string SSHStrictKeyCheck
		{
			get
			{
				try {
					return (string)client.Get(GCONF_APP_PATH + "/ssh/strict_key_check");
				} catch (GConf.NoSuchKeyException) {
					return "ask";
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ssh/strict_key_check", value);
			}
		}
		
		
		
		public string FTPSDataChannelProtectionLevel
		{
			
			get 
			{ 
				try {
					return (string)client.Get(GCONF_APP_PATH + "/ftps/data_protection_level");
				} catch (GConf.NoSuchKeyException) {
					return "C";
				}
			}
			set { client.Set(GCONF_APP_PATH + "/ftps/data_protection_level", value); }
		}
		
		public bool FTP_PassiveMode
		{
			get
			{
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/ftp/passive_mode");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ftp/passive_mode", value);
			}
		}
		
		public bool FTP_EmptyUserAnonymous
		{
			get
			{
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/ftp/empty_user_anonymous");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ftp/empty_user_anonymous", value);
			}
		}
		
		public bool FTP_EmailAsAnonymousPass
		{
			get
			{
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/ftp/empty_anon_pass_email");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ftp/empty_anon_pass_email", value);
			}
		}
		
		public string FTP_EmailAddress
		{
			get
			{
				try {
					return (string)client.Get(GCONF_APP_PATH + "/ftp/email");
				} catch (GConf.NoSuchKeyException) {
					return string.Format("{0}@{1}", Environment.UserName, Environment.UserDomainName);
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ftp/email", value);
			}
		}
		
		public int FTPDefaultPort
		{
			get
			{
				try {
					return (int)client.Get(GCONF_APP_PATH + "/ftp/default_port");
				} catch (GConf.NoSuchKeyException) {
					return 21;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ftp/default_port", value);
			}
		}
		
		public int SSH_DefaultPort
		{
			get
			{
				try {
					return (int)client.Get(GCONF_APP_PATH + "/ssh/default_port");
				} catch (GConf.NoSuchKeyException) {
					return 22;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/ssh/default_port", value);
			}
		}
		
		public bool FTPSVerifyServerSertificate
		{
			get
			{  
				try {
					return (bool)client.Get(GCONF_APP_PATH + "/ftps/verify_server_certificate");
				} catch (GConf.NoSuchKeyException) {
					return true;
				}
			}
			set { client.Set(GCONF_APP_PATH + "/ftps/verify_server_certificate", value); }
		}
		
		public int NetworkDefaultProtocol
		{
			get
			{  
				try {
					return (int)client.Get(GCONF_APP_PATH + "/net/default_protocol");
				} catch (GConf.NoSuchKeyException) {
					return 1;
				}
			}
			set { client.Set(GCONF_APP_PATH + "/net/default_protocol", value); }
		}
		
		public int NetworkTimeout
		{
			get
			{  
				try {
					int timeout = (int)client.Get(GCONF_APP_PATH + "/net/timeout");
					if(timeout < 0)
						return 120000;
					else
						return timeout;
					
				} catch (GConf.NoSuchKeyException) {
					return 120000;
				}
			}
			set
			{
				client.Set(GCONF_APP_PATH + "/net/timeout", value);
			}
		}
		
		private Dictionary<string,string> CreateAlgorithmDictionary()
		{
			Dictionary<string,string> tmp = new Dictionary<string,string>(); 
			tmp.Add("cipher.s2c", "3des-cbc,aes128-cbc");
			tmp.Add("cipher.c2s", "3des-cbc,aes128-cbc");
			tmp.Add("mac.s2c", "hmac-md5,hmac-sha1");
			tmp.Add("mac.c2s", "hmac-md5,hmac-sha1");
			tmp.Add("compression.s2c", "none");
			tmp.Add("compression.c2s", "none");
			tmp.Add("lang.s2c", string.Empty);
			tmp.Add("lang.c2s", string.Empty);
			tmp.Add("diffie-hellman-group-exchange-sha1", "bareFTP.Protocol.Sftp.DHGEX");
			tmp.Add("diffie-hellman-group1-sha1", "bareFTP.Protocol.Sftp.DHG1");
			tmp.Add("dh", "bareFTP.Protocol.Sftp.jce.DH");
			tmp.Add("3des-cbc", "bareFTP.Protocol.Sftp.jce.TripleDESCBC");
			tmp.Add("hmac-sha1", "bareFTP.Protocol.Sftp.jce.HMACSHA1");
			tmp.Add("hmac-sha1-96", "bareFTP.Protocol.Sftp.jce.HMACSHA196");
			tmp.Add("hmac-md5", "bareFTP.Protocol.Sftp.jce.HMACMD5");
			tmp.Add("hmac-md5-96", "bareFTP.Protocol.Sftp.jce.HMACMD596");
			tmp.Add("sha-1", "bareFTP.Protocol.Sftp.jce.SHA1");
			tmp.Add("md5", "bareFTP.Protocol.Sftp.jce.MD5");
			tmp.Add("signature.dss", "bareFTP.Protocol.Sftp.jce.SignatureDSA");
			tmp.Add("signature.rsa", "bareFTP.Protocol.Sftp.jce.SignatureRSA");
			tmp.Add("keypairgen.dsa", "bareFTP.Protocol.Sftp.jce.KeyPairGenDSA");
			tmp.Add("keypairgen.rsa", "bareFTP.Protocol.Sftp.jce.KeyPairGenRSA");
			tmp.Add("aes128-cbc", "bareFTP.Protocol.Sftp.jce.AES128CBC");
			tmp.Add("kex", "diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha1");
			tmp.Add("server_host_key", "ssh-rsa,ssh-dss");
			return tmp;
		}
		
	}
}
