package com.one.file;

import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.microedition.io.Connection;

public class Connector
{
	public static final int READ = javax.microedition.io.Connector.READ;
	public static final int WRITE = javax.microedition.io.Connector.WRITE;
	public static final int READ_WRITE = javax.microedition.io.Connector.READ_WRITE;

	private static ConnectionProvider provider;
	private static Hashtable tempfiles = new Hashtable();
	private static String tempFileDir = "";

	public static void setConnectionProvider(ConnectionProvider cp)
	{
		provider = cp;
	}

	public static void setTempFileDir(String path)
	{
		tempFileDir = "";

		if(path != null)
		{
			try
			{
				FileConnection fc = openDirectConnection("file:///" + path, READ);

				if(fc.isDirectory() && fc.canWrite())
				{
					tempFileDir = path;
				}

				fc.close();
			}
			catch(Throwable t)
			{
			}
		}
	}

	public static String getTempFileDir()
	{
		return tempFileDir;
	}
	
	public static Connection open(String name) throws IOException
	{
		if(name.startsWith("file://"))
		{
			return TransparentConnector.open(name, READ_WRITE);
		}
		else
		{
			return javax.microedition.io.Connector.open(name);
		}
	}
	
	public static Connection open(String name, int mode) throws IOException
	{
		if(name.startsWith("file://"))
		{
			return TransparentConnector.open(name, mode);
		}
		else
		{
			return javax.microedition.io.Connector.open(name, mode);
		}
	}
	
	public static Connection open(String name, int mode, boolean timeouts) throws IOException
	{
		if(name.startsWith("file://"))
		{
			return TransparentConnector.open(name, mode);
		}
		else
		{
			return javax.microedition.io.Connector.open(name, mode, timeouts);
		}
	}
	
	public static InputStream openInputStream(String name) throws IOException
	{
		if(name.startsWith("file://"))
		{
			return new AFCInputStream((FileConnection)TransparentConnector.open(name, READ));
		}
		else
		{
			return javax.microedition.io.Connector.openInputStream(name);
		}
	}

	public static OutputStream openOutputStream(String name) throws IOException
	{
		if(name.startsWith("file://"))
		{
			return new AFCOutputStream((FileConnection)TransparentConnector.open(name, WRITE));
		}
		else
		{
			return javax.microedition.io.Connector.openOutputStream(name);
		}
	}

	public static DataInputStream openDataInputStream(String name) throws IOException
	{
		return new DataInputStream(openInputStream(name));
	}

	public static DataOutputStream openDataOutputStream(String name) throws IOException
	{
		return new DataOutputStream(openOutputStream(name));
	}
	
	public static Enumeration listRoots()
	{
		return provider.listRoots();
	}

	/**
	 * Открыть FileConnection напрямую из ФС.
	 *
	 * Методы open(), в отличие от этого, используют TransparentConnector
	 * для создания прозрачных соединений с архивами,
	 * а сам TransparentConnector вынужден использовать этот метод
	 * для открытия базовых файлов.
	 *
	 * @param name имя файла / папки для открытия
	 * @return FileConnection для этого файла / папки
	 * @throws IOException
	 */
	public static FileConnection openDirectConnection(String name, int mode) throws IOException
	{
		if(!name.startsWith("file:///"))
		{
			name = "file:///" + name;
		}

		return provider.convertFileConnection(javax.microedition.io.Connector.open(name, mode));
	}

	/**
	 * Создать уникальное имя (для временных файлов).
	 * @return например, "~12CF926007F.tmp"
	 */
	public static String createTempFileName()
	{
		return "~" + Long.toString(System.currentTimeMillis(), 16).toUpperCase() + ".tmp";
	}

	/**
	 * Открыть временный файл.
	 *
	 * Временный файл имеет всегда уникальное имя, и создается
	 * в ближайшей папке, которая расположена в реальной ФС
	 * (чтобы не писать в контейнеры вроде архивов,
	 * которые сами для записи требуют временный файл).
	 *
	 * Если задана папка для временных файлов,
	 * все временные файлы создаются в указанной папке.
	 *
	 * @param base путь или полное имя файла, рядом с которым будет создан временный файл
	 * @param exact true, если все таки надо создать файл ИМЕННО в указанной папке
	 * @return имя временного файла
	 */
	public static String createTempFile(String base, boolean exact)
	{
		base = noFirstSlash(base);

//		if(base != null)
//		{
//			base = noFirstSlash(base);
//		}
//		else if(tempFileDir.length() > 0)
//		{
//			exact = false;
//		}
//		else
//		{
//			throw new IOException("Neither base path nor temp file directory is set");
//		}
		
		if(exact)
		{
			base = base.substring(0, base.lastIndexOf('/') + 1);
		}
		else if(tempFileDir.length() > 0)
		{
			base = tempFileDir;
		}
		else
		{
			int index = base.indexOf(".");

			if(index >= 0)
			{
				base = base.substring(0, base.lastIndexOf('/', index) + 1);
			}
			else
			{
				base = base.substring(0, base.lastIndexOf('/') + 1);
			}
		}

		String filename = base + createTempFileName();
		tempfiles.put(filename, new Object());

		//System.out.println("Created temp file " + filename);

		return filename;
	}

	public static void releaseTempFile(String filename)
	{
		tempfiles.remove(noFirstSlash(filename));
	}

	public static boolean isTempFileUsed(String filename)
	{
		return tempfiles.get(noFirstSlash(filename)) != null;
	}

	protected static String noFirstSlash(String filename)
	{
		if(filename.startsWith("/"))
		{
			return filename.substring(1);
		}
		else
		{
			return filename;
		}
	}
}
