package ru.cdmlex.jtest;

import ru.cdmlex.jtest.model.*;
import java.awt.event.KeyEvent;
import java.awt.*;
import java.util.List;

import ru.cdmlex.jtest.Scene;
import static ru.cdmlex.jtest.Constants.*;

public class MainScene extends Scene {
    private Snake snake;
	private Map map;
	private Delay snakeMoveDelay;
	private Materials materials;
	private BodyPart bullet;
	private int snake_timer;
	private boolean fire_on;
	private boolean fire_show;
	public static int level = 1;
    public MainScene(JGame game) {
        super(game);
        snake = new Snake(WORLD_WIDTH / 2, WORLD_HEIGHT / 2, Direction.RIGHT);
		snakeMoveDelay = new Delay(95);
		materials = new Materials();
		
		bullet = new BodyPart(0, 0, null);
		
		nextLevel();
    }
	private void nextLevel() {
		
		if (level > 7) {
			game.setScene(new GameOverScene(game, 2, snake.getBody().size()));
			level = 1;
		}
		else
			map = new Map("m"+level+".txt");
		bullet.end =true;
		snake_timer = 0;
		fire_show = false;		
		fire_on = false;
	}
	
    @Override
    public void update(long nanosPassed) {
		processInput();
         if (snakeMoveDelay.updateAndCheck(nanosPassed)) {

			
			map.update();

			
			snake_timer--;
			if (snake_timer < 1) {
				fire_show = false;
				BodyPart head = snake.head();
				switch (map.action(head.getX(), head.getY())) {
					case 1 : snake.add(); break;
					case 2 : fire_on = true; break;
					case 0 : level++;  nextLevel(); break;
					case 12 : snake.dec(); break;
					case 14 : snake.dec(); snake.dec(); break;
					case 16 : snake.dec(); snake.dec(); snake.dec(); break;
				}		

				snake.move(map);
				
				if (head.getX() < 0) 
					head.setX(WORLD_WIDTH-1);
				else
				if (head.getX() >= WORLD_WIDTH) 
					head.setX(0);
				
				if (head.getY() < 0)
					head.setY(WORLD_HEIGHT-1);
				else
				if (head.getY() >= WORLD_HEIGHT)
					head.setY(0);
				
				if (isGameOver()) {
					game.setScene(new GameOverScene(game, 1, snake.getBody().size()));
				}
				
				snake_timer = 2;
			}
			
            bullet_update();

        }
    }
    @Override
    public void draw(Graphics2D g) {
        g.setColor(new Color(75, 114, 122));
        g.fillRect(0, 0, game.getScreenSize().width, game.getScreenSize().height);
        //Materials.s_exit.draw(g, map.exit_x * CELL_SIZE, map.exit_y * CELL_SIZE-CELL_SIZE);
		map.draw0(g, materials);
		snake.draw(g, materials, fire_show);
		if (!bullet.end) {
			materials.s_tl[0].draw_a(g, bullet.getX() * CELL_SIZE, bullet.getY() * CELL_SIZE, 1);
		}
		map.draw1(g, materials);
    }
	
    public void fire() {
		if (bullet.end) {
			fire_on = false;
			bullet.end = false;
			BodyPart head = snake.head();
			bullet.setX(head.getX());
			bullet.setY(head.getY());
			bullet.dir = head.dir;
			bullet_update();
			fire_show = true;
		}
    }
	
	public void bullet_update() {
		if (!bullet.end) {
			int x = bullet.getX() + bullet.dir.deltaX();
			int y = bullet.getY() + bullet.dir.deltaY();
			
            bullet.setX(x);
            bullet.setY(y);
			
			for (BodyPart bodyPart : snake.getBody())
            if (bodyPart.getX() == x & bodyPart.getY() == y) {
                bullet.end = true;
				game.setScene(new GameOverScene(game, 1, 0));
				break;
            }
			
			if (map.bullet_col(x, y)) {
			  bullet.end = true;
			  map.placeApple(2, -2);
			}
		}
    }
    /*
    private boolean isCellEmpty(int x, int y) {
        for (BodyPart bodyPart : snake.getBody()) {
            if (bodyPart.getX() == x && bodyPart.getY() == y) {
                return false;
            }
        }
        return true;
    }
	*/
	private void processInput() {
        for (KeyEvent event : game.getInput().getKeyPressedEvents()) {
            switch (event.getKeyCode()) {
                case KeyEvent.VK_UP: case KeyEvent.VK_W:
					if (snake.head().dir != Direction.DOWN)
						snake.setDirection(Direction.UP);
                    break;
                case KeyEvent.VK_RIGHT: case KeyEvent.VK_D:
					{if (snake.head().dir != Direction.LEFT)
						snake.setDirection(Direction.RIGHT);}
                    break;
                case KeyEvent.VK_DOWN: case KeyEvent.VK_S:
					{if (snake.head().dir != Direction.UP)
						snake.setDirection(Direction.DOWN);}
                    break;
                case KeyEvent.VK_LEFT: case KeyEvent.VK_A:
					{if (snake.head().dir != Direction.RIGHT)
						snake.setDirection(Direction.LEFT);}
                    break;
				case KeyEvent.VK_R: case KeyEvent.VK_SPACE:
					if (fire_on)
						fire();
                    break;
            }
        }
    }
	
    private boolean isGameOver() {
        if (snake.getBody().size() == WORLD_WIDTH * WORLD_HEIGHT) {
            return true;
        }
		if (snake.getBody().size() <= 1)
			return true;
			
        for (BodyPart bodyPart : snake.getBody()) {
            if (bodyPart != snake.head()
                    && snake.head().getX() == bodyPart.getX()
                    && snake.head().getY() == bodyPart.getY()) {
                return true;
            }
        }

        return false;
    }

}
