/* copyright 	Maher Awamy <muhri@muhri.net>		*
 *							*
 *  released under the GPL				*/


/* Thanks for epiphany's code for making this a breeze for me */

#include "SkipStoneContentHandler.h"
#include "skipstone.h"
//#include <nsStringGlue.h>
#include <nsCOMPtr.h>
#include <nsIFile.h>
#include <nsIHelperAppLauncherDialog.h>
#include <nsIURI.h>

#include <nsCExternalHandlerService.h>
#include <nsComponentManagerUtils.h>
#include <nsIDOMWindow.h>
#include <nsIInterfaceRequestorUtils.h>
#include <nsILocalFile.h>
#include <nsIMIMEInfo.h>
#include <nsIURL.h>
#include <nsMemory.h>
#include <nsNetError.h>
#ifndef CVS_MOZILLA
#include <nsServiceManagerUtils.h>
#endif
extern ConfigData config;
extern "C" gboolean download_url(const gchar *uri);

NS_GENERIC_FACTORY_CONSTRUCTOR(GContentHandler)

static const nsModuleComponentInfo sAppComps[] = {

	{
		NS_IHELPERAPPLAUNCHERDLG_CLASSNAME,
		G_CONTENTHANDLER_CID,
		NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
		GContentHandlerConstructor
	}
};


  
extern "C" void register_ch(void)
{

	nsresult rv;

	nsCOMPtr<nsIComponentRegistrar> cr;
	NS_GetComponentRegistrar(getter_AddRefs(cr));


	nsCOMPtr<nsIComponentManager> cm;
	NS_GetComponentManager (getter_AddRefs (cm));


	for (guint i = 0; i < G_N_ELEMENTS (sAppComps); i++)
	{
		nsCOMPtr<nsIGenericFactory> componentFactory;
		rv = NS_NewGenericFactory(getter_AddRefs(componentFactory),
					  &(sAppComps[i]));
		if (NS_FAILED(rv) || !componentFactory)
		{
			g_warning ("Failed to make a factory for %s\n", sAppComps[i].mDescription);


			continue;  // don't abort registering other components
		}

		rv = cr->RegisterFactory(sAppComps[i].mCID,
					 sAppComps[i].mDescription,
					 sAppComps[i].mContractID,
					 componentFactory);
		if (NS_FAILED(rv))
		{
			g_warning ("Failed to register %s\n", sAppComps[i].mDescription);


		}

		if (sAppComps[i].mRegisterSelfProc)
		{
			rv = sAppComps[i].mRegisterSelfProc (cm, nsnull, nsnull, nsnull, &sAppComps[i]);

			if (NS_FAILED (rv))
			{
				g_warning ("Failed to register-self for %s\n", sAppComps[i].mDescription);

			}
		}
	}




}
  
  

GContentHandler::GContentHandler()
: mMimeType(nsnull)
, mUserTime(0)
{

}


GContentHandler::~GContentHandler()
{

}

NS_IMPL_ISUPPORTS1(GContentHandler, nsIHelperAppLauncherDialog)


NS_IMETHODIMP
GContentHandler::Show (nsIHelperAppLauncher *aLauncher,
		       nsISupports *aContext,
#ifndef CVS_MOZILLA
		       PRUint32  aForced)
#else
                       PRBool aForced)
#endif  

{
	nsresult rv;

	gboolean handled = FALSE;


	mContext = aContext;
	mLauncher = aLauncher;
	rv = Init ();
	NS_ENSURE_SUCCESS (rv, rv);


	if (!handled)
	{
		MIMEInitiateAction ();
	}
	else
	{
#ifndef CVS_MOZILLA
		mLauncher->Cancel (NS_BINDING_ABORTED);
#else
	        mLauncher->Cancel();
#endif	   
	}

	return NS_OK;
}

/* nsILocalFile promptForSaveToFile (in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */
NS_IMETHODIMP GContentHandler::PromptForSaveToFile(
				    nsIHelperAppLauncher *aLauncher,			    
				    nsISupports *aWindowContext,
				    const PRUnichar *aDefaultFile,
				    const PRUnichar *aSuggestedFileExtension,
				    nsILocalFile **_retval)
{

     char *filename = NULL;
     gint response;
     nsEmbedCString defaultFile;
     GtkWidget *dialog;

	NS_UTF16ToCString (nsEmbedString (aDefaultFile),
			   NS_CSTRING_ENCODING_UTF8, defaultFile);

     filename = (char *)defaultFile.get();

     if (config.use_skipstone_mime) {
	  gboolean downloaded = download_url(mUrl.get());
	  if (downloaded) return NS_OK;
     }
	nsCOMPtr<nsIDOMWindow> parentDOMWindow = do_GetInterface (aWindowContext);

     dialog = gtk_file_chooser_dialog_new("Save", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, NULL);
     gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			    GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
     gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), defaultFile.get());
     response = gtk_dialog_run(GTK_DIALOG(dialog));
     filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
	if (response == GTK_RESPONSE_ACCEPT)
	{
		nsCOMPtr <nsILocalFile> destFile (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
		NS_ENSURE_TRUE (destFile, NS_ERROR_FAILURE);
		destFile->InitWithNativePath (nsEmbedCString (filename));
	        g_free (filename);
		NS_IF_ADDREF (*_retval = destFile);	     
	        gtk_widget_destroy(dialog);
		return NS_OK;
	}
     
     gtk_widget_destroy(dialog);
     return NS_ERROR_FAILURE;

}

NS_METHOD GContentHandler::Init ()
{
	nsresult rv;

	NS_ENSURE_TRUE (mLauncher, NS_ERROR_FAILURE);
     
	nsCOMPtr<nsIMIMEInfo> MIMEInfo;
	mLauncher->GetMIMEInfo (getter_AddRefs(MIMEInfo));
	NS_ENSURE_TRUE (MIMEInfo, NS_ERROR_FAILURE);

//	rv = MIMEInfo->GetMIMEType (mMimeType);

	nsCOMPtr<nsIURI> uri;
	mLauncher->GetSource (getter_AddRefs(uri));
	NS_ENSURE_TRUE (uri, NS_ERROR_FAILURE);
	
	uri->GetSpec (mUrl);

	return NS_OK;
}



NS_METHOD GContentHandler::MIMEInitiateAction (void)
{
     MIMEDoAction();
     return NS_OK;
}

NS_METHOD GContentHandler::MIMEDoAction (void)
{

     mLauncher->SaveToDisk (nsnull, PR_FALSE);
     return NS_OK;
}
