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

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

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

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

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

package javax.microedition.lcdui.game;

import javax.microedition.lcdui.*;
import malik.emulator.application.*;
import malik.emulator.media.graphics.*;
import malik.emulator.microedition.*;

public abstract class GameCanvas extends CustomCanvas
{
    public static final int UP_PRESSED     = 1 << UP;
    public static final int LEFT_PRESSED   = 1 << LEFT;
    public static final int RIGHT_PRESSED  = 1 << RIGHT;
    public static final int DOWN_PRESSED   = 1 << DOWN;
    public static final int FIRE_PRESSED   = 1 << FIRE;
    public static final int GAME_A_PRESSED = 1 << GAME_A;
    public static final int GAME_B_PRESSED = 1 << GAME_B;
    public static final int GAME_C_PRESSED = 1 << GAME_C;
    public static final int GAME_D_PRESSED = 1 << GAME_D;

    private final boolean suppressKeyEvents;
    private int keyStates;
    private final Image buffer;

    protected GameCanvas(boolean suppressKeyEvents) {
        RasterCanvas screen = RasterCanvas.screen;
        this.suppressKeyEvents = suppressKeyEvents;
        this.buffer = Image.createImage(screen.getWidth(), screen.getHeight());
    }

    public void paint(Graphics render) {
        if(render == null)
        {
            throw new NullPointerException("GameCanvas.paint: аргумент render равен нулевой ссылке.");
        }
        render.drawImage(buffer, 0, 0, 0);
    }

    public void flushGraphics() {
        flushBuffer(buffer);
    }

    public void flushGraphics(int left, int top, int width, int height) {
        flushBuffer(left, top, width, height, buffer);
    }

    public int getKeyStates() {
        return keyStates;
    }

    protected Graphics getGraphics() {
        return buffer.getGraphics();
    }

    protected final void show() {
        showNotify();
    }

    protected final void hide() {
        keyStates = 0;
        hideNotify();
    }

    protected final void keyboardEvent(KeyboardEvent event) {
        int keyCode;
        int gameAction;
        DeviceSettings settings = DeviceManager.getInstance().getSettings();
        switch(event.getAction())
        {
        case KeyboardEvent.ACTION_KEY_PRESSED:
            if((keyCode = settings.getKeyCode(event.getKey())) != 0)
            {
                if((gameAction = settings.keyCodeToGameAction(keyCode) & 0x1f) != 0) keyStates |= (1 << gameAction);
                if(gameAction == 0 || !suppressKeyEvents) keyPressed(keyCode);
            }
            break;
        case KeyboardEvent.ACTION_KEY_REPEATED:
            if(settings.isKeyRepeatedEvent() && (keyCode = settings.getKeyCode(event.getKey())) != 0)
            {
                if((gameAction = settings.keyCodeToGameAction(keyCode) & 0x1f) != 0) keyStates |= (1 << gameAction);
                if(gameAction == 0 || !suppressKeyEvents) keyRepeated(keyCode);
            }
            break;
        case KeyboardEvent.ACTION_KEY_RELEASED:
            if((keyCode = settings.getKeyCode(event.getKey())) != 0)
            {
                if((gameAction = settings.keyCodeToGameAction(keyCode) & 0x1f) != 0) keyStates &= ~(1 << gameAction);
                if(gameAction == 0 || !suppressKeyEvents) keyReleased(keyCode);
            }
            break;
        }
    }
}
