// -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-

//
//  Copyright (C) 2003 Takuro Ashie
//
//  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, 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.
//

// Some codes are taken from Epiphany 0.8.2
// Copyright (C) 2000-2003 Marco Pesenti Gritti

// samples of nsISelection are:
//   content/base/src/nsDocumentViewer.cpp
//   layout/base/src/nsCaret.cpp


#include <kz-mozselectionlistener.h>
#include <gtkmozembed_internal.h>

#include <nsIInterfaceRequestorUtils.h>
#include <docshell/nsIDocShell.h>
#include <docshell/nsIDocShellTreeItem.h>
#include <docshell/nsIDocShellTreeOwner.h>
#include <docshell/nsIContentViewer.h>
#include <nsISelection.h>
#include <content/nsISelectionPrivate.h>
#include <nsIClipboardCommands.h>
#include <nsLiteralString.h>
#include <nsString.h>
#include <nsIDOMElement.h>
#include <nsIDocument.h>
#include <nsIURI.h>
#include <nsIWebBrowserFocus.h>
#include <nsIWebPageDescriptor.h>
#include <nsIMarkupDocumentViewer.h>
#include <nsIDOMWindowInternal.h>
#include <nsIChromeEventHandler.h>


#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif /* HAVE_CONFIG_H */

KzMozSelectionListener::KzMozSelectionListener () :
	mKzMozEmbed (nsnull),
	mWebBrowser (nsnull),
	mSelectionWasCollapsed (PR_TRUE)
{
}


KzMozSelectionListener::~KzMozSelectionListener ()
{
}


NS_IMPL_ISUPPORTS1(KzMozSelectionListener, nsISelectionListener)


nsresult
KzMozSelectionListener::Init (KzMozEmbed *kzembed)
{
	mKzMozEmbed = kzembed;
	gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(mKzMozEmbed),
					getter_AddRefs(mWebBrowser));
	if (!mWebBrowser) return NS_ERROR_FAILURE;

	return NS_OK;
}


void
KzMozSelectionListener::Destroy (void)
{
	mKzMozEmbed = nsnull;
	mWebBrowser = nsnull;
}


//
// SelectionListener implementation
//

NS_IMETHODIMP
KzMozSelectionListener::NotifySelectionChanged (nsIDOMDocument *doc,
						nsISelection *sel,
						PRInt16 reason)
{
	g_print("notify selection changed\n");
	return NS_OK;
}


nsresult
KzMozSelectionListener::AddSelectionListener (void)
{
	nsresult rv;
	nsCOMPtr<nsIDOMWindow> domWindow;

	nsCOMPtr<nsIWebBrowserFocus> focus = do_GetInterface(mWebBrowser, &rv);
	if (NS_FAILED(rv) || !focus) return NS_ERROR_FAILURE;

	rv = focus->GetFocusedWindow (getter_AddRefs(domWindow));
	if (NS_FAILED(rv))
		rv = mWebBrowser->GetContentDOMWindow (getter_AddRefs(domWindow));
	
	if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

	nsCOMPtr<nsISelection> selection;
	rv = domWindow->GetSelection(getter_AddRefs(selection));
	if (!selection) return NS_ERROR_FAILURE;

	nsCOMPtr<nsISelectionPrivate> selectionPriv;
	selectionPriv = do_QueryInterface(selection);
	if (!selectionPriv) return NS_ERROR_FAILURE;

	return selectionPriv->AddSelectionListener(this);
}


nsresult
KzMozSelectionListener::RemoveSelectionListener (void)
{
	nsresult rv;
	nsCOMPtr<nsIDOMWindow> domWindow;

	nsCOMPtr<nsIWebBrowserFocus> focus = do_GetInterface(mWebBrowser, &rv);
	if (NS_FAILED(rv) || !focus) return NS_ERROR_FAILURE;

	rv = focus->GetFocusedWindow (getter_AddRefs(domWindow));
	if (NS_FAILED(rv))
		rv = mWebBrowser->GetContentDOMWindow (getter_AddRefs(domWindow));
	
	if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

	nsCOMPtr<nsISelection> selection;
	rv = domWindow->GetSelection(getter_AddRefs(selection));
	if (!selection) return NS_ERROR_FAILURE;

	nsCOMPtr<nsISelectionPrivate> selectionPriv;
	selectionPriv = do_QueryInterface(selection);
	if (!selectionPriv) return NS_ERROR_FAILURE;

	return selectionPriv->RemoveSelectionListener(this);
}
