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

import javax.microedition.lcdui.*;

public class ButtonSet extends CustomItem
{
    private final int width;
    private final int height;
    private int pressed;
    private int count;
    private int[][] buttons;
    private final Image background;
    private final Object monitor;

    public ButtonSet(String label, Image background) {
        super(label);
        if(background == null)
        {
            throw new NullPointerException("ButtonSet: аргумент background равен нулевой ссылке.");
        }
        this.width = background.getWidth() >> 1;
        this.height = background.getHeight();
        this.pressed = -1;
        this.buttons = new int[1][];
        this.background = background;
        this.monitor = new Object();
    }

    public void setButton(int buttonID, int left, int top, int width, int height) {
        int buttonLeft = Math.max(0, left);
        int buttonTop = Math.max(0, top);
        int buttonRight = Math.min(this.width, left + width);
        int buttonBottom = Math.min(this.height, top + height);
        if(buttonLeft >= buttonRight || buttonTop >= buttonBottom) return;
        synchronized(monitor)
        {
            int index;
            int[][] buttons = this.buttons;
            if((index = indexOf(buttonID, buttons)) >= 0)
            {
                int[] info;
                (info = buttons[index])[1] = buttonLeft;
                info[2] = buttonTop;
                info[3] = buttonRight;
                info[4] = buttonBottom;
            } else
            {
                int len;
                if((len = count) == buttons.length)
                {
                    Array.copy(buttons, 0, buttons = new int[(len << 1) + 1][], 0, len);
                    this.buttons = buttons;
                }
                buttons[len++] = new int[] { buttonID, buttonLeft, buttonTop, buttonRight, buttonBottom };
                count = len;
            }
        }
    }

    public int getPressedButtonID() {
        int p;
        return (p = pressed) >= 0 ? buttons[p][0] : 0;
    }

    protected void paint(Graphics render, int contentWidth, int contentHeight) {
        int width = this.width;
        int height = this.height;
        int pressed = this.pressed;
        Image background = this.background;
        render.drawRegion(background, 0, 0, width, height, 0, 0, 0, 0);
        if(pressed >= 0)
        {
            int left;
            int top;
            int[] button;
            left = (button = buttons[pressed])[1];
            render.drawRegion(background, width + left, top = button[2], button[3] - left, button[4] - top, 0, left, top, 0);
        }
    }

    protected void pointerPressed(int x, int y) {
        int index;
        if((index = indexOf(x, y, buttons)) >= 0 && index != pressed)
        {
            pressed = index;
            super.notifyStateChanged();
            super.repaint();
        }
    }

    protected int getMinContentWidth() {
        return width;
    }

    protected int getMinContentHeight() {
        return height;
    }

    protected int getPrefContentWidth(int contentHeight) {
        return width;
    }

    protected int getPrefContentHeight(int contentWidth) {
        return height;
    }

    private int indexOf(int buttonID, int[][] buttons) {
        for(int i = count; i-- > 0; ) if(buttons[i][0] == buttonID) return i;
        return -1;
    }

    private int indexOf(int x, int y, int[][] buttons) {
        for(int i = count; i-- > 0; )
        {
            int[] button = buttons[i];
            if(x >= button[1] && y >= button[2] && x < button[3] && y < button[4]) return i;
        }
        return -1;
    }
}
