/*
	Реализация спецификаций 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;

public abstract class Canvas extends Displayable
{
	public static final int UP = 1;
	public static final int LEFT = 2;
	public static final int RIGHT = 5;
	public static final int DOWN = 6;
	public static final int FIRE = 8;
	public static final int GAME_A = 9;
	public static final int GAME_B = 10;
	public static final int GAME_C = 11;
	public static final int GAME_D = 12;
	public static final int KEY_POUND = 35;
	public static final int KEY_STAR = 42;
	public static final int KEY_NUM0 = 48;
	public static final int KEY_NUM1 = 49;
	public static final int KEY_NUM2 = 50;
	public static final int KEY_NUM3 = 51;
	public static final int KEY_NUM4 = 52;
	public static final int KEY_NUM5 = 53;
	public static final int KEY_NUM6 = 54;
	public static final int KEY_NUM7 = 55;
	public static final int KEY_NUM8 = 56;
	public static final int KEY_NUM9 = 57;
	private static boolean KEY_REPEATED_EVENTS;

	public static void setKeyRepeatedEvent(boolean keyRepeatedEvents)
	{
		KEY_REPEATED_EVENTS = keyRepeatedEvents;
	}

	public static boolean isKeyRepeatedEvent()
	{
		return KEY_REPEATED_EVENTS;
	}

	private static String getMIDletName()
	{
		return MIDletProxy.getInstance().getMIDletDescriptor().get("MIDlet-Name");
	}


	protected int keyStates;

	private boolean clientFocused;
	private boolean suppressKeyEvents;

	protected Canvas()
	{
		this(false, false, getMIDletName(), null, null, null, null, false);
	}

	protected Canvas(boolean fullScreenMode, boolean suppressKeyEvents)
	{
		this(false, fullScreenMode, getMIDletName(), null, null, null, null, suppressKeyEvents);
	}

	protected Canvas(boolean fullScreenMode, String title, Ticker ticker,
			Command[] commands, Command defaultCommand, CommandListener listener,
			boolean suppressKeyEvents)
	{
		this(true, fullScreenMode, title, ticker, commands, defaultCommand, listener, suppressKeyEvents);
	}

	private Canvas(boolean system, boolean fullScreenMode, String title, Ticker ticker,
			Command[] commands, Command defaultCommand, CommandListener listener,
			boolean suppressKeyEvents)
	{
		super(system, fullScreenMode, title, ticker, commands, defaultCommand, listener);
		this.suppressKeyEvents = suppressKeyEvents;
	}

	public void setFullScreenMode(boolean fullScreen)
	{
		super.setFullScreenMode(fullScreen);
	}

	public int getWidth()
	{
		return super.getWidth();
	}

	public int getHeight()
	{
		return super.getHeight();
	}

	public boolean isDoubleBuffered()
	{
		return true;
	}

	public boolean hasRepeatEvents()
	{
		return true;
	}

	public boolean hasPointerEvents()
	{
		return true;
	}

	public boolean hasPointerMotionEvents()
	{
		return true;
	}

	public int getGameAction(int keyCode)
	{
		return MIDletProxy.getInstance().keyCodeToGameAction(keyCode);
	}

	public int getKeyCode(int gameAction)
	{
		return MIDletProxy.getInstance().gameActionToKeyCode(gameAction);
	}

	public String getKeyName(int keyCode)
	{
		return MIDletProxy.getInstance().getKeyName(keyCode);
	}

	public final void repaint()
	{
		callSeriallyPaintClient(0, 0, getClientWidth(), getClientHeight());
	}

	public final void repaint(int left, int top, int width, int height)
	{
		callSeriallyPaintClient(left, top, width, height);
	}

	public final void serviceRepaints()
	{
		MIDletProxy.getInstance().getEmulatorScreen().serviceRepaints(this);
	}

	protected abstract void paint(Graphics render);

	protected void sizeChanged(int width, int height)
	{
	}

	protected void showNotify()
	{
	}

	protected void hideNotify()
	{
	}

	protected void keyPressed(int keyCode)
	{
	}

	protected void keyRepeated(int keyCode)
	{
	}

	protected void keyReleased(int keyCode)
	{
	}

	protected void pointerPressed(int x, int y)
	{
	}

	protected void pointerDragged(int x, int y)
	{
	}

	protected void pointerReleased(int x, int y)
	{
	}

	void paintClient(Graphics render, int width, int height, int clipLeft, int clipTop, int clipWidth, int clipHeight)
	{
		Graphics clientRender;
		(clientRender = getClientContext()).reset();
		clientRender.setClip(clipLeft, clipTop, clipWidth, clipHeight);
		paint(clientRender);
	}

	void onShow()
	{
		super.onShow();
		keyStates = 0;
		clientFocused = false;
		try
		{
			showNotify();
		}
		catch(RuntimeException e)
		{
			e.printRealStackTrace();
		}
	}

	void onHide()
	{
		keyStates = 0;
		clientFocused = false;
		try
		{
			hideNotify();
		}
		catch(RuntimeException e)
		{
			e.printRealStackTrace();
		}
		super.onHide();
	}

	void onKeyPressed(int key, int charCode)
	{
		int keyCode;
		int gameAction;
		MIDletProxy proxy;
		if((!super.keyHandling(key)) &&
				(keyCode = (proxy = MIDletProxy.getInstance()).getKeyCode(key)) != 0)
		{
			if((gameAction = proxy.keyCodeToGameAction(keyCode)) != 0)
			{
				keyStates |= 1 << gameAction;
			}
			if(!suppressKeyEvents || gameAction == 0)
			{
				try
				{
					keyPressed(keyCode);
				}
				catch(RuntimeException e)
				{
					e.printRealStackTrace();
				}
			}
			return;
		}
		super.onKeyPressed(key, charCode);
	}

	void onKeyRepeated(int key, int charCode)
	{
		int keyCode;
		if(KEY_REPEATED_EVENTS && (!super.keyHandling(key)) &&
				(keyCode = MIDletProxy.getInstance().getKeyCode(key)) != 0 &&
				(!suppressKeyEvents || MIDletProxy.getInstance().keyCodeToGameAction(keyCode) == 0))
		{
			try
			{
				keyRepeated(keyCode);
			}
			catch(RuntimeException e)
			{
				e.printRealStackTrace();
			}
			return;
		}
		super.onKeyRepeated(key, charCode);
	}

	void onKeyReleased(int key)
	{
		int keyCode;
		int gameAction;
		MIDletProxy proxy;
		if((!super.keyHandling(key)) &&
				(keyCode = (proxy = MIDletProxy.getInstance()).getKeyCode(key)) != 0)
		{
			if((gameAction = proxy.keyCodeToGameAction(keyCode)) != 0)
			{
				keyStates &= ~(1 << gameAction);
			}
			if(!suppressKeyEvents || gameAction == 0)
			{
				try
				{
					keyReleased(keyCode);
				}
				catch(RuntimeException e)
				{
					e.printRealStackTrace();
				}
			}
			return;
		}
		super.onKeyReleased(key);
	}

	void onPointerPressed(int x, int y, int button)
	{
		int l;
		int t;
		Display display = MIDletProxy.getInstance().getEmulatorScreen();
		if(button == MIDletProxy.BUTTON_MAIN && (!super.coordinateHandling(x, y)) &&
				x >= (l = display.getGUIElementLeft(this, GUI_ELEMENT_CLIENT)) &&
				x < l + display.getGUIElementWidth(this, GUI_ELEMENT_CLIENT) &&
				y >= (t = display.getGUIElementTop(this, GUI_ELEMENT_CLIENT)) &&
				y < t + display.getGUIElementHeight(this, GUI_ELEMENT_CLIENT))
		{
			clientFocused = true;
			try
			{
				pointerPressed(x - l, y - t);
			}
			catch(RuntimeException e)
			{
				e.printRealStackTrace();
			}
			return;
		}
		super.onPointerPressed(x, y, button);
	}

	void onPointerDragged(int x, int y)
	{
		int l;
		int t;
		Display display;
		if(clientFocused)
		{
			display = MIDletProxy.getInstance().getEmulatorScreen();
			l = display.getGUIElementLeft(this, GUI_ELEMENT_CLIENT);
			t = display.getGUIElementTop(this, GUI_ELEMENT_CLIENT);
			try
			{
				pointerDragged(x - l, y - t);
			}
			catch(RuntimeException e)
			{
				e.printRealStackTrace();
			}
			return;
		}
		super.onPointerDragged(x, y);
	}

	void onPointerReleased(int x, int y, int button)
	{
		int l;
		int t;
		Display display;
		if(clientFocused && button == MIDletProxy.BUTTON_MAIN)
		{
			clientFocused = false;
			display = MIDletProxy.getInstance().getEmulatorScreen();
			l = display.getGUIElementLeft(this, GUI_ELEMENT_CLIENT);
			t = display.getGUIElementTop(this, GUI_ELEMENT_CLIENT);
			try
			{
				pointerReleased(x - l, y - t);
			}
			catch(RuntimeException e)
			{
				e.printRealStackTrace();
			}
			return;
		}
		super.onPointerReleased(x, y, button);
	}
}
