package ru.cdmlex.jtest.model;

import java.util.ArrayList;
import java.util.List;
import java.awt.*;
import ru.cdmlex.jtest.Materials;
import static ru.cdmlex.jtest.Constants.*;

public class Snake {
        private List<BodyPart> body;
        private Direction dir;
        public Snake(int x, int y, Direction dir) {
            this.dir = dir;
            body = new ArrayList<BodyPart>();
            body.add(new BodyPart(x, y, dir));
            body.add(new BodyPart(x - dir.deltaX(), y - dir.deltaY(), dir));
            body.add(new BodyPart(x - dir.deltaX() * 2, y - dir.deltaY() * 2, dir));
			body.add(new BodyPart(x - dir.deltaX() * 3, y - dir.deltaY() * 3, dir));
			body.add(new BodyPart(x - dir.deltaX() * 4, y - dir.deltaY() * 4, dir));
        }
        public void move(Map map) {
			if (map.freeway(head().getX() + dir.deltaX(), head().getY() + dir.deltaY())) {
				moveBody();
				moveHead();
			}
        }
        private void moveBody() {
            for (int i = body.size() - 1; i > 0; i--) {
                BodyPart current = body.get(i);
                BodyPart previous = body.get(i - 1);
                current.setX(previous.getX());
                current.setY(previous.getY());
				current.dir = previous.dir;
				current.end = ((body.size() - 1) == i);
            }
        }
        private void moveHead() {
            head().setX(head().getX() + dir.deltaX());
            head().setY(head().getY() + dir.deltaY());
			head().dir = dir;
        }
        public BodyPart head() {
            return body.get(0);
        }
        public List<BodyPart> getBody() {
            return body;
        }
        public Direction getDirection() {
            return dir;
        }
        public void setDirection(Direction dir) {
            this.dir = dir;
        }
		public void add() {
			BodyPart lastPart = body.get(body.size() - 1);
			lastPart.end = false;
			BodyPart newPart = new BodyPart(lastPart.getX(), lastPart.getY(), lastPart.dir);
			newPart.end = true;
			body.add(newPart);
		}
		public void dec() {
			int sz = body.size();
			if (sz > 1)
			body.remove(sz - 1);
		}
		public void draw(Graphics2D g, Materials materials, boolean fire) {
			int prev = - 1;
			for (BodyPart bodyPart : body) {
				int n = bodyPart.dir.SpriteNum();
				if (prev == - 1) {
					int n1 = n;
					if (fire) {
						if (n == 1) n1 = 4;
						else
						if (n == 3) n1 = 5;
					}
					materials.s_g.draw_a(g, bodyPart.getX() * CELL_SIZE - 0, (bodyPart.getY() * CELL_SIZE) - 0, n1);
				}
				else
				if (bodyPart.end)
					materials.s_h.draw_a(g, bodyPart.getX() * CELL_SIZE - 0, (bodyPart.getY() * CELL_SIZE) - 0, prev);
				else {
					int n1 = n;
					if (prev != n) {
						if ((n == 0) & (prev == 1) | (n == 3) & (prev == 2))
							n1 = 2;
						if ((n == 1) & (prev == 2) | (n == 0) & (prev == 3))
							n1 = 3;
						if ((n == 2) & (prev == 3) | (n == 1) & (prev == 0))
							n1 = 4;
						if ((n == 3) & (prev == 0) | (n == 2) & (prev == 1))
							n1 = 5;					
					}
					else 
						if (n > 1) n1-=2;
					materials.s_t.draw_a(g, bodyPart.getX() * CELL_SIZE - 0, (bodyPart.getY() * CELL_SIZE)- 0, n1);
				}
				prev = n;
			}
		}		
}

