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

/**
 * Class Sky represents the World in which players have to pop the balloons by typing the letters in them.
 * 
 * @author Maria - Despoina Gkaintatzi
 * @version 24.04.2015
 */
public class Sky extends World
{
    private Snail snail;
    private Counter scoreCounter;
    private Counter lifeCounter;
    long lastAdded = System.currentTimeMillis();

    /**
     * Constructor for objects of class Sky.
     * 
     */
    public Sky(Snail snail, int score)
    {    
        super(1200, 800, 1);
        scoreCounter = new Counter("Score: ", score, score);
        lifeCounter = new Counter("Lives: ", 5, 5);
        addObject(scoreCounter, 1100, 50);
        addObject(lifeCounter, 1100, 100);
        addObject(snail, 50, 450);
    }

    /**
     * Act method for class Sky.
     */
    public void act()
    {
        addBalloons();
        checkLives();  
        checkHighScore();
    }

    /**
     * Returns the scoreCounter.
     * 
     * @return Counter scoreCounter
     */
    public Counter getScoreCounter()
    {
        return scoreCounter;
    }

    /**
     * Returns the lifeCounter.
     * 
     * @return Counter lifeCounter
     */
    public Counter getLifeCounter()
    {
        return lifeCounter;
    }

    /**
     * This method is called when the game is over to display the final score.
     * 
     * @param message(String) the message to be displayed when game is over.
     */
    public void gameOver(String message) 
    {
        addObject(new ScoreBoard(message,scoreCounter.getValue()),getWidth()/2 , getHeight()/2);
    }

    /**
     * Creates a balloon with a letter drawn in it 
     * after a given number of seconds.
     * 
     * @param seconds(int) after how many seconds the balloon will be created.
     */
    private void createBalloon(int seconds)
    {
        long curTime  = System.currentTimeMillis();
        if (curTime >= lastAdded + seconds) 
        {   
            Letter newLetter = new Letter(Color.yellow); // creates a random letter
            Balloon newBalloon = new Balloon(50, new Vector(270,5), newLetter.getTextImage().getText()); // creates the balloon
            List<Letter> letters = this.getObjects(Letter.class); // gets a list with all the existing letters in the world

            if (letters.isEmpty())                              // if there are no letters
            {
                addObject(newLetter, 600, 100);                 // add newLetter in the world
            }
            else if (letters.size() == 1)                       // if there is one letter
            {
                letters.get(0).move(-60);                       // move the letter to the left and
                addObject(newLetter, 600, 100);                 // add newLetter in its place
            }
            else                                                //if more than one letter
            {
                int maxX = 0;
                for (Letter currentLetter : letters)            // finds the x coordinate of the first letter in the right
                {
                    if (currentLetter.getX() > maxX)
                    {
                        maxX = currentLetter.getX();
                    }
                }

                int x = 0;
                int y = 0;
                List<Letter> temp = new ArrayList();

                while(!letters.isEmpty())                       // puts letters in a temp list according to their position in the world
                {                                               // the first element is the first letter on the left and the last is the first letter on th right

                    for (int i = 0; i < letters.size(); i++)
                    {   
                        x = letters.get(i).getX();
                        y = letters.get(i).getY();
                        if (x == getMinX(letters))
                        {
                            temp.add(letters.get(i));
                            letters.remove(i);
                        }
                    }

                }

                for (Letter currentLetter : temp)               // moves every letter of temp list to the left
                {
                    currentLetter.move(-50);
                }
                addObject(newLetter, maxX, y);                  // adds newLetter
            }
            addObject(newBalloon, Greenfoot.getRandomNumber(1100), 800);            // adds the balloon

            lastAdded  = curTime;
        }
    }

    /**
     * Accelerates the addition of balloons to the world according to the player's score.
     */
    private void addBalloons()
    {
        if (scoreCounter.getValue() < 300)
        {
            createBalloon(4000);
        }
        else if (scoreCounter.getValue() >= 300 && scoreCounter.getValue() < 350)
        {
            createBalloon(3000);
        }
        else if (scoreCounter.getValue() >= 350 && scoreCounter.getValue() < 500)
        {
            createBalloon(2000);
        }
        else
        {
            createBalloon(1000);
        }
    }

    /**
     * Checks if the player has reached a high score and ends the game.
     */
    private void checkHighScore()
    {
        if (scoreCounter.getValue() == 20000)
        {
            Greenfoot.playSound("Ta Da.wav");
            gameOver("Congradulations!");
            Greenfoot.stop();
        }
    }

    /**
     * Checks if the player has used all the lifes that has at his disposal and ends the game.
     */
    private void checkLives()
    {
        if (lifeCounter.getValue() == 0)
        {
            Greenfoot.playSound("fanfare.wav");
            gameOver("Game Over");
            Greenfoot.stop();
        }
    }

    /**
     *  Gets the first Letter from the left among a number of Letters
     *  
     *  @param letters (List<Letter>) a list of Letters 
     */
    private int getMinX(List<Letter> letters)
    {
        int min = 1200;
        for (Letter currentLetter : letters )
        {
            if (currentLetter.getX() < min)
            {
                min = currentLetter.getX();
            }
        }

        return min;
    }
}
