/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

import com.sun.star.uno.UnoRuntime;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
import com.sun.star.script.framework.runtime.XScriptContext;
import com.sun.star.util.XStringSubstitution;

import javax.mail.*;
import javax.activation.*;

import java.io.*;


public class MimeConfiguration
{

	// Office Installation path
	private static String instPath = "";


	public static boolean createFiles( XScriptContext xsc )
	{
		try
		{
			XComponentContext xcc = xsc.getComponentContext();
			XMultiComponentFactory xmf = xcc.getServiceManager();

			Object pathSub = xmf.createInstanceWithContext( "com.sun.star.comp.framework.PathSubstitution", xcc );
			XStringSubstitution stringSub = ( XStringSubstitution ) UnoRuntime.queryInterface( XStringSubstitution.class, pathSub );
			instPath = stringSub.getSubstituteVariableValue( "$(inst)" );

		}
		catch( com.sun.star.beans.UnknownPropertyException upe )
		{
			System.out.println( "com.sun.star.beans.UnknownPropertyException" );
			upe.printStackTrace();
		}
		catch( com.sun.star.uno.Exception e )
		{
			System.out.println( "com.sun.star.uno.Exception" );
			e.printStackTrace();
		}

		writeMailCap();
		writeMimeTypes();

		// ToDo: include status feedback to StatusWindow
		return true;
	}




	private static void writeMailCap()
	{
		String mailcapPath = getConfigDir() + System.getProperty( "file.separator" ) + "mailcap";

		try
		{
	                if( ! new File( java.net.URLDecoder.decode( mailcapPath )  ).exists() )
       	                {
				//System.out.println( "URLDecoder: " + java.net.URLDecoder.decode( mailcapPath ) );
				File mailcapFile = new File( mailcapPath );
				FileWriter out = new FileWriter( mailcapFile );
				String[] lines = getMailcapText();
				for( int i=0; i<lines.length; i++ )
				{
					out.write( lines[i], 0, lines[i].length() );
				}
				out.close();
                	}
                	else
                	{
				//System.out.println( "URLDecoder: " + java.net.URLDecoder.decode( mailcapPath ) );
                	}



			// use prog dir, if not there then java.io to create/write new file
			MailcapCommandMap map = new MailcapCommandMap( mailcapPath );
			CommandMap.setDefaultCommandMap ( map );
		}
		catch( IOException ioe )
		{
			ioe.printStackTrace();
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}
	}


	private static String[] getMailcapText()
	{
		String[] mailcapText = {
			"#\n",
			"# Default mailcap file for the JavaMail System.\n",
			"#\n",
			"# JavaMail content-handlers:\n",
			"#\n",
			"text/plain;;            x-java-content-handler=com.sun.mail.handlers.text_plain\n",
			"text/html;;             x-java-content-handler=com.sun.mail.handlers.text_html\n",
			"text/xml;;              x-java-content-handler=com.sun.mail.handlers.text_xml\n",
			"image/gif;;             x-java-content-handler=com.sun.mail.handlers.image_gif\n",
			"image/jpeg;;            x-java-content-handler=com.sun.mail.handlers.image_jpeg\n",
			"multipart/*;;           x-java-content-handler=com.sun.mail.handlers.multipart_mixed\n",
			"message/rfc822;;        x-java-content-handler=com.sun.mail.handlers.message_rfc822\n"
		};

		return mailcapText;
	}



	private static void writeMimeTypes()
	{
		String mimetypesPath = getConfigDir() + System.getProperty( "file.separator" ) + "mimetypes.default";

		try
		{
	                if( ! new File( java.net.URLDecoder.decode( mimetypesPath )  ).exists() )
       	                {
				//System.out.println( "URLDecoder: " + java.net.URLDecoder.decode( mimetypesPath ) );
				File mimetypesFile = new File( mimetypesPath );
				FileWriter out = new FileWriter( mimetypesFile );
				String[] lines = getMimeTypesText();
				for( int i=0; i<lines.length; i++ )
				{
					out.write( lines[i], 0, lines[i].length() );
				}
				out.close();
                	}
                	else
                	{
				//System.out.println( "URLDecoder: " + java.net.URLDecoder.decode( mimetypesPath ) );
                	}

			MimetypesFileTypeMap mimeTypes = new MimetypesFileTypeMap( mimetypesPath );
                    	FileTypeMap.setDefaultFileTypeMap( mimeTypes );
		}
		catch( IOException ioe )
		{
			ioe.printStackTrace();
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}
	}


	private static String[] getMimeTypesText()
	{
		String[] mimesText = {
			"#\n",
			"# A simple, old format, mime.types file\n",
			"#\n",
			"text/html               html htm HTML HTM\n",
			"text/plain              txt text TXT TEXT\n",
			"image/gif               gif GIF\n",
			"image/ief               ief\n",
			"image/jpeg              jpeg jpg jpe JPG\n",
			"image/tiff              tiff tif\n",
			"image/x-xwindowdump     xwd\n",
			"application/postscript  ai eps ps\n",
			"application/rtf         rtf\n",
			"application/x-tex       tex\n",
			"application/x-texinfo   texinfo texi\n",
			"application/x-troff     t tr roff\n",
			"audio/basic             au\n",
			"audio/midi              midi mid\n",
			"audio/x-aifc            aifc\n",
			"audio/x-aiff            aif aiff\n",
			"audio/x-mpeg            mpeg mpg\n",
			"audio/x-wav             wav\n",
			"video/mpeg              mpeg mpg mpe\n",
			"video/quicktime         qt mov\n",
			"video/x-msvideo         avi\n"
		};

		return mimesText;
	}


	private static String getConfigDir()
	{
		// mailcap file must be written to the Office user/config  directory

                // instPath is a URL, needs to be converted to a system pathname
                String config = instPath + "/user/config";
                String configNonURL = "";

                if( System.getProperty( "os.name" ).indexOf( "Windows" ) != -1 )
                {
                        // Windows
                        // removes "file:///"
                        int start = 8;
                        configNonURL = config.substring( start, config.length() );
                        // Convert forward to back-slashes
                        while( configNonURL.indexOf( "/" ) != -1 )
                        {
                                int fSlash = configNonURL.indexOf( "/" );
                                String firstPart = configNonURL.substring( 0, fSlash );
                                String secondPart = configNonURL.substring( fSlash + 1, configNonURL.length() );
                                configNonURL = firstPart + "\\" + secondPart;
                        }
                }
                else
                {
                        // Unix/Linux
                        // removes "file://"
                        int start = 7;
                        configNonURL = config.substring( start, config.length() );
                }

		return configNonURL;
	}

}
