// BookmarkDialog.cs
//
//  Copyright (C) 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.Xml;
using bareFTP.Preferences.Bookmarks;

namespace bareFTP.Gui.Preferences
{
	public partial class BookmarkDialog : Gtk.Dialog
	{
		BookmarkStore store;
		folder folder_w = new folder();
		Gtk.Widget current_w;
		bookmark_gen bookmark_w = new bookmark_gen();
		BookmarkList list;
		Bookmarks b;
		bareFTP.Protocol.ConnectionProperties conn_props;
		BookmarkEntry newitem = null;
		
		public BookmarkDialog(bareFTP.Protocol.ConnectionProperties connprops) : this()
		{
			conn_props = connprops;
			AddNewBookmark();
		}
		
		public BookmarkDialog()
		{
			
			this.Build();
			this.Modal = true;
			hpaned1.Position = 200;
			
			b = new Bookmarks();
			list = new BookmarkList();
			this.scrolledwindow1.Add(list);
			this.scrolledwindow1.ShowAll();
			store = list.Model as BookmarkStore;
			list.Selection.Changed += DisplayBookmark;
			list.ItemDeleted += DisplayBookmark;
			
			if(b.RootItem != null)
			{
				foreach(BookmarkItem item in b.RootItem.Items)
				{
					Gtk.TreeIter iter = store.AppendValues(item);
					if(item is BookmarkFolder)
						CreateTreeItem(item, iter);
				}
			}
			
			Gtk.VBox vbox = new Gtk.VBox();
			vbox.PackStart(new Gtk.Label(string.Empty), true, true, 0);
			hpaned1.Add2(vbox);
			current_w = vbox;
			vbox.ShowAll();
			
			bookmark_w.NameChanged += delegate {
				list.QueueDraw();
			};
			folder_w.NameChanged += delegate {
				list.QueueDraw();
			};
		}

		protected void DisplayBookmark(object sender, EventArgs e)
		{
			Gtk.TreeIter iter;
			if(list.Selection.GetSelected(out iter))
			{
				BookmarkItem item = (BookmarkItem)store.GetValue(iter, 0);
				if(current_w != null)
						hpaned1.Remove(current_w);
				
				if(item is BookmarkEntry)
				{
					hpaned1.Add2(bookmark_w);
					current_w = bookmark_w;
					bookmark_w.Bookmark = (BookmarkEntry)item;
				}
				else
				{
					hpaned1.Add2(folder_w);
					current_w = folder_w;
					folder_w.Bookmark = (BookmarkFolder)item;
				}

				hpaned1.ShowAll();
			}
			else
			{
				if(current_w != null)
						hpaned1.Remove(current_w);
				
				Gtk.VBox vbox = new Gtk.VBox();
				vbox.PackStart(new Gtk.Label(string.Empty), true, true, 0);
				hpaned1.Add2(vbox);
				current_w = vbox;
				vbox.ShowAll();
			}
		}
		
		private void CreateTreeItem(BookmarkItem item, Gtk.TreeIter iter)
		{
			foreach(BookmarkItem _item in item.Items)
			{
				Gtk.TreeIter _iter = store.AppendValues(iter, _item);
				
				if(_item is BookmarkFolder)
					CreateTreeItem(_item, _iter);
			}
		}

		protected virtual void onCloseClicked (object sender, System.EventArgs e)
		{
			this.Destroy();
		}

		public void SaveBookmarks()
		{
			XmlDocument doc = new XmlDocument();
			XmlElement xbookmarks = doc.CreateElement("bookmarks");
			Gtk.TreeIter iter;
			
			if(store.GetIterFirst(out iter))
				ParseStore(iter, doc, xbookmarks);
			
			doc.AppendChild(xbookmarks);
			try
			{
				b.Save(doc);
			}
			catch(bareFTP.Preferences.KeyringException ex)
			{
				Dialog.Dialogs.ErrorDialog(ex.Message);
			}
		}

		private void ParseStore(Gtk.TreeIter _iter, XmlDocument doc, XmlElement xelem)
		{
			Gtk.TreeIter iter = _iter;
			bool notend = true;
			while(notend)
			{
				BookmarkItem item = (BookmarkItem)store.GetValue(iter, 0);
				if(item is BookmarkFolder)
				{
					XmlElement xfolder = doc.CreateElement("folder");
					xfolder.SetAttribute("name", item.Name);
					xelem.AppendChild(xfolder);
					if(store.IterHasChild(iter))
					{
						Gtk.TreeIter childiter;
						store.IterChildren(out childiter, iter);
						ParseStore(childiter, doc, xfolder);
					}
				}
				else
				{
					BookmarkEntry entry = item as BookmarkEntry;
					XmlElement xbookmark = doc.CreateElement("bookmark");
					xbookmark.SetAttribute("name", entry.Name);
					
					XmlElement xprotocol = doc.CreateElement("protocol");
					xprotocol.InnerText = entry.Protocol.ToString();
					xbookmark.AppendChild(xprotocol);

					XmlElement xhost = doc.CreateElement("host");
					xhost.InnerText = entry.Host;
					xbookmark.AppendChild(xhost);

					XmlElement xport = doc.CreateElement("port");
					xport.InnerText = entry.Port.ToString();
					xbookmark.AppendChild(xport);

					XmlElement xuser = doc.CreateElement("user");
					xuser.InnerText = entry.User;
					xbookmark.AppendChild(xuser);

					XmlElement xpass = doc.CreateElement("password");
					xpass.InnerText = entry.Pass;
					xbookmark.AppendChild(xpass);

					XmlElement xshowhidden = doc.CreateElement("showhidden");
					xshowhidden.InnerText = entry.ShowHidden.ToString();
					xbookmark.AppendChild(xshowhidden);

					XmlElement xpassive = doc.CreateElement("passive");
					xpassive.InnerText = entry.Passive.ToString();
					xbookmark.AppendChild(xpassive);

					XmlElement xencryptdata = doc.CreateElement("encryptdata");
					xencryptdata.InnerText = entry.EncryptData.ToString();
					xbookmark.AppendChild(xencryptdata);

					XmlElement xcharset = doc.CreateElement("charset");
					xcharset.InnerText = entry.CharSet;
					xbookmark.AppendChild(xcharset);

					XmlElement xremotepath = doc.CreateElement("remotepath");
					xremotepath.InnerText = entry.RemotePath;
					xbookmark.AppendChild(xremotepath);

					XmlElement xlocalpath = doc.CreateElement("localpath");
					xlocalpath.InnerText = entry.LocalPath;
					xbookmark.AppendChild(xlocalpath);
					
					XmlElement syncronized_browse = doc.CreateElement("syncronized_browse");
					syncronized_browse.InnerText = entry.SyncedBrowse.ToString();
					xbookmark.AppendChild(syncronized_browse);

					xelem.AppendChild(xbookmark);
					
				}
				notend = store.IterNext(ref iter);
			}
		}
		
		protected virtual void onNewFolderClicked(object sender, System.EventArgs e)
		{
			Gtk.TreeIter iter;
			BookmarkItem newitem;
			
			newitem = new BookmarkFolder(Mono.Unix.Catalog.GetString("New folder"));
			
			if(list.Selection.CountSelectedRows() == 1)
			{
				list.Selection.GetSelected(out iter);
				
				Gtk.TreePath path = store.GetPath(iter);
				iter = store.AppendValues(iter, newitem);
				list.ExpandRow(path, false);
			}
			else
				iter = store.AppendValues(newitem);
			
			list.Selection.SelectIter(iter);
		}
		
		protected virtual void onNewBookmarkClicked (object sender, System.EventArgs e)
		{
			Gtk.TreeIter iter;
			BookmarkItem newitem;
			newitem = new BookmarkEntry(Mono.Unix.Catalog.GetString("New bookmark"));
			
			
			if(list.Selection.CountSelectedRows() == 1)
			{
				list.Selection.GetSelected(out iter);
				
				Gtk.TreeIter piter;
				if(store.IterParent(out piter, iter))
				{
					iter = store.AppendValues(piter, newitem);
				}
				else
				iter = store.AppendValues(newitem);
			}
			else
				iter = store.AppendValues(newitem);
			
			list.Selection.SelectIter(iter);
			
		}
		
		public string NewBookmarkLocalPath
		{
			set { newitem.LocalPath = value; }
		}
		
		public string NewBookmarkRemotePath
		{
			set { newitem.RemotePath = value; }
		}
		
		public bool NewBookmarkSyncedBrowse
		{
			set { newitem.SyncedBrowse = value; }
		}
		
		protected virtual void AddNewBookmark ()
		{
			newitem = new BookmarkEntry(Mono.Unix.Catalog.GetString(conn_props.Hostname));
			
			newitem.Host = conn_props.Hostname;
			if(conn_props.Port > 0)
				newitem.Port = conn_props.Port.ToString();
			newitem.User = conn_props.User;
			newitem.Pass = conn_props.Password;
			newitem.Protocol = conn_props.Protocol+1;
			newitem.Passive = conn_props.Passive;
			newitem.CharSet = conn_props.RemoteCharset;
		}
		
		public void InsertNewBookmark()
		{
			Gtk.TreeIter iter;
			iter = store.AppendValues(newitem);
			list.Selection.SelectIter(iter);
		}
		
		protected virtual void ExportBookmarks(object sender, EventArgs e)
		{
			XmlDocument doc = new XmlDocument();
			XmlElement xbookmarks = doc.CreateElement("bookmarks");
			Gtk.TreeIter iter;
			
			if(store.GetIterFirst(out iter))
				ParseStore(iter, doc, xbookmarks);
			
			doc.AppendChild(xbookmarks);
			
			Gtk.FileChooserDialog dialog = 
				new Gtk.FileChooserDialog(
				                          Mono.Unix.Catalog.GetString("Backup Bookmarks"), 
				                     	  this, Gtk.FileChooserAction.Save, 
				                          Mono.Unix.Catalog.GetString("Cancel"), Gtk.ResponseType.Cancel, 
			
				                          Mono.Unix.Catalog.GetString("Save"), Gtk.ResponseType.Ok);

			dialog.SetCurrentFolder(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal));
			dialog.CurrentName = string.Format("bareftp-bookmarks-{0}.xml", DateTime.Now.ToString("yyyy-MM-dd"));
			
			if(dialog.Run() == (int)Gtk.ResponseType.Ok)
			{
				try
				{
					System.IO.FileStream fs = new System.IO.FileStream(dialog.Filename, System.IO.FileMode.Create);
					doc.Save(fs);
				}
				catch(Exception ex)
				{
					bareFTP.Gui.Dialog.Dialogs.ErrorDialog(ex.Message);
				}
			}
			dialog.Destroy();
			
		}
		
		protected virtual void ImportBookmarks(object sender, EventArgs e)
		{
			Gtk.FileChooserDialog dialog = 
				new Gtk.FileChooserDialog(
				                          Mono.Unix.Catalog.GetString("Restore Bookmarks"), 
				                     	  this, Gtk.FileChooserAction.Open, 
				                          Mono.Unix.Catalog.GetString("Cancel"), Gtk.ResponseType.Cancel, 
			
				                          Mono.Unix.Catalog.GetString("Open"), Gtk.ResponseType.Ok);
			
			dialog.SetCurrentFolder(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal));
			
			if(dialog.Run() == (int)Gtk.ResponseType.Ok)
			{
				try
				{
					Bookmarks imp_bookmarks = new Bookmarks(dialog.Filename);
					if(imp_bookmarks.RootItem != null)
					{
						foreach(BookmarkItem item in imp_bookmarks.RootItem.Items)
						{
							Gtk.TreeIter iter = store.AppendValues(item);
							if(item is BookmarkFolder)
								CreateTreeItem(item, iter);
						}
					}
				}
				catch(Exception ex)
				{
					bareFTP.Gui.Dialog.Dialogs.ErrorDialog(ex.Message);
				}
			}
			dialog.Destroy();
			
		}
	}
}
