/*
 * Copyright (C) 2013 Darth Affe <http://wyrez.org> and contributors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.wyrez.shootingstars.game;

import com.jme3.asset.AssetManager;
import com.jme3.input.InputManager;
import com.jme3.light.AmbientLight;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import org.wyrez.shootingstars.controls.PlayerCamControl;
import org.wyrez.shootingstars.controls.PlayerMouseControl;
import org.wyrez.shootingstars.controls.PlayerMoveControl;
import org.wyrez.shootingstars.controls.PlayerShootControl;
import org.wyrez.shootingstars.controls.WeaponProjectileCollisionControl;
import org.wyrez.shootingstars.controls.WeaponProjectileControl;
import org.wyrez.shootingstars.data.AudioDataManager;
import org.wyrez.shootingstars.factories.Materials;
import org.wyrez.shootingstars.gui.GameGUI;
import org.wyrez.shootingstars.helper.MathHelper;
import org.wyrez.shootingstars.helper.UserDataKeys;
import org.wyrez.shootingstars.mesh.HexPrism;
import org.wyrez.shootingstars.states.StateManager;
import org.wyrez.shootingstars.states.util.OptionSettings;

/**
 *
 * @author Darth Affe
 */
public class Player extends Node {

    private Node weaponContainer;
    private Spatial weapon;
    private Node projectile;

    public Player(Node rootNode, StateManager stateManager, AssetManager assetManager,
            ViewPort viewPort, GameGUI gui, InputManager inputManager, Camera camera,
            AudioDataManager audioDataManager, Node starNode, OptionSettings settings) {
        super("Player");

        initPlayer(inputManager, camera, audioDataManager, gui);
        if (settings.isShowWeaponEnabled()) {
            initWeapon(assetManager);
            initProjectile(rootNode);
            initWeaponContainer();
        }
        initGhostProjectile(starNode);
        addLight();
    }

    private void initPlayer(InputManager inputManager, Camera camera,
            AudioDataManager audioDataManager, GameGUI gui) {
        this.setUserData(UserDataKeys.RUNNING, false);
        this.setUserData(UserDataKeys.SHOOTING, false);
        this.setUserData(UserDataKeys.POINTS, 0);
        this.addControl(new PlayerMouseControl(inputManager, camera));
        this.addControl(new PlayerMoveControl(audioDataManager));
        this.addControl(new PlayerShootControl(inputManager, gui));
        this.addControl(new PlayerCamControl(camera));
    }

    private void initWeapon(AssetManager assetManager) {
        weapon = assetManager.loadModel("Models/sniper.mesh.j3o");
        weapon.rotate(0f, MathHelper.degreeToRadian(90f), 0f);
        weapon.scale(0.33f);
    }

    private void initProjectile(Node rootNode) {
        projectile = new Node("projectile");

        Geometry geom1 = new Geometry("weapon", new HexPrism(0.1f, 3f));
        geom1.setMaterial(Materials.WEAPON.create());
        geom1.rotate(MathHelper.degreeToRadian(90f), 0f, 0f);
        geom1.move(0f, -0.15f, 0f);
        projectile.attachChild(geom1);

        Geometry geom2 = new Geometry("weapon", new Box(0.1f, 0.2f, 4.25f));
        geom2.setMaterial(Materials.WEAPON.create());
        geom2.move(0f, 0.25f, -5f);
        projectile.attachChild(geom2);

        projectile.addControl(new WeaponProjectileControl(rootNode, this));
    }

    private void initWeaponContainer() {
        weaponContainer = new Node("weaponContainer");
        weaponContainer.attachChild(weapon);
        weaponContainer.attachChild(projectile);

        weaponContainer.rotate(MathHelper.degreeToRadian(-10f), MathHelper.degreeToRadian(10f), MathHelper.degreeToRadian(-5f));
        weaponContainer.move(-0.41f, -0.28f, 9f);

        weaponContainer.scale(0.75f);

        this.attachChild(weaponContainer);
    }

    private void initGhostProjectile(Node starNode) {
        Geometry ghostProjectile = new Geometry("ghostProjectile", new Box(0.1f, 0.1f, 2500f));
        ghostProjectile.setMaterial(Materials.UNSHADED.create());
        ghostProjectile.setCullHint(CullHint.Always);
        ghostProjectile.move(0f, 0f, 2510f);
        ghostProjectile.addControl(new WeaponProjectileCollisionControl(starNode, this));
        this.attachChild(ghostProjectile);
    }

    private void addLight() {
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(ColorRGBA.White);
        this.addLight(ambient);
    }
}
