/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package tankattack;

import Sprites.*;
import java.util.*;
import javafx.animation.*;
import javafx.geometry.*;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.stage.*;
import javafx.util.*;

/**
 *
 * @author Ruslan
 */
public abstract class World {
    
    public static boolean isListeningForInput = true;
    
    private Stage myStage;
    
    private Scene scene;
    private Group root;
    private Circle myEnemy;
    private Point2D myEnemyVelocity;
    private Random myGenerator = new Random();
    
    private ArrayList<Sprite> sprites;
    private Player playerSprite;
        
    private Timeline timeline;
    
    // Performance-Improving Variables
    // created to not create objects @ 60Hz
    private double[] playerLocation;   
    private double[] newXY;
    
    
    // Setters, Getters
    public void addSprite(Sprite s) {
        
        if (sprites == null) {
            
            sprites = new ArrayList();
            
        }
        
        sprites.add(s);
        root.getChildren().add(s);
        
    }
    
    public void removeSprite(Sprite s) {
        
        if (sprites == null) {
            
            return;
            
        }
        
        sprites.remove(s);
        root.getChildren().remove(s);
        
    }
        
    public void setPlayerSprite(Player player) {
        
        playerSprite = player;
        
    }
    
    public Player getPlayerSprite() {
        
        return playerSprite;
        
    }
    
    public Group getGroup() {
        
        return this.root;
        
    }
    
    public void setGroup(Group root) {
        
        this.root = root;
        
    }
    
    public Scene getScene() {
        
        return this.scene;
        
    }
    
    public void setScene(Scene scene) {
        
        this.scene = scene;
        
    }
    
    // Real Methods
        // Constructors
        // Create Scene, Then Init Animation. Rest of methods are helpers.
    
    public World() {
        throw new UnsupportedOperationException("need to pass in a stage"); 
    }
    
    public World(Stage stage) {
        
        this.myStage = stage;
        
    }
    
    public Scene createScene() {
        
        root = new Group();
        createInitialSprites();
        
        scene = new Scene(root, TankAttack.gameWidth, TankAttack.gameHeight, Color.CORNFLOWERBLUE);
        scene.setOnKeyPressed(e -> handleKeyInput(e));
        scene.setOnKeyReleased(e -> handleKeyRelease(e));
        return scene;
        
    }
    
    public void initAnimation() {
        
        KeyFrame frame = new KeyFrame(Duration.millis(1000 / TankAttack.NUM_FRAMES_PER_SECOND), e -> updateSprites());
        
        if (timeline == null) {
            
            timeline = new Timeline();
            
        }        
        
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.getKeyFrames().add(frame);
        timeline.play();
        
    }

    public abstract void createInitialSprites();
    
    public void createPlayerSprite() {
                
        Player player = new Player(TankAttack.gameWidth/2 , TankAttack.gameHeight / 2);
                
        setPlayerSprite(player);
        addSprite(player);
    
    }

    private void updateSprites() {

//        System.out.println("All is well. Printing animation 60 times a second.");
        
        // Update Player
        updatePlayerLocation();

        // Other Updates
        
        
        // Temporary end to game
        if (playerSprite.getTranslateX() < 10) {
            
            System.out.println("updateSprites calling finish.");
            endOfLevel();
            
            // TODO Implement this.
            // Player is left all alone. Stop animation. Level defeated.
            
            
        }
        
    }
    
    private void updatePlayerLocation() {
                
        if (playerLocation == null) {
            
            playerLocation = new double[2];
            
        }
        
        playerLocation[0] = playerSprite.getTranslateX();
        playerLocation[1] = playerSprite.getTranslateY();            
                
        double playerWidth  = playerSprite.width();
        double playerHeight = playerSprite.height();

        if (newXY == null) {
            
            newXY = new double[2];
            
        }
        
        newXY = DirController.getNewXY(playerLocation, playerWidth, playerHeight, TankAttack.PLAYER_SPEED);
        
        playerSprite.setTranslateX(newXY[0]);
        playerSprite.setTranslateY(newXY[1]);    
    
    }

    private void endOfLevel() {
        
        timeline.pause();
        
        // TODO: Display level complete.
        showEndOfLevelText();
        
        // Tell TankAttack to put up the next world.
        signalEndOfLevel();
        
    }
    
    private void showEndOfLevelText() {
        
        System.out.println("TODO: Animate text over this level's end saying END OF LEVEL.");
        
    }
    
    public abstract void signalEndOfLevel();
    
    public void handleKeyInput(KeyEvent e) {
        
        KeyCode keyCode = e.getCode();
                
        if (keyCode == KeyCode.RIGHT) {
            
            DirController.rightPressed = true;
            
        }
        
        else if (keyCode == KeyCode.LEFT) {
            
            DirController.leftPressed = true;
            
        }
        
        else if (keyCode == KeyCode.UP) {
            
            DirController.upPressed = true;
            
        }
        
        else if (keyCode == KeyCode.DOWN) {
            
            DirController.downPressed = true;
            
        }
        
        // TODO: Implement space bar to shoot, and cheat codes, here.
        
    }

    public void handleKeyRelease(KeyEvent e) {
        
        KeyCode keyCode = e.getCode();
        
        if (keyCode == KeyCode.RIGHT) {
            
            DirController.rightPressed = false;
            
        }
        
        else if (keyCode == KeyCode.LEFT) {
            
            DirController.leftPressed = false;
            
        }
        
        else if (keyCode == KeyCode.UP) {
            
            DirController.upPressed = false;
            
        }
        
        else if (keyCode == KeyCode.DOWN) {
            
            DirController.downPressed = false;
            
        }
        
    }


}







@@ -3695,22 +3695,46 @@
   //
- Update Player
+//// DONE ////////////////////////////
 %0A   
@@ -3777,384 +3777,411 @@
   //
- Other Updates%0A        %0A        %0A        // Temporary end to game%0A        if (playerSprite.getTranslateX() %3C 10) %7B%0A            %0A            System.out.println(%22updateSprites calling finish.%22);%0A            endOfLevel();%0A            %0A            // TODO Implement this.%0A            // Player is left all alone. Stop animation. Level defeated.%0A            %0A            %0A        %7D
+//// DONE ////////////////////////////%0A        %0A        ////// IMPLEMENT ////////////////////////////%0A        // Other Updates%0A//        updateEnemySprites();%0A        %0A        // Handle Firing%0A        handleFiring();%0A        %0A        // Register Collisions / Hits%0A//        handleCollision();%0A        %0A        // Check for win%0A        checkForWin();%0A        ////// IMPLEMENT ////////////////////////////
 %0A   

update method refactor, new stubs