package com.brackeen.javagamebook.game;

import com.brackeen.javagamebook.math3D.*;

/**
    Klasa GameObject jest podstawą dla wszystkich typów obiektów
    występujących w grze, które są reprezentowane za pomocą obiektu
    klasy PolygonGroup. Przykładowo, GameObject może być obiektem
    statycznym (np. skrzynią), obiektem w ruchu (np. pociskiem lub
    przeciwnikiem) lub dowolnym innym typem obiektu (np. apteczką).
    Obiekty klasy GameObject mogą się znajdować w trzech podstawowych
    stanach: bezczynności (STATE_IDLE), aktywności (STATE_ACTIVE) i 
    zniszczenia (STATE_DESTROYED).
*/
public class GameObject {
    protected static final int STATE_IDLE = 0;
    protected static final int STATE_ACTIVE = 1;
    protected static final int STATE_DESTROYED = 2;

    private PolygonGroup polygonGroup;
    private int state;

    /**
        Tworzy nowy GameObject reprezentowany przez przekazany obiekt 
        klasy PolygonGroup. Przekazany obiekt może mieć wartość null.
    */
    public GameObject(PolygonGroup polygonGroup) {
        this.polygonGroup = polygonGroup;
        state = STATE_IDLE;
    }


    /**
        Zwraca położenie tego obiektu GameObject w oparciu o dane
        obiektu klasy Transform3D.
    */
    public Vector3D getLocation() {
        return polygonGroup.getTransform().getLocation();
    }


    /**
        Zwraca obiekt reprezentujący ruch obiektu w grze.
    */
    public MovingTransform3D getTransform() {
        return polygonGroup.getTransform();
    }


    /**
        Zwraca obiekt klasy PolygonGroup dla tego obiektu w grze.
    */
    public PolygonGroup getPolygonGroup() {
        return polygonGroup;
    }


    /**
        Zwraca współrzędną X tego obiektu klasy GameObject.
    */
    public float getX() {
        return getLocation().x;
    }


    /**
        Zwraca współrzędną Y tego obiektu klasy GameObject.
    */
    public float getY() {
        return getLocation().y;
    }


    /**
        Zwraca współrzędną Z tego obiektu klasy GameObject.
    */
    public float getZ() {
        return getLocation().z;
    }


    /**
        Ustawia stan tego obiektu. Parametr state powinien mieć
        wartość STATE_IDLE, STATE_ACTIVE lub STATE_DESTROYED.
    */
    protected void setState(int state) {
        this.state = state;
    }


    /**
        Ustawia stan wskazanego obiektu. Dzięki temu dowolny obiekt
        GameObject może zmienić stan dowolnego innego obiektu GameObject.
        Parametr state powinien mieć wartość STATE_IDLE, STATE_ACTIVE lub
        STATE_DESTROYED.
    */
    protected void setState(GameObject object, int state) {
        object.setState(state);
    }


    /**
        Zwraca true, jeśli ten obiekt GameObject jest w stanie bezczynności.
    */
    public boolean isIdle() {
        return (state == STATE_IDLE);
    }


    /**
        Zwraca true, jeśli ten obiekt GameObject jest w stanie aktywności.
    */
    public boolean isActive() {
        return (state == STATE_ACTIVE);
    }


    /**
        Zwraca true, jeśli ten obiekt GameObject jest w stanie zniszczenia.
    */
    public boolean isDestroyed() {
        return (state == STATE_DESTROYED);
    }


    /**
        Jeśli ten GameObject znajduje się w stanie aktywności, ta
        metoda aktualizuje jego obiekt PolygonGroup. W przeciwnym
        przypadku, metoda nie wykonuje żadnych działań.
    */
    public void update(GameObject player, long elapsedTime) {
        if (isActive()) {
            polygonGroup.update(elapsedTime);
        }
    }


    /**
        Informuje ten GameObject o tym, czy był widoczny, czy nie,
        podczas ostatniej aktualizacji. Domyślnie, jeśli ten GameObject
        znajduje się w stanie bezczynności i otrzymuje informację, że
        jest widoczny, przechodzi w stan aktywności.
    */
    public void notifyVisible(boolean visible) {
        if (visible && isIdle()) {
            state = STATE_ACTIVE;
        }
    }

}
