
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

//using Mono.Unix;

using Tomboy;

namespace Tomboy.Bugzilla
{
	public class BugzillaNoteAddin : NoteAddin
	{
		static int last_bug;

		public const string BugzillaLinkTagName = "link:bugzilla";

		static BugzillaNoteAddin ()
		{
			last_bug = -1;
		}

		public override void Initialize ()
		{
			if (!Note.TagTable.IsDynamicTagRegistered (BugzillaLinkTagName)) {
				Note.TagTable.RegisterDynamicTag (BugzillaLinkTagName, typeof (BugzillaLink));
			}
		}

		public override void Shutdown ()
		{
		}

		public override void OnNoteOpened ()
		{
			Window.Editor.DragDataReceived += OnDragDataReceived;
		}

		[DllImport("libgobject-2.0.so.0")]
		static extern void g_signal_stop_emission_by_name (IntPtr raw, string name);

		[GLib.ConnectBefore]
		void OnDragDataReceived (object sender, Gtk.DragDataReceivedArgs args)
		{
			Logger.Debug ("Bugzilla.OnDragDataReceived");
			foreach (Gdk.Atom atom in args.Context.Targets) {
				if (atom.Name == "text/uri-list" ||
				                atom.Name == "_NETSCAPE_URL") {
					DropUriList (args);
					return;
				}
			}
		}

		void DropUriList (Gtk.DragDataReceivedArgs args)
		{
			if (args.SelectionData.Length > 0) {
				string uriString = Encoding.UTF8.GetString (args.SelectionData.Data);

				string bugIdGroup = "bugid";
				string regexString =
				        @"show_bug\.cgi\?(\S+\&){0,1}id=(?<" + bugIdGroup + @">\d{5,})";

				Match match = Regex.Match (uriString, regexString);
				if (match.Success) {
					int bugId = int.Parse (match.Groups [bugIdGroup].Value);
					if (InsertBug (args.X, args.Y, uriString, bugId)) {
						Gtk.Drag.Finish (args.Context, true, false, args.Time);
						g_signal_stop_emission_by_name(Window.Editor.Handle,
						                               "drag_data_received");
					}
				}
			}
		}

		bool InsertBug (int x, int y, string uri, int id)
		{
			try {
				// Debounce.  I'm not sure why this is necessary :(
				if (id == last_bug) {
					last_bug = -1;
					return true;
				}
				last_bug = id;

				BugzillaLink link_tag = (BugzillaLink)
				                        Note.TagTable.CreateDynamicTag (BugzillaLinkTagName);
				link_tag.BugUrl = uri;

				// Place the cursor in the position where the uri was
				// dropped, adjusting x,y by the TextView's VisibleRect.
				Gdk.Rectangle rect = Window.Editor.VisibleRect;
				x = x + rect.X;
				y = y + rect.Y;
				Gtk.TextIter cursor = Window.Editor.GetIterAtLocation (x, y);
				Buffer.PlaceCursor (cursor);

				Buffer.Undoer.AddUndoAction (new InsertBugAction (cursor, id.ToString (), Buffer, link_tag));

				Gtk.TextTag[] tags = {link_tag};
				Buffer.InsertWithTags (ref cursor, id.ToString (), tags);
				return true;
			} catch {
			return false;
		}
	}
}
}