import greenfoot.*;
import java.util.List;
import java.util.ArrayList;
import java.awt.Color;
import java.awt.Font;

/**
 * This class creates a Snail object.
 * 
 * @author Maria - Despoina Gkaintatzi 
 * @version 12.06.2015
 */
public class Snail extends SmoothMover
{
    public static int LEVEL = 1;
    private MessageBoard messageLevel;
    private Bubble bubble;
    private Vector speed;
    private int size;
    private int hit = 0;
    private int count = 2;
    private List<GreenfootImage> images;
    private long curTime = 0;
    private long lastShown = 0;

    /**
     * Constructor for the objects of class Snail.
     * 
     * @param size(int) the desirable size
     */
    public Snail(int size)
    {
        super(new Vector(0, 1));
        setSize(size);
    }

    /**
     * Constructor for the objects of class Snail.
     * 
     * @param size(int) the desirable size
     * @param speed(Vector) the speed of the snail
     */
    public Snail(int size, Vector speed)
    {
        super(speed);
        images = new ArrayList(11);
        images.add(0,new GreenfootImage("snail1.gif"));
        images.add(1,new GreenfootImage("snail2.gif"));
        images.add(2,new GreenfootImage("snail3.gif"));
        images.add(3,new GreenfootImage("snail4.gif"));
        images.add(4,new GreenfootImage("snail5.gif"));
        images.add(5,new GreenfootImage("snailLooking.gif"));
        images.add(6,new GreenfootImage("snailWaiting2.gif"));
        images.add(7,new GreenfootImage("snailWaiting3.gif"));
        images.add(8,new GreenfootImage("snailBack.gif"));
        images.add(9,new GreenfootImage("snailBack1.gif"));
        images.add(10,new GreenfootImage("snailBack2.gif"));

        if (getWorld() instanceof City){
            setImage(images.get(0)); 
        }
        else
        {
            setImage(images.get(5));
        }
    }

    /**
     * Act - do whatever the Snail wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        checkNextLevel();
        checkKeys();
        if (getWorld() instanceof City)
        {
            ((City)getWorld()).scrollBackground();
            move();
            makeSmoke();
            changeImage();
        }  
        if (getWorld() instanceof Desktop)
        {
            move();
            makeSmoke();
            changeImage();
        }
        curTime = System.currentTimeMillis();
        if (curTime >= lastShown + 3000)
        {
            getWorld().removeObject(bubble);
            lastShown = curTime;
        }
    }  

    /**
     * Sets the size of this snail. 
     * 
     * @param size(int) the desirable size
     */
    public void setSize(int size) 
    {
        this.size = size;
        GreenfootImage image = getImage();
        image.scale(size, size);
    }

    /**
     * Makes a sound every time a key is pressed. The sound differs according to whether the key
     * is the key in question.
     * 
     * @param correct(boolean) true if the key is correct
     */
    public void makeSound(boolean correct)
    {

        if (correct)
            Greenfoot.playSound("Yes.wav");
        else
            Greenfoot.playSound("Aww.wav");

    }

    /**
     * Checks if Snail has reached the desirable speed to get to the next level.
     */
    private void checkNextLevel()
    {
        if(LEVEL == 1 && Letter.ITERATIONS > 456)
        //if(LEVEL == 1 && Letter.ITERATIONS > 20)
        {
            LEVEL++;
            messageLevel = new MessageBoard("Congradulations!", "Click here to go to Level " + LEVEL);
            ((City)getWorld()).addObject(messageLevel, 600, 400);
            resetLives();
        }
        if(LEVEL == 2 && Letter.ITERATIONS > 679)
        //if(LEVEL == 2 && Letter.ITERATIONS > 40)
        {
            LEVEL = 3;
            messageLevel = new MessageBoard("Congradulations", "Click here to go to Level " + LEVEL);
            ((City)getWorld()).addObject(messageLevel, 600, 400);
            resetLives();
        }
        if(LEVEL == 3 && Letter.ITERATIONS > 1023)
        //if(LEVEL == 3 && Letter.ITERATIONS > 60)
        {
            LEVEL = 4;
            messageLevel = new MessageBoard("Congradulations", "Click here to go to Level " + LEVEL);
            ((City)getWorld()).addObject(messageLevel, 600, 400);
            resetLives();
        }
        if(LEVEL == 4 && Letter.ITERATIONS > 1213)
        //if(LEVEL == 4 && Letter.ITERATIONS > 80)
        {
            LEVEL = 5;
            messageLevel = new MessageBoard("Congradulations", "Click here to go to Level " + LEVEL);
            ((City)getWorld()).addObject(messageLevel, 600, 400);
            resetLives();
        }

        if(LEVEL == 5 && Letter.ITERATIONS > 1689)
        //if(LEVEL == 5 && Letter.ITERATIONS > 100)
        {
            LEVEL = 6;
            messageLevel = new MessageBoard("Congradulations", "Click here to go to Level " + LEVEL);
            ((City)getWorld()).addObject(messageLevel, 600, 400);
            int score = ((City)getWorld()).getScoreCounter().getValue();
            Greenfoot.setWorld(new Sky(this,score));
        }

    }

    /**
     * Changes the image of the Snail to create a movement effect.
     */
    private void changeImage()
    {

        if (getImage() == images.get(5))
        {
            setImage(images.get(1));
        }

        if (getImage() == images.get(4))
        {
            setImage(images.get(1));
        }
        else if (getImage() == images.get(1))
        {
            setImage(images.get(2));
        }
        else if (getImage() == images.get(2))
        {
            setImage(images.get(3));
        }
        else if (getImage() == images.get(3))
        {
            setImage(images.get(4));
        }

    }

    /**
     * Checks whether the appropriate key is being pressed and acts accordingly.
     */
    private void checkKeys()
    {
        if (getWorld() instanceof City){
            List <Letter> letters = ((City)getWorld()).getObjects(Letter.class);
            List <Arrow> arrows = ((City)getWorld()).getObjects(Arrow.class);
            Letter letter = letters.get(0);
            String aLetter = letter.getTextImage().getText();
            TextImage image;

            if (Greenfoot.getKey() != null)
            {
                if (Greenfoot.isKeyDown(aLetter))
                {   
                    makeSound(true);
                    ((City)getWorld()).scrollBackground();
                    ((City)getWorld()).getScoreCounter().add(10, 20000);
                    ((City)getWorld()).resetButtonColor(aLetter);
                    ((City)getWorld()).removeObjects(letters);
                    ((City)getWorld()).removeObjects(arrows);
                    ((City)getWorld()).addObject(new Letter(Color.yellow), 600, 100);
                    hit++;
                    if (hit%150 == 0)                   // accelerates the speed of the snail, every 150 successive times that a letter was typed correctly
                    {                            
                        accelerate(1.1);
                        showEncouragementMessage("You are doing great!");
                    }
                    if (hit == 200)                   // gives an extra life, every 180 successive times that a letter was typed correctly
                    {                           
                        hit = 0;
                        ((City)getWorld()).getLifeCounter().subtract(-1, 0);
                        showEncouragementMessage("You just won a life!");
                    }

                }
                else 
                {   
                    makeSound(false);
                    image = letter.getTextImage().colored(Color.red, null);
                    letter.setImage(image);
                    ((City)getWorld()).getLifeCounter().subtract(1, 0);
                    setMovement(new Vector(0,1));           // when misses, sets the snail's speed to the initial
                }
            }
        }
    }

    /**
     * Put out a puff of smoke (only on every second call).
     */
    private void makeSmoke()
    {
        count--;
        if (count == 0) {
            getWorld().addObject ( new Smoke(), getX()-20, getY()+12);
            count = 2;
        }
    }

    /**
     * Displays a message from the snail to the user.
     */
    private void showEncouragementMessage(String message)
    {
        bubble = new Bubble(20,getMovement(),message,new Font("Helvetica", Font.BOLD, 30), 50);
        getWorld().addObject(bubble, getX() + 50, getY() - 110); 
        lastShown = System.currentTimeMillis();
    }

    /**
     * Resets life counter to five.
     */
    private void resetLives()
    {
        while (((City)getWorld()).getLifeCounter().getValue() < 5)
        {
            ((City)getWorld()).getLifeCounter().subtract(-1, 0);
        }
    }
}
