/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package malik.emulator.io.j2me;

import java.io.*;
import malik.emulator.fileformats.graphics.*;

public final class ImplementationManager extends Object
{
	public static final String PROPERTY_SYSTEM_GUI =
			"malik.emulator.microedition.system.gui.class";
	public static final String PROPERTY_IMAGE_DECODER =
			"malik.emulator.microedition.image.decoder.class";
	public static final String PROPERTY_PLAYER_MANAGER =
			"malik.emulator.microedition.player.manager.class";
	public static final String PROPERTY_CONNECTION_FACTORY =
			"malik.emulator.microedition.connection.factory.class";
	private static VirtualSystemGUI SYSTEM_GUI;
	private static VirtualImageDecoder IMAGE_DECODER;
	private static VirtualPlayerManager PLAYER_MANAGER;
	private static VirtualConnectionFactory CONNECTION_FACTORY;
	private static final Object LOCK;

	static
	{
		LOCK = new Object();
	}

	public static VirtualSystemGUI getSystemGUI()
	{
		VirtualSystemGUI result;
		synchronized(LOCK)
		{
			if((result = SYSTEM_GUI) == null)
			{
				try
				{
					result = SYSTEM_GUI = (VirtualSystemGUI) Class.forName(
							System.getSystemProperty(PROPERTY_SYSTEM_GUI)).newInstance();
				}
				catch(Exception e)
				{
					throw new ImplementationNotFoundError(
							"Реализация системного пользовательского интерфейса не найдена. " +
							"Проверьте файл свойств /config.properties и исходный код " +
							"системных библиотек.");
				}
			}
		}
		return result;
	}

	public static ImageDecoder getImageDecoder(InputStream src)
			throws IOException
	{
		VirtualImageDecoder result;
		synchronized(LOCK)
		{
			if((result = IMAGE_DECODER) == null)
			{
				try
				{
					result = IMAGE_DECODER = (VirtualImageDecoder) Class.forName(
							System.getSystemProperty(PROPERTY_IMAGE_DECODER)).newInstance();
				}
				catch(Exception e)
				{
					throw new ImplementationNotFoundError(
							"Реализация декодера изображений не найдена. " +
							"Проверьте файл свойств /config.properties и исходный код " +
							"системных библиотек.");
				}
			}
		}
		return result.getImageDecoder(src);
	}

	public static VirtualPlayerManager getPlayerManager()
	{
		VirtualPlayerManager result;
		synchronized(LOCK)
		{
			if((result = PLAYER_MANAGER) == null)
			{
				try
				{
					result = PLAYER_MANAGER = (VirtualPlayerManager) Class.forName(
							System.getSystemProperty(PROPERTY_PLAYER_MANAGER)).newInstance();
				}
				catch(Exception e)
				{
					throw new ImplementationNotFoundError(
							"Реализация системы проигрывания медиа-данных не найдена. " +
							"Проверьте файл свойств /config.properties и исходный код " +
							"системных библиотек.");
				}
			}
		}
		return result;
	}

	public static VirtualPlayerManagerExt getPlayerManagerExt()
	{
		VirtualPlayerManager result;
		synchronized(LOCK)
		{
			if((result = PLAYER_MANAGER) == null)
			{
				try
				{
					result = PLAYER_MANAGER = (VirtualPlayerManager) Class.forName(
							System.getSystemProperty(PROPERTY_PLAYER_MANAGER)).newInstance();
				}
				catch(Exception e)
				{
					throw new ImplementationNotFoundError(
							"Реализация системы проигрывания медиа-данных не найдена. " +
							"Проверьте файл свойств /config.properties и исходный код " +
							"системных библиотек.");
				}
			}
		}
		if(!(result instanceof VirtualPlayerManagerExt))
		{
			throw new ImplementationNotFoundError(
					"Реализация расширенной системы проигрывания медиа-данных (JSR-135) " +
					"не найдена. Проверьте файл свойств /config.properties и исходный код " +
					"системных библиотек.");
		}
		return (VirtualPlayerManagerExt) result;
	}

	public static VirtualConnectionFactory getConnectionFactory()
	{
		VirtualConnectionFactory result;
		synchronized(LOCK)
		{
			if((result = CONNECTION_FACTORY) == null)
			{
				try
				{
					result = CONNECTION_FACTORY = (VirtualConnectionFactory) Class.forName(
							System.getSystemProperty(PROPERTY_CONNECTION_FACTORY)).newInstance();
				}
				catch(Exception e)
				{
					throw new ImplementationNotFoundError(
							"Реализация системы создания соединений не найдена. " +
							"Проверьте файл свойств /config.properties и исходный код " +
							"системных библиотек.");
				}
			}
		}
		return result;
	}


	private ImplementationManager()
	{
	}
}
