#define MOZILLA_INTERNAL_API 1
#include "gtkmozembed.h"
#include "gtkmozembed_internal.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDocShell.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsIWebBrowser.h"
#include "nsIDOMNodeList.h"
#include "nsIDocument.h"
#include "nsReadableUtils.h"
#include "nsIContentViewer.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"

static nsIDocShell *mozilla_get_docshell(GtkMozEmbed *b);

extern "C" gboolean GetFavIconURL (GtkMozEmbed *b, gchar **favicon_url)
{
	nsresult result;
	PRUint32 links_count;
	char *relstr;

   nsCOMPtr<nsIDocShell> docShell = mozilla_get_docshell(b);
   if (!docShell) return FALSE;

   nsCOMPtr<nsIContentViewer> cv;
   result = docShell->GetContentViewer(getter_AddRefs(cv));
   if (!NS_SUCCEEDED(result) || !cv) 	return FALSE;
   
   
     nsCOMPtr<nsIDOMDocument> aDOMDocument;
   result = cv->GetDOMDocument(getter_AddRefs(aDOMDocument));

	if (!NS_SUCCEEDED(result) || !aDOMDocument) return FALSE;

   

	nsString strname;
	strname.AssignWithConversion("LINK");

	nsCOMPtr<nsIDOMNodeList> aLinks;
	result = aDOMDocument->GetElementsByTagName (strname, 
						     getter_AddRefs (aLinks));
	if (NS_FAILED (result))  return FALSE;

   

	result = aLinks->GetLength (&links_count);
	if (NS_FAILED (result))  return FALSE;

   
	for (PRUint32 i = 0; i < links_count; i++)
	{
		nsCOMPtr<nsIDOMNode> aLink;
		result = aLinks->Item (i, getter_AddRefs (aLink));
		if (NS_FAILED (result)) return FALSE;

	   
		nsCOMPtr<nsIDOMElement> linkElement;
		linkElement = do_QueryInterface (aLink);
		if (!linkElement) return FALSE;

	   

		nsAutoString attr;
		attr.AssignWithConversion("rel");
		nsAutoString value;
		linkElement->GetAttribute (attr, value);
		relstr = ToNewCString (value);
		g_strup (relstr);

		if (!strcmp(relstr, "SHORTCUT ICON") || !strcmp(relstr, "ICON"))
		{

			
			nsMemory::Free (relstr);

			nsAutoString attr;
			attr.AssignWithConversion("href");
			nsAutoString value;
			linkElement->GetAttribute (attr, value);
			if (value.IsEmpty()) continue;

			
			nsCOMPtr<nsIDocument> doc = 
				do_QueryInterface (aDOMDocument);
			if(!doc) return FALSE;
			
			nsCString link, favicon_urlc;
		     	link.AssignWithConversion(value);
		   
			
			nsCOMPtr<nsIURI> uri;
/*#ifdef CVS_MOZILLA
			uri = doc->GetDocumentURL();
#else*/
		        uri = doc->GetDocumentURI ();
/*#endif*/
			result = uri->Resolve (link, favicon_urlc);
			if (NS_FAILED (result)) return FALSE;	
		     	
		     	*favicon_url = ToNewCString(favicon_urlc);

			return TRUE;
		}
	}

	return FALSE;
}

static nsIDocShell *mozilla_get_docshell(GtkMozEmbed *b)
{
     	nsresult result ;	

	/* get nsIBrowser */
	nsIWebBrowser *wb = nsnull;
	gtk_moz_embed_get_nsIWebBrowser(b,&wb);
	nsCOMPtr<nsIDocShell> docShell;

        nsCOMPtr<nsIDocShellTreeItem> browserAsItem;
	browserAsItem = do_QueryInterface(wb);
     	if (!browserAsItem) return NULL;
	// get the tree owner for that item
	nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
	result = browserAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
     	if (!NS_SUCCEEDED(result) || !treeOwner) return NULL;
	// get the primary content shell as an item
	nsCOMPtr<nsIDocShellTreeItem> contentItem;
	result = treeOwner->GetPrimaryContentShell(getter_AddRefs(contentItem));
     	if (!NS_SUCCEEDED(result) || !contentItem) return NULL;
	// QI that back to a docshell
	docShell = do_QueryInterface(contentItem);

     	return docShell;
}
