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

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

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

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

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


package javax.microedition.lcdui;

import java.io.*;
import javax.microedition.midlet.*;
import malik.emulator.application.*;
import malik.emulator.fileformats.text.mapped.*;
import malik.emulator.io.cloud.*;
import malik.emulator.io.j2me.*;
import malik.emulator.media.graphics.RasterCanvas;
import malik.emulator.media.text.*;
import malik.emulator.util.*;

public class MIDletProxy extends Object
		implements AppProxy
{
	private static final class MIDletStartEvent extends Object
			implements Runnable
	{
		private VirtualSystemGUI systemGUI;

		public MIDletStartEvent(VirtualSystemGUI systemGUI)
		{
			this.systemGUI = systemGUI;
		}

		public void run()
		{
			systemGUI.onMIDletStarted();
		}
	}

	private static final class MIDletDestroyEvent extends Object
			implements Runnable
	{
		private VirtualSystemGUI systemGUI;

		public MIDletDestroyEvent(VirtualSystemGUI systemGUI)
		{
			this.systemGUI = systemGUI;
		}

		public void run()
		{
			systemGUI.onMIDletDestroyed();
		}
	}

	public static final int DEVICE_KEY_1 = 0x31;
	public static final int DEVICE_KEY_2 = 0x32;
	public static final int DEVICE_KEY_3 = 0x33;
	public static final int DEVICE_KEY_4 = 0x34;
	public static final int DEVICE_KEY_5 = 0x35;
	public static final int DEVICE_KEY_6 = 0x36;
	public static final int DEVICE_KEY_7 = 0x37;
	public static final int DEVICE_KEY_8 = 0x38;
	public static final int DEVICE_KEY_9 = 0x39;
	public static final int DEVICE_KEY_STAR = 0x2a;
	public static final int DEVICE_KEY_0 = 0x30;
	public static final int DEVICE_KEY_POUND = 0x23;
	public static final int DEVICE_KEY_UP = 0x26;
	public static final int DEVICE_KEY_DOWN = 0x24;
	public static final int DEVICE_KEY_LEFT = 0x28;
	public static final int DEVICE_KEY_RIGHT = 0x29;
	public static final int DEVICE_KEY_SELECT = 0x2b;
	public static final int DEVICE_KEY_SOFT1 = 0x25;
	public static final int DEVICE_KEY_SOFT2 = 0x27;
	public static final int DEVICE_KEY_CONSOLE = 0x2c;
	public static final int DEVICE_KEY_EXITAPP = 0x2e;
	public static final int FONT_STYLE_PLAIN = 0x00;
	public static final int FONT_STYLE_BOLD = 0x01;
	public static final int FONT_STYLE_ITALIC = 0x02;
	public static final int FONT_STYLE_BOLD_ITALIC = 0x03;
	public static final int FONT_SIZE_MEDIUM = 0x00;
	public static final int FONT_SIZE_SMALL = 0x01;
	public static final int FONT_SIZE_LARGE = 0x02;
	private static MIDletProxy INSTANCE;
	private static final String MIDLET_DESCRIPTOR = "/res/META-INF/MANIFEST.MF";
	private static final String MIDLET_PROPERTIES = "/midlet.properties";

	public static int getSystemKeyCode(String keyName)
	{
		if(keyName == null)
			return 0;
		if("BACKSPACE".equals(keyName))
			return KEY_BACKSPACE;
		if("TAB".equals(keyName))
			return KEY_TAB;
		if("ENTER".equals(keyName))
			return KEY_ENTER;
		if("SHIFT".equals(keyName))
			return KEY_SHIFT;
		if("CTRL".equals(keyName))
			return KEY_CTRL;
		if("ALT".equals(keyName))
			return KEY_ALT;
		if("PAUSE_BREAK".equals(keyName))
			return KEY_PAUSE_BREAK;
		if("CAPS_LOCK".equals(keyName))
			return KEY_CAPS_LOCK;
		if("ESCAPE".equals(keyName))
			return KEY_ESCAPE;
		if("SPACE".equals(keyName))
			return KEY_SPACE;
		if("PAGE_UP".equals(keyName))
			return KEY_PAGE_UP;
		if("PAGE_DOWN".equals(keyName))
			return KEY_PAGE_DOWN;
		if("END".equals(keyName))
			return KEY_END;
		if("HOME".equals(keyName))
			return KEY_HOME;
		if("LEFT".equals(keyName))
			return KEY_LEFT;
		if("UP".equals(keyName))
			return KEY_UP;
		if("RIGHT".equals(keyName))
			return KEY_RIGHT;
		if("DOWN".equals(keyName))
			return KEY_DOWN;
		if("INSERT".equals(keyName))
			return KEY_INSERT;
		if("DELETE".equals(keyName))
			return KEY_DELETE;
		if("0".equals(keyName))
			return KEY_0;
		if("1".equals(keyName))
			return KEY_1;
		if("2".equals(keyName))
			return KEY_2;
		if("3".equals(keyName))
			return KEY_3;
		if("4".equals(keyName))
			return KEY_4;
		if("5".equals(keyName))
			return KEY_5;
		if("6".equals(keyName))
			return KEY_6;
		if("7".equals(keyName))
			return KEY_7;
		if("8".equals(keyName))
			return KEY_8;
		if("9".equals(keyName))
			return KEY_9;
		if("A".equals(keyName))
			return KEY_A;
		if("B".equals(keyName))
			return KEY_B;
		if("C".equals(keyName))
			return KEY_C;
		if("D".equals(keyName))
			return KEY_D;
		if("E".equals(keyName))
			return KEY_E;
		if("F".equals(keyName))
			return KEY_F;
		if("G".equals(keyName))
			return KEY_G;
		if("H".equals(keyName))
			return KEY_H;
		if("I".equals(keyName))
			return KEY_I;
		if("J".equals(keyName))
			return KEY_J;
		if("K".equals(keyName))
			return KEY_K;
		if("L".equals(keyName))
			return KEY_L;
		if("M".equals(keyName))
			return KEY_M;
		if("N".equals(keyName))
			return KEY_N;
		if("O".equals(keyName))
			return KEY_O;
		if("P".equals(keyName))
			return KEY_P;
		if("Q".equals(keyName))
			return KEY_Q;
		if("R".equals(keyName))
			return KEY_R;
		if("S".equals(keyName))
			return KEY_S;
		if("T".equals(keyName))
			return KEY_T;
		if("U".equals(keyName))
			return KEY_U;
		if("V".equals(keyName))
			return KEY_V;
		if("W".equals(keyName))
			return KEY_W;
		if("X".equals(keyName))
			return KEY_X;
		if("Y".equals(keyName))
			return KEY_Y;
		if("Z".equals(keyName))
			return KEY_Z;
		if("CONTEXT".equals(keyName))
			return KEY_CONTEXT;
		if("NUM_0".equals(keyName))
			return KEY_NUM_0;
		if("NUM_1".equals(keyName))
			return KEY_NUM_1;
		if("NUM_2".equals(keyName))
			return KEY_NUM_2;
		if("NUM_3".equals(keyName))
			return KEY_NUM_3;
		if("NUM_4".equals(keyName))
			return KEY_NUM_4;
		if("NUM_5".equals(keyName))
			return KEY_NUM_5;
		if("NUM_6".equals(keyName))
			return KEY_NUM_6;
		if("NUM_7".equals(keyName))
			return KEY_NUM_7;
		if("NUM_8".equals(keyName))
			return KEY_NUM_8;
		if("NUM_9".equals(keyName))
			return KEY_NUM_9;
		if("NUM_STAR".equals(keyName))
			return KEY_NUM_STAR;
		if("NUM_PLUS".equals(keyName))
			return KEY_NUM_PLUS;
		if("NUM_SEPARATOR".equals(keyName))
			return KEY_NUM_SEPARATOR;
		if("NUM_MINUS".equals(keyName))
			return KEY_NUM_MINUS;
		if("NUM_DECIMAL".equals(keyName))
			return KEY_NUM_DECIMAL;
		if("NUM_DIVIDE".equals(keyName))
			return KEY_NUM_DIVIDE;
		if("F1".equals(keyName))
			return KEY_F1;
		if("F2".equals(keyName))
			return KEY_F2;
		if("F3".equals(keyName))
			return KEY_F3;
		if("F4".equals(keyName))
			return KEY_F4;
		if("F5".equals(keyName))
			return KEY_F5;
		if("F6".equals(keyName))
			return KEY_F6;
		if("F7".equals(keyName))
			return KEY_F7;
		if("F8".equals(keyName))
			return KEY_F8;
		if("F9".equals(keyName))
			return KEY_F9;
		if("F10".equals(keyName))
			return KEY_F10;
		if("F11".equals(keyName))
			return KEY_F11;
		if("F12".equals(keyName))
			return KEY_F12;
		if("F13".equals(keyName))
			return KEY_F13;
		if("F14".equals(keyName))
			return KEY_F14;
		if("F15".equals(keyName))
			return KEY_F15;
		if("F16".equals(keyName))
			return KEY_F16;
		if("F17".equals(keyName))
			return KEY_F17;
		if("F18".equals(keyName))
			return KEY_F18;
		if("F19".equals(keyName))
			return KEY_F19;
		if("F20".equals(keyName))
			return KEY_F20;
		if("F21".equals(keyName))
			return KEY_F21;
		if("F22".equals(keyName))
			return KEY_F22;
		if("F23".equals(keyName))
			return KEY_F23;
		if("F24".equals(keyName))
			return KEY_F24;
		if("NUM_LOCK".equals(keyName))
			return KEY_NUM_LOCK;
		if("SCROLL_LOCK".equals(keyName))
			return KEY_SCROLL_LOCK;
		if("LSHIFT".equals(keyName))
			return KEY_LSHIFT;
		if("RSHIFT".equals(keyName))
			return KEY_RSHIFT;
		if("LCTRL".equals(keyName))
			return KEY_LCTRL;
		if("RCTRL".equals(keyName))
			return KEY_RCTRL;
		if("LALT".equals(keyName))
			return KEY_LALT;
		if("RALT".equals(keyName))
			return KEY_RALT;
		if("SEMICOLON".equals(keyName))
			return KEY_SEMICOLON;
		if("EQUAL".equals(keyName))
			return KEY_EQUAL;
		if("COMMA".equals(keyName))
			return KEY_COMMA;
		if("MINUS".equals(keyName))
			return KEY_MINUS;
		if("PERIOD".equals(keyName))
			return KEY_PERIOD;
		if("SLASH".equals(keyName))
			return KEY_SLASH;
		if("GRAVE".equals(keyName))
			return KEY_GRAVE;
		if("LBRACKET".equals(keyName))
			return KEY_LBRACKET;
		if("BACKSLASH".equals(keyName))
			return KEY_BACKSLASH;
		if("RBRACKET".equals(keyName))
			return KEY_RBRACKET;
		if("APOSTROPHE".equals(keyName))
			return KEY_APOSTROPHE;
		return 0;
	}

	public static String getSystemKeyName(int key)
	{
		switch(key)
		{
		case KEY_BACKSPACE:
			return "BACKSPACE";
		case KEY_TAB:
			return "TAB";
		case KEY_ENTER:
			return "ENTER";
		case KEY_SHIFT:
			return "SHIFT";
		case KEY_CTRL:
			return "CTRL";
		case KEY_ALT:
			return "ALT";
		case KEY_PAUSE_BREAK:
			return "PAUSE_BREAK";
		case KEY_CAPS_LOCK:
			return "CAPS_LOCK";
		case KEY_ESCAPE:
			return "ESCAPE";
		case KEY_SPACE:
			return "SPACE";
		case KEY_PAGE_UP:
			return "PAGE_UP";
		case KEY_PAGE_DOWN:
			return "PAGE_DOWN";
		case KEY_END:
			return "END";
		case KEY_HOME:
			return "HOME";
		case KEY_LEFT:
			return "LEFT";
		case KEY_UP:
			return "UP";
		case KEY_RIGHT:
			return "RIGHT";
		case KEY_DOWN:
			return "DOWN";
		case KEY_INSERT:
			return "INSERT";
		case KEY_DELETE:
			return "DELETE";
		case KEY_0:
			return "0";
		case KEY_1:
			return "1";
		case KEY_2:
			return "2";
		case KEY_3:
			return "3";
		case KEY_4:
			return "4";
		case KEY_5:
			return "5";
		case KEY_6:
			return "6";
		case KEY_7:
			return "7";
		case KEY_8:
			return "8";
		case KEY_9:
			return "9";
		case KEY_A:
			return "A";
		case KEY_B:
			return "B";
		case KEY_C:
			return "C";
		case KEY_D:
			return "D";
		case KEY_E:
			return "E";
		case KEY_F:
			return "F";
		case KEY_G:
			return "G";
		case KEY_H:
			return "H";
		case KEY_I:
			return "I";
		case KEY_J:
			return "J";
		case KEY_K:
			return "K";
		case KEY_L:
			return "L";
		case KEY_M:
			return "M";
		case KEY_N:
			return "N";
		case KEY_O:
			return "O";
		case KEY_P:
			return "P";
		case KEY_Q:
			return "Q";
		case KEY_R:
			return "R";
		case KEY_S:
			return "S";
		case KEY_T:
			return "T";
		case KEY_U:
			return "U";
		case KEY_V:
			return "V";
		case KEY_W:
			return "W";
		case KEY_X:
			return "X";
		case KEY_Y:
			return "Y";
		case KEY_Z:
			return "Z";
		case KEY_CONTEXT:
			return "CONTEXT";
		case KEY_NUM_0:
			return "NUM_0";
		case KEY_NUM_1:
			return "NUM_1";
		case KEY_NUM_2:
			return "NUM_2";
		case KEY_NUM_3:
			return "NUM_3";
		case KEY_NUM_4:
			return "NUM_4";
		case KEY_NUM_5:
			return "NUM_5";
		case KEY_NUM_6:
			return "NUM_6";
		case KEY_NUM_7:
			return "NUM_7";
		case KEY_NUM_8:
			return "NUM_8";
		case KEY_NUM_9:
			return "NUM_9";
		case KEY_NUM_STAR:
			return "NUM_STAR";
		case KEY_NUM_PLUS:
			return "NUM_PLUS";
		case KEY_NUM_SEPARATOR:
			return "NUM_SEPARATOR";
		case KEY_NUM_MINUS:
			return "NUM_MINUS";
		case KEY_NUM_DECIMAL:
			return "NUM_DECIMAL";
		case KEY_NUM_DIVIDE:
			return "NUM_DIVIDE";
		case KEY_F1:
			return "F1";
		case KEY_F2:
			return "F2";
		case KEY_F3:
			return "F3";
		case KEY_F4:
			return "F4";
		case KEY_F5:
			return "F5";
		case KEY_F6:
			return "F6";
		case KEY_F7:
			return "F7";
		case KEY_F8:
			return "F8";
		case KEY_F9:
			return "F9";
		case KEY_F10:
			return "F10";
		case KEY_F11:
			return "F11";
		case KEY_F12:
			return "F12";
		case KEY_F13:
			return "F13";
		case KEY_F14:
			return "F14";
		case KEY_F15:
			return "F15";
		case KEY_F16:
			return "F16";
		case KEY_F17:
			return "F17";
		case KEY_F18:
			return "F18";
		case KEY_F19:
			return "F19";
		case KEY_F20:
			return "F20";
		case KEY_F21:
			return "F21";
		case KEY_F22:
			return "F22";
		case KEY_F23:
			return "F23";
		case KEY_F24:
			return "F24";
		case KEY_NUM_LOCK:
			return "NUM_LOCK";
		case KEY_SCROLL_LOCK:
			return "SCROLL_LOCK";
		case KEY_LSHIFT:
			return "LSHIFT";
		case KEY_RSHIFT:
			return "RSHIFT";
		case KEY_LCTRL:
			return "LCTRL";
		case KEY_RCTRL:
			return "RCTRL";
		case KEY_LALT:
			return "LALT";
		case KEY_RALT:
			return "RALT";
		case KEY_SEMICOLON:
			return "SEMICOLON";
		case KEY_EQUAL:
			return "EQUAL";
		case KEY_COMMA:
			return "COMMA";
		case KEY_MINUS:
			return "MINUS";
		case KEY_PERIOD:
			return "PERIOD";
		case KEY_SLASH:
			return "SLASH";
		case KEY_GRAVE:
			return "GRAVE";
		case KEY_LBRACKET:
			return "LBRACKET";
		case KEY_BACKSLASH:
			return "BACKSLASH";
		case KEY_RBRACKET:
			return "RBRACKET";
		case KEY_APOSTROPHE:
			return "APOSTROPHE";
		}
		return null;
	}

	public static MIDletProxy getInstance()
	{
		return INSTANCE;
	}


	private boolean paused;
	private int keyUsedAs1;
	private int keyUsedAs2;
	private int keyUsedAs3;
	private int keyUsedAs4;
	private int keyUsedAs5;
	private int keyUsedAs6;
	private int keyUsedAs7;
	private int keyUsedAs8;
	private int keyUsedAs9;
	private int keyUsedAsStar;
	private int keyUsedAs0;
	private int keyUsedAsPound;
	private int keyUsedAsUp;
	private int keyUsedAsDown;
	private int keyUsedAsLeft;
	private int keyUsedAsRight;
	private int keyUsedAsSelect;
	private int keyUsedAsSoft1;
	private int keyUsedAsSoft2;
	private int keyUsedAsConsole;
	private int keyUsedAsExitApp;
	private int keyCodeForUp;
	private int keyCodeForDown;
	private int keyCodeForLeft;
	private int keyCodeForRight;
	private int keyCodeForSelect;
	private int keyCodeForSoft1;
	private int keyCodeForSoft2;
	private String[] fontKeys;
	private RasterFont[] fonts;
	private AttributableMappedTextDecoder midletDescriptor;
	private Display emulatorScreen;
	private VirtualSystemGUI systemGUI;
	private MappedTextDecoder midletProperties;
	private MIDlet registeredMIDlet;

	public MIDletProxy()
	{
		String[] fk;
		if(INSTANCE != null)
		{
			throw new InstantiationError("MIDletProxy: " +
					"нельзя создать ещё один экземпляр класса MIDletProxy. " +
					"Используйте выражение MIDletProxy.getInstance().");
		}
		INSTANCE = this;
		fk = new String[] {
				"font.medium.plain", "font.medium.bold",
				"font.medium.italic", "font.medium.bold.italic",
				"font.small.plain", "font.small.bold",
				"font.small.italic", "font.small.bold.italic",
				"font.large.plain", "font.large.bold",
				"font.large.italic", "font.large.bold.italic"
		};
		this.fontKeys = fk;
		this.fonts = new RasterFont[fk.length];
		this.midletDescriptor = new ManifestFile();
		loadMIDletProperties();
		loadMIDletDescriptor();
		this.emulatorScreen = createDisplay();
		this.systemGUI = ImplementationManager.getSystemGUI();
	}

	public void appLaunch()
	{
		Displayable.tickerStart();
		systemGUI.showStartScreen(emulatorScreen);
	}

	public void appTerminate()
	{
		Displayable.tickerStop();
		systemGUI.onAppTerminate();
	}

	public void keyPressed(int key, int charCode)
	{
		if(key == keyUsedAsConsole || key == keyUsedAsExitApp)
		{
			return;
		}
		emulatorScreen.setEvent(Display.EVENT_KEY_PRESSED, key, charCode, charCode >> 16);
	}

	public void keyRepeated(int key, int charCode)
	{
		if(key == keyUsedAsConsole || key == keyUsedAsExitApp)
		{
			return;
		}
		emulatorScreen.setEvent(Display.EVENT_KEY_REPEATED, key, charCode, charCode >> 16);
	}

	public void keyReleased(int key)
	{
		if(key == keyUsedAsConsole)
		{
			systemGUI.showConsole(emulatorScreen);
			return;
		}
		if(key == keyUsedAsExitApp)
		{
			systemGUI.showExitScreen(emulatorScreen);
			return;
		}
		emulatorScreen.setEvent(Display.EVENT_KEY_RELEASED, key, 0, 0);
	}

	public void pointerPressed(int x, int y, int button)
	{
		emulatorScreen.setEvent(Display.EVENT_POINTER_PRESSED, x, y, button);
	}

	public void pointerDragged(int x, int y)
	{
		emulatorScreen.setEvent(Display.EVENT_POINTER_DRAGGED, x, y, 0);
	}

	public void pointerReleased(int x, int y, int button)
	{
		emulatorScreen.setEvent(Display.EVENT_POINTER_RELEASED, x, y, button);
	}

	public void windowResize(int width, int height)
	{
	}

	public void windowShow()
	{
		paused = false;
		emulatorScreen.setEvent(Display.EVENT_WINDOW_SHOW, 0, 0, 0);
	}

	public void windowHide()
	{
		paused = true;
		emulatorScreen.setEvent(Display.EVENT_WINDOW_HIDE, 0, 0, 0);
	}

	public void startMIDlet(Class midletClass)
	{
		emulatorScreen.startMIDlet(midletClass);
	}

	public void stopMIDlet()
	{
		emulatorScreen.stopMIDlet();
	}

	public void setKeyUsedAs(int deviceKey, int key)
	{
		switch(deviceKey)
		{
		default:
			throw new IllegalArgumentException("MIDletProxy.setKeyUsedAs: " +
					"недопустимое значение параметра deviceKey.");
		case DEVICE_KEY_1:
			keyUsedAs1 = key;
			return;
		case DEVICE_KEY_2:
			keyUsedAs2 = key;
			return;
		case DEVICE_KEY_3:
			keyUsedAs3 = key;
			return;
		case DEVICE_KEY_4:
			keyUsedAs4 = key;
			return;
		case DEVICE_KEY_5:
			keyUsedAs5 = key;
			return;
		case DEVICE_KEY_6:
			keyUsedAs6 = key;
			return;
		case DEVICE_KEY_7:
			keyUsedAs7 = key;
			return;
		case DEVICE_KEY_8:
			keyUsedAs8 = key;
			return;
		case DEVICE_KEY_9:
			keyUsedAs9 = key;
			return;
		case DEVICE_KEY_STAR:
			keyUsedAsStar = key;
			return;
		case DEVICE_KEY_0:
			keyUsedAs0 = key;
			return;
		case DEVICE_KEY_POUND:
			keyUsedAsPound = key;
			return;
		case DEVICE_KEY_UP:
			keyUsedAsUp = key;
			return;
		case DEVICE_KEY_DOWN:
			keyUsedAsDown = key;
			return;
		case DEVICE_KEY_LEFT:
			keyUsedAsLeft = key;
			return;
		case DEVICE_KEY_RIGHT:
			keyUsedAsRight = key;
			return;
		case DEVICE_KEY_SELECT:
			keyUsedAsSelect = key;
			return;
		case DEVICE_KEY_SOFT1:
			keyUsedAsSoft1 = key;
			return;
		case DEVICE_KEY_SOFT2:
			keyUsedAsSoft2 = key;
			return;
		case DEVICE_KEY_CONSOLE:
			keyUsedAsConsole = key;
			return;
		case DEVICE_KEY_EXITAPP:
			keyUsedAsExitApp = key;
			return;
		}
	}

	public void setKeyCodeFor(int deviceKey, int keyCode)
	{
		switch(deviceKey)
		{
		default:
			throw new IllegalArgumentException("MIDletProxy.setKeyCodeFor: " +
					"недопустимое значение параметра deviceKey.");
		case DEVICE_KEY_1:
		case DEVICE_KEY_2:
		case DEVICE_KEY_3:
		case DEVICE_KEY_4:
		case DEVICE_KEY_5:
		case DEVICE_KEY_6:
		case DEVICE_KEY_7:
		case DEVICE_KEY_8:
		case DEVICE_KEY_9:
		case DEVICE_KEY_STAR:
		case DEVICE_KEY_0:
		case DEVICE_KEY_POUND:
			throw new IllegalStateException("MIDletProxy.setKeyCodeFor: " +
					"для цифровых кнопок, звёздочки и решётки нельзя изменить код клавиши.");
		case DEVICE_KEY_UP:
			keyCodeForUp = keyCode;
			return;
		case DEVICE_KEY_DOWN:
			keyCodeForDown = keyCode;
			return;
		case DEVICE_KEY_LEFT:
			keyCodeForLeft = keyCode;
			return;
		case DEVICE_KEY_RIGHT:
			keyCodeForRight = keyCode;
			return;
		case DEVICE_KEY_SELECT:
			keyCodeForSelect = keyCode;
			return;
		case DEVICE_KEY_SOFT1:
			keyCodeForSoft1 = keyCode;
			return;
		case DEVICE_KEY_SOFT2:
			keyCodeForSoft2 = keyCode;
			return;
		case DEVICE_KEY_CONSOLE:
		case DEVICE_KEY_EXITAPP:
			throw new IllegalStateException("MIDletProxy.setKeyCodeFor: " +
					"для системных клавиш нельзя изменить код клавиши.");
		}
	}

	public void setFont(int size, int style, RasterFont font)
	{
		if(size < 0 || size >= 3)
		{
			throw new IllegalArgumentException("MIDletProxy.setFont: " +
					"недопустимое значение параметра size.");
		}
		if(style < 0 || style >= 4)
		{
			throw new IllegalArgumentException("MIDletProxy.setFont: " +
					"недопустимое значение параметра style.");
		}
		if(font == null)
		{
			font = RasterFont.getRasterFontAtIndex(0);
		}
		fonts[(size << 2) | style] = font;
	}

	public int keyCodeToGameAction(int keyCode)
	{
		if(keyCode == keyCodeForUp)
		{
			return Canvas.UP;
		}
		if(keyCode == keyCodeForDown)
		{
			return Canvas.DOWN;
		}
		if(keyCode == keyCodeForLeft)
		{
			return Canvas.LEFT;
		}
		if(keyCode == keyCodeForRight)
		{
			return Canvas.RIGHT;
		}
		if(keyCode == keyCodeForSelect)
		{
			return Canvas.FIRE;
		}
		if(keyCode == keyCodeForSoft1)
		{
			return 0;
		}
		if(keyCode == keyCodeForSoft2)
		{
			return 0;
		}
		switch(keyCode)
		{
		case DEVICE_KEY_1:
			return Canvas.GAME_A;
		case DEVICE_KEY_2:
			return Canvas.UP;
		case DEVICE_KEY_3:
			return Canvas.GAME_B;
		case DEVICE_KEY_4:
			return Canvas.LEFT;
		case DEVICE_KEY_5:
			return Canvas.FIRE;
		case DEVICE_KEY_6:
			return Canvas.RIGHT;
		case DEVICE_KEY_7:
			return Canvas.GAME_C;
		case DEVICE_KEY_8:
			return Canvas.DOWN;
		case DEVICE_KEY_9:
			return Canvas.GAME_D;
		case DEVICE_KEY_STAR:
		case DEVICE_KEY_0:
		case DEVICE_KEY_POUND:
			return 0;
		default:
			throw new IllegalArgumentException("MIDletProxy.keyCodeToGameAction: " +
					"несуществующий код клавиши: " + keyCode + ".");
		}
	}

	public int gameActionToKeyCode(int gameAction)
	{
		switch(gameAction)
		{
		default:
			throw new IllegalArgumentException("MIDletProxy.gameActionToKeyCode: " +
					"несуществующее игровое действие: " + gameAction + ".");
		case Canvas.UP:
			return DEVICE_KEY_2;
		case Canvas.LEFT:
			return DEVICE_KEY_4;
		case Canvas.RIGHT:
			return DEVICE_KEY_6;
		case Canvas.DOWN:
			return DEVICE_KEY_8;
		case Canvas.FIRE:
			return DEVICE_KEY_5;
		case Canvas.GAME_A:
			return DEVICE_KEY_1;
		case Canvas.GAME_B:
			return DEVICE_KEY_3;
		case Canvas.GAME_C:
			return DEVICE_KEY_7;
		case Canvas.GAME_D:
			return DEVICE_KEY_9;
		}
	}

	public int getKeyUsedAs(int deviceKey)
	{
		switch(deviceKey)
		{
		default:
			throw new IllegalArgumentException("MIDletProxy.getKeyUsedAs: " +
					"недопустимое значение параметра deviceKey.");
		case DEVICE_KEY_1:
			return keyUsedAs1;
		case DEVICE_KEY_2:
			return keyUsedAs2;
		case DEVICE_KEY_3:
			return keyUsedAs3;
		case DEVICE_KEY_4:
			return keyUsedAs4;
		case DEVICE_KEY_5:
			return keyUsedAs5;
		case DEVICE_KEY_6:
			return keyUsedAs6;
		case DEVICE_KEY_7:
			return keyUsedAs7;
		case DEVICE_KEY_8:
			return keyUsedAs8;
		case DEVICE_KEY_9:
			return keyUsedAs9;
		case DEVICE_KEY_STAR:
			return keyUsedAsStar;
		case DEVICE_KEY_0:
			return keyUsedAs0;
		case DEVICE_KEY_POUND:
			return keyUsedAsPound;
		case DEVICE_KEY_UP:
			return keyUsedAsUp;
		case DEVICE_KEY_DOWN:
			return keyUsedAsDown;
		case DEVICE_KEY_LEFT:
			return keyUsedAsLeft;
		case DEVICE_KEY_RIGHT:
			return keyUsedAsRight;
		case DEVICE_KEY_SELECT:
			return keyUsedAsSelect;
		case DEVICE_KEY_SOFT1:
			return keyUsedAsSoft1;
		case DEVICE_KEY_SOFT2:
			return keyUsedAsSoft2;
		case DEVICE_KEY_CONSOLE:
			return keyUsedAsConsole;
		case DEVICE_KEY_EXITAPP:
			return keyUsedAsExitApp;
		}
	}

	public int getKeyCodeFor(int deviceKey)
	{
		switch(deviceKey)
		{
		default:
			throw new IllegalArgumentException("MIDletProxy.getKeyCodeFor: " +
					"недопустимое значение параметра deviceKey.");
		case DEVICE_KEY_1:
		case DEVICE_KEY_2:
		case DEVICE_KEY_3:
		case DEVICE_KEY_4:
		case DEVICE_KEY_5:
		case DEVICE_KEY_6:
		case DEVICE_KEY_7:
		case DEVICE_KEY_8:
		case DEVICE_KEY_9:
		case DEVICE_KEY_STAR:
		case DEVICE_KEY_0:
		case DEVICE_KEY_POUND:
			return deviceKey;
		case DEVICE_KEY_UP:
			return keyCodeForUp;
		case DEVICE_KEY_DOWN:
			return keyCodeForDown;
		case DEVICE_KEY_LEFT:
			return keyCodeForLeft;
		case DEVICE_KEY_RIGHT:
			return keyCodeForRight;
		case DEVICE_KEY_SELECT:
			return keyCodeForSelect;
		case DEVICE_KEY_SOFT1:
			return keyCodeForSoft1;
		case DEVICE_KEY_SOFT2:
			return keyCodeForSoft2;
		case DEVICE_KEY_CONSOLE:
		case DEVICE_KEY_EXITAPP:
			throw new IllegalStateException("MIDletProxy.getKeyCodeFor: " +
					"для системных клавиш не существует код клавиши.");
		}
	}

	public int getKeyCode(int key)
	{
		if(key == keyUsedAs1)
		{
			return DEVICE_KEY_1;
		}
		if(key == keyUsedAs2)
		{
			return DEVICE_KEY_2;
		}
		if(key == keyUsedAs3)
		{
			return DEVICE_KEY_3;
		}
		if(key == keyUsedAs4)
		{
			return DEVICE_KEY_4;
		}
		if(key == keyUsedAs5)
		{
			return DEVICE_KEY_5;
		}
		if(key == keyUsedAs6)
		{
			return DEVICE_KEY_6;
		}
		if(key == keyUsedAs7)
		{
			return DEVICE_KEY_7;
		}
		if(key == keyUsedAs8)
		{
			return DEVICE_KEY_8;
		}
		if(key == keyUsedAs9)
		{
			return DEVICE_KEY_9;
		}
		if(key == keyUsedAsStar)
		{
			return DEVICE_KEY_STAR;
		}
		if(key == keyUsedAs0)
		{
			return DEVICE_KEY_0;
		}
		if(key == keyUsedAsPound)
		{
			return DEVICE_KEY_POUND;
		}
		if(key == keyUsedAsUp)
		{
			return keyCodeForUp;
		}
		if(key == keyUsedAsDown)
		{
			return keyCodeForDown;
		}
		if(key == keyUsedAsLeft)
		{
			return keyCodeForLeft;
		}
		if(key == keyUsedAsRight)
		{
			return keyCodeForRight;
		}
		if(key == keyUsedAsSelect)
		{
			return keyCodeForSelect;
		}
		if(key == keyUsedAsSoft1)
		{
			return keyCodeForSoft1;
		}
		if(key == keyUsedAsSoft2)
		{
			return keyCodeForSoft2;
		}
		return 0;
	}

	public String getKeyName(int keyCode)
	{
		if(keyCode == keyCodeForUp)
		{
			return "\u2191";
		}
		if(keyCode == keyCodeForDown)
		{
			return "\u2193";
		}
		if(keyCode == keyCodeForLeft)
		{
			return "\u2190";
		}
		if(keyCode == keyCodeForRight)
		{
			return "\u2192";
		}
		if(keyCode == keyCodeForSelect)
		{
			return "Центральная клавиша выбора";
		}
		if(keyCode == keyCodeForSoft1)
		{
			return "Левая клавиша выбора";
		}
		if(keyCode == keyCodeForSoft2)
		{
			return "Правая клавиша выбора";
		}
		switch(keyCode)
		{
		case DEVICE_KEY_1:
			return "1";
		case DEVICE_KEY_2:
			return "2";
		case DEVICE_KEY_3:
			return "3";
		case DEVICE_KEY_4:
			return "4";
		case DEVICE_KEY_5:
			return "5";
		case DEVICE_KEY_6:
			return "6";
		case DEVICE_KEY_7:
			return "7";
		case DEVICE_KEY_8:
			return "8";
		case DEVICE_KEY_9:
			return "9";
		case DEVICE_KEY_STAR:
			return "*";
		case DEVICE_KEY_0:
			return "0";
		case DEVICE_KEY_POUND:
			return "#";
		default:
			throw new IllegalArgumentException("MIDletProxy.getKeyName: " +
					"несуществующий код клавиши: " + keyCode + ".");
		}
	}

	public RasterFont getFont(int size, int style)
	{
		if(size < 0 || size >= 3)
		{
			throw new IllegalArgumentException("MIDletProxy.getFont: " +
					"недопустимое значение параметра size.");
		}
		if(style < 0 || style >= 4)
		{
			throw new IllegalArgumentException("MIDletProxy.getFont: " +
					"недопустимое значение параметра style.");
		}
		return fonts[(size << 2) | style];
	}

	public final void loadMIDletProperties()
	{
		midletProperties = new PropertiesFile();
		try
		{
			if(loadMIDletPropertiesHelper())
			{
				readMIDletProperties();
			}
		}
		finally
		{
			midletProperties = null;
		}
	}

	public final void saveMIDletProperties()
	{
		PrintStream printer = new PrintStream(new FileOutputStream(MIDLET_PROPERTIES));
		try
		{
			writeMIDletProperties(printer);
		}
		finally
		{
			printer.close();
		}
	}

	public final void notifyMIDletDestroyed()
	{
		emulatorScreen.terminateEventStreams();
	}

	public final void registerMIDlet(MIDlet midlet)
	{
		int error = 0;
		synchronized(fonts)
		{
			label0:
			{
				if(registeredMIDlet != null)
				{
					error = 1;
					break label0;
				}
				registeredMIDlet = midlet;
			}
		}
		if(error == 1)
		{
			throw new SecurityException("В системе уже есть запущенный мидлет.");
		}
	}

	public final void setEnableStackTrace(boolean enableStackTrace)
	{
		ThrowableStackTrace.enable(enableStackTrace);
	}

	public final void setKeyRepeatedEvent(boolean keyRepeatedEvent)
	{
		Canvas.setKeyRepeatedEvent(keyRepeatedEvent);
	}

	public final void setSerializeRepaint(boolean serializeRepaint)
	{
		Display.setSerializeRepaint(serializeRepaint);
	}

	public final void setMaximumFrequency(int maximumFrequency)
	{
		Display.setMaximumFrequency(maximumFrequency);
	}

	public final boolean isPaused()
	{
		return paused;
	}

	public final boolean isEnableStackTrace()
	{
		return ThrowableStackTrace.enabled();
	}

	public final boolean isKeyRepeatedEvent()
	{
		return Canvas.isKeyRepeatedEvent();
	}

	public final boolean isSerializeRepaint()
	{
		return Display.isSerializeRepaint();
	}

	public final int getMaximumFrequency()
	{
		return Display.getMaximumFrequency();
	}

	public final Display getEmulatorScreen()
	{
		return emulatorScreen;
	}

	public final MIDlet getRegisteredMIDlet()
	{
		return registeredMIDlet;
	}

	public final AttributableMappedTextDecoder getMIDletDescriptor()
	{
		return midletDescriptor;
	}

	public final Exception getMIDletStartingCause()
	{
		return emulatorScreen.getMIDletStartingCause();
	}

	final void notifyMIDletStarted()
	{
		Run.getInstance().setEvent(new MIDletStartEvent(systemGUI));
	}

	final void notifyMIDletTerminated()
	{
		Run.getInstance().setEvent(new MIDletDestroyEvent(systemGUI));
	}

	protected void defaultMIDletProperties()
	{
		int i;
		RasterFont[] af;
		RasterFont f;
		setEnableStackTrace(true);
		setKeyRepeatedEvent(true);
		setSerializeRepaint(true);
		keyUsedAs1 = KEY_NUM_7;
		keyUsedAs2 = KEY_NUM_8;
		keyUsedAs3 = KEY_NUM_9;
		keyUsedAs4 = KEY_NUM_4;
		keyUsedAs5 = KEY_NUM_5;
		keyUsedAs6 = KEY_NUM_6;
		keyUsedAs7 = KEY_NUM_1;
		keyUsedAs8 = KEY_NUM_2;
		keyUsedAs9 = KEY_NUM_3;
		keyUsedAsStar = KEY_NUM_STAR;
		keyUsedAs0 = KEY_NUM_0;
		keyUsedAsPound = KEY_NUM_DIVIDE;
		keyUsedAsUp = KEY_UP;
		keyUsedAsDown = KEY_DOWN;
		keyUsedAsLeft = KEY_LEFT;
		keyUsedAsRight = KEY_RIGHT;
		keyUsedAsSelect = KEY_ENTER;
		keyUsedAsSoft1 = KEY_F1;
		keyUsedAsSoft2 = KEY_F2;
		keyUsedAsConsole = KEY_F3;
		keyUsedAsExitApp = KEY_F4;
		keyCodeForUp = -1;
		keyCodeForDown = -2;
		keyCodeForLeft = -3;
		keyCodeForRight = -4;
		keyCodeForSelect = -5;
		keyCodeForSoft1 = -6;
		keyCodeForSoft2 = -7;
		for(f = RasterFont.getRasterFontAtIndex(0), i = (af = fonts).length; i-- > 0; af[i] = f);
	}

	protected void readMIDletProperties()
	{
		int i;
		String[] fk = fontKeys;
		RasterFont[] f = fonts;
		setEnableStackTrace(readMIDletPropertyAsBoolean(
				"system.ENABLE_STACK_TRACE", true));
		setKeyRepeatedEvent(readMIDletPropertyAsBoolean(
				"system.KEY_REPEATED_EVENT", true));
		setSerializeRepaint(readMIDletPropertyAsBoolean(
				"system.SERIALIZE_REPAINT", true));
		setMaximumFrequency(readMIDletPropertyAsInt(
				"system.MAXIMUM_FREQUENCY", 25));
		keyUsedAs1 = readMIDletPropertyAsKey("key.1", KEY_NUM_7);
		keyUsedAs2 = readMIDletPropertyAsKey("key.2", KEY_NUM_8);
		keyUsedAs3 = readMIDletPropertyAsKey("key.3", KEY_NUM_9);
		keyUsedAs4 = readMIDletPropertyAsKey("key.4", KEY_NUM_4);
		keyUsedAs5 = readMIDletPropertyAsKey("key.5", KEY_NUM_5);
		keyUsedAs6 = readMIDletPropertyAsKey("key.6", KEY_NUM_6);
		keyUsedAs7 = readMIDletPropertyAsKey("key.7", KEY_NUM_1);
		keyUsedAs8 = readMIDletPropertyAsKey("key.8", KEY_NUM_2);
		keyUsedAs9 = readMIDletPropertyAsKey("key.9", KEY_NUM_3);
		keyUsedAsStar = readMIDletPropertyAsKey("key.ASTERISK", KEY_NUM_STAR);
		keyUsedAs0 = readMIDletPropertyAsKey("key.0", KEY_NUM_0);
		keyUsedAsPound = readMIDletPropertyAsKey("key.POUND", KEY_NUM_DIVIDE);
		keyUsedAsUp = readMIDletPropertyAsKey("key.UP", KEY_UP);
		keyUsedAsDown = readMIDletPropertyAsKey("key.DOWN", KEY_DOWN);
		keyUsedAsLeft = readMIDletPropertyAsKey("key.LEFT", KEY_LEFT);
		keyUsedAsRight = readMIDletPropertyAsKey("key.RIGHT", KEY_RIGHT);
		keyUsedAsSelect = readMIDletPropertyAsKey("key.SELECT", KEY_ENTER);
		keyUsedAsSoft1 = readMIDletPropertyAsKey("key.SOFT1", KEY_F1);
		keyUsedAsSoft2 = readMIDletPropertyAsKey("key.SOFT2", KEY_F2);
		keyUsedAsConsole = readMIDletPropertyAsKey("key.CONSOLE", KEY_F3);
		keyUsedAsExitApp = readMIDletPropertyAsKey("key.EXITAPP", KEY_F4);
		keyCodeForUp = readMIDletPropertyAsInt("key.code.UP", -1);
		keyCodeForDown = readMIDletPropertyAsInt("key.code.DOWN", -2);
		keyCodeForLeft = readMIDletPropertyAsInt("key.code.LEFT", -3);
		keyCodeForRight = readMIDletPropertyAsInt("key.code.RIGHT", -4);
		keyCodeForSelect = readMIDletPropertyAsInt("key.code.SELECT", -5);
		keyCodeForSoft1 = readMIDletPropertyAsInt("key.code.SOFT1", -6);
		keyCodeForSoft2 = readMIDletPropertyAsInt("key.code.SOFT2", -7);
		for(i = fk.length; i-- > 0; )
		{
			f[i] = readMIDletPropertyAsRasterFont(fk[i]);
		}
	}

	protected void writeMIDletProperties(PrintStream printer)
	{
		int i;
		int len;
		String[] fk = fontKeys;
		RasterFont[] f = fonts;
		len = fk.length;
		printer.println();
		printer.println("# Параметры мидлета (можно менять, не запуская сам мидлет)");
		printer.println("# Этот файл перезаписывается каждый раз, когда вы сохраняете");
		printer.println("# настройки, поэтому НЕ дописывайте в него какую-либо информацию.");
		printer.print("system.ENABLE_STACK_TRACE = ");
		printer.println(isEnableStackTrace());
		printer.print("system.KEY_REPEATED_EVENT = ");
		printer.println(isKeyRepeatedEvent());
		printer.print("system.SERIALIZE_REPAINT = ");
		printer.println(isSerializeRepaint());
		printer.print("system.MAXIMUM_FREQUENCY = ");
		printer.println(getMaximumFrequency());
		printer.println();
		printer.print("key.1 = ");
		printer.println(getSystemKeyName(keyUsedAs1));
		printer.print("key.2 = ");
		printer.println(getSystemKeyName(keyUsedAs2));
		printer.print("key.3 = ");
		printer.println(getSystemKeyName(keyUsedAs3));
		printer.print("key.4 = ");
		printer.println(getSystemKeyName(keyUsedAs4));
		printer.print("key.5 = ");
		printer.println(getSystemKeyName(keyUsedAs5));
		printer.print("key.6 = ");
		printer.println(getSystemKeyName(keyUsedAs6));
		printer.print("key.7 = ");
		printer.println(getSystemKeyName(keyUsedAs7));
		printer.print("key.8 = ");
		printer.println(getSystemKeyName(keyUsedAs8));
		printer.print("key.9 = ");
		printer.println(getSystemKeyName(keyUsedAs9));
		printer.print("key.ASTERISK = ");
		printer.println(getSystemKeyName(keyUsedAsStar));
		printer.print("key.0 = ");
		printer.println(getSystemKeyName(keyUsedAs0));
		printer.print("key.POUND = ");
		printer.println(getSystemKeyName(keyUsedAsPound));
		printer.print("key.UP = ");
		printer.println(getSystemKeyName(keyUsedAsUp));
		printer.print("key.DOWN = ");
		printer.println(getSystemKeyName(keyUsedAsDown));
		printer.print("key.LEFT = ");
		printer.println(getSystemKeyName(keyUsedAsLeft));
		printer.print("key.RIGHT = ");
		printer.println(getSystemKeyName(keyUsedAsRight));
		printer.print("key.SELECT = ");
		printer.println(getSystemKeyName(keyUsedAsSelect));
		printer.print("key.SOFT1 = ");
		printer.println(getSystemKeyName(keyUsedAsSoft1));
		printer.print("key.SOFT2 = ");
		printer.println(getSystemKeyName(keyUsedAsSoft2));
		printer.print("key.CONSOLE = ");
		printer.println(getSystemKeyName(keyUsedAsConsole));
		printer.print("key.EXITAPP = ");
		printer.println(getSystemKeyName(keyUsedAsExitApp));
		printer.println();
		printer.print("key.code.UP = ");
		printer.println(keyCodeForUp);
		printer.print("key.code.DOWN = ");
		printer.println(keyCodeForDown);
		printer.print("key.code.LEFT = ");
		printer.println(keyCodeForLeft);
		printer.print("key.code.RIGHT = ");
		printer.println(keyCodeForRight);
		printer.print("key.code.SELECT = ");
		printer.println(keyCodeForSelect);
		printer.print("key.code.SOFT1 = ");
		printer.println(keyCodeForSoft1);
		printer.print("key.code.SOFT2 = ");
		printer.println(keyCodeForSoft2);
		printer.println();
		for(i = 0; i < len; i++)
		{
			printer.print(fk[i]);
			printer.print(" = ");
			printer.println(f[i].getName());
		}
		printer.println();
	}

	protected Display createDisplay()
	{
		return new Display(RasterCanvas.getScreenCanvas());
	}

	protected final boolean readMIDletPropertyAsBoolean(String key, boolean defaultValue)
	{
		String value;
		return (value = readMIDletProperty(key)) == null ? defaultValue :
				("true".equalsIgnoreCase(value) ||
				((!"false".equalsIgnoreCase(value)) && defaultValue));
	}

	protected final int readMIDletPropertyAsInt(String key, int defaultValue)
	{
		int result;
		String value = readMIDletProperty(key);
		try
		{
			result = (value.startsWith("0x") || value.startsWith("0X")) ?
					(
						Integer.parseInt(value.substring(2), 16)
					) :
					(
						(value.startsWith("-0x") || value.startsWith("-0X")) ?
						(
							-Integer.parseInt(value.substring(3), 16)
						) :
						(
							Integer.parseInt(value)
						)
					);
		}
		catch(RuntimeException e)
		{
			result = defaultValue;
		}
		return result;
	}

	protected final int readMIDletPropertyAsKey(String key, int defaultKey)
	{
		int result;
		String value = readMIDletProperty(key);
		try
		{
			if((result = getSystemKeyCode(value)) == 0)
			{
				result = defaultKey;
			}
		}
		catch(RuntimeException e)
		{
			result = defaultKey;
		}
		return result;
	}

	protected final RasterFont readMIDletPropertyAsRasterFont(String key)
	{
		return RasterFont.getRasterFontAtName(readMIDletProperty(key));
	}

	protected final String readMIDletProperty(String key)
	{
		return midletProperties.get(key);
	}

	private void loadMIDletDescriptor()
	{
		FileInputStream file = new FileInputStream(MIDLET_DESCRIPTOR);
		try
		{
			file.checkOpenError();
			try
			{
				midletDescriptor.loadFromInputStream(file);
			}
			finally
			{
				file.close();
			}
		}
		catch(IOException e)
		{
			System.err.println("Не удалось загрузить дескриптор мидлета: ошибка ввода-вывода.");
			System.err.println("Проверьте файл" + MIDLET_DESCRIPTOR + ". Подробности ниже.");
			e.printRealStackTrace();
		}
	}

	private boolean loadMIDletPropertiesHelper()
	{
		boolean result;
		FileInputStream file = new FileInputStream(MIDLET_PROPERTIES);
		try
		{
			file.checkOpenError();
			try
			{
				midletProperties.loadFromInputStream(file);
			}
			finally
			{
				file.close();
			}
			result = true;
		}
		catch(IOException e)
		{
			System.err.println("Не удалось загрузить файл свойств мидлета: ошибка ввода-вывода.");
			System.err.println("Будут загружены свойства по умолчанию. Подробности ниже.");
			e.printRealStackTrace();
			defaultMIDletProperties();
			result = false;
		}
		return result;
	}
}
