import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;

/**
 * Die Schlange, die vom Spieler gesteuert wird
 * 
 * @author Rainer Helfrich
 * @version April 2020
 */
public class Snake extends Actor
{
    /**
     * Die Queue, die die Körperelemente enthält
     */
    private Queue<SnakeElement> theQueue;

    /**
     * Die aktuelle Bewegungsrichtung der Schlange
     */
    private char richtung;

    /**
     * Konstanten für die vier Bewegungsrichtungen
     */
    private final char OBEN = 'w';
    private final char UNTEN = 's';
    private final char LINKS = 'a';
    private final char RECHTS = 'd';

    /**
     * Erzeugt eine neue Schlange und platziert sie in der Welt.
     */
    public Snake(World w)
    {
        theQueue = new ArrayQueue();
        SnakeElement el = new SnakeElement();
        w.addObject(el, 15, 10);
        theQueue.enqueue(el);
        el = new SnakeElement();
        w.addObject(el, 14, 10);
        theQueue.enqueue(el);
        richtung = RECHTS;
    }

    /**
     * Prüft, ob die Taste zum Buchstaben c gedrückt ist
     * @param c Die Taste, die überprüft wird
     * @return true, wenn die Taste gedrückt ist; false sonst
     */
    private boolean isKeyDown(char c)
    {
        return Greenfoot.isKeyDown(""+c);
    }

    private int neuePosition(int p, int g)
    {
        if (p < 0)
        {
            p += g;
        }
        return p % g;
    }

    /**
     * Wird in jedem Zeitschritt aufgerufen
     */
    public void act() 
    {
        if (isKeyDown(OBEN) && richtung != UNTEN)
        {
            richtung = OBEN;
        }
        else if (isKeyDown(UNTEN) && richtung != OBEN)
        {
            richtung = UNTEN;
        }
        else if (isKeyDown(LINKS) && richtung != RECHTS)
        {
            richtung = LINKS;
        }
        else if (isKeyDown(RECHTS) && richtung != LINKS)
        {
            richtung = RECHTS;
        }
        SnakeWorld sw = (SnakeWorld)getWorld();

        int x = getX();
        int y = getY();
        if (richtung == OBEN)
        {
            y--;
        }
        else if (richtung == UNTEN)
        {
            y++;
        }
        else if (richtung == LINKS)
        {
            x--;
        }
        else if (richtung == RECHTS)
        {
            x++;
        }
        x = neuePosition(x, getWorld().getWidth());
        y = neuePosition(y, getWorld().getHeight());

        List<Apple> apples = sw.getObjectsAt(x, y, Apple.class);
        SnakeElement el;
        if (!apples.isEmpty())
        {
            Apple a = apples.get(0);
            sw.removeObject(a);
            sw.placeApple();
        }
        else
        {
            el = theQueue.dequeue();
            sw.removeObject(el);
        }
        if (!sw.getObjectsAt(x, y, SnakeElement.class).isEmpty()) // Kollision mit sich selbst
        {
            sw.setGameOver();
            return;
        }
        el = new SnakeElement();   
        sw.addObject(el, x, y);
        theQueue.enqueue(el);
        setLocation(x, y);
    }    
}
