/*
 * 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.light.AmbientLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import org.wyrez.shootingstars.data.AudioDataManager;
import org.wyrez.shootingstars.controls.GroundBorderGlowControl;
import org.wyrez.shootingstars.controls.GroundGlowControl;
import org.wyrez.shootingstars.controls.GroundMoveControl;
import org.wyrez.shootingstars.factories.Materials;
import org.wyrez.shootingstars.mesh.HexPrism;

/**
 *
 * @author Darth Affe
 */
public class Ground extends Node {
    
    public Ground(AudioDataManager adm) {
        this(adm, 1000f);
    }
    
    public Ground(AudioDataManager adm, float radius) {
        this(adm, radius, 0.1f);
    }
    
    public Ground(AudioDataManager adm, float radius, float factor) {
        super("Ground");
        generateHexGrid(adm, radius, factor);
        addLight();
    }

    //TODO cleanup
    private void generateHexGrid(AudioDataManager adm, float borderWidth, float factor) {
        float size = borderWidth * factor;
        int maxIterations = (int) (borderWidth / size) - 2;
        
        Node prism = new GlowingHexPrism(new Vector3f(0f, -140f, 0f), size, 150f, 0.8f, adm);
        prism.addControl(new GroundMoveControl(adm));
        this.attachChild(prism);
        
        float xcc = 0f;
        float ycc = 0f;
        float centerDistance = size * FastMath.sqrt(3f);
        for (int iteration = 0; iteration < maxIterations; iteration++) {
            float xc = xcc;
            float yc = ycc - (float) iteration * centerDistance;
            float dx = (FastMath.sqrt(3f) * centerDistance / 2f);
            float dy = centerDistance / 2f;
            
            for (int directions = 0; directions < 6; directions++) {
                for (int steps = 0; steps < iteration; steps++) {
                    if ((iteration == maxIterations - 1)) {
                        Geometry hex = new Geometry("Prism_" + xc + " - " + yc,
                                new HexPrism(new Vector3f(xc, 0f, yc), size, 160f));
                        hex.setMaterial(Materials.HEX.create());
                        hex.addControl(new GroundBorderGlowControl(adm));
                        this.attachChild(hex);
                    } else {
                        prism = new GlowingHexPrism(new Vector3f(xc, -140f, yc), size,
                                150f, 0.8f, adm);
                        prism.addControl(new GroundMoveControl(adm));
                        this.attachChild(prism);
                    }
                    xc = xc + dx;
                    yc = yc + dy;
                }
                float dxn = (FastMath.cos(FastMath.PI / 3f) * dx - FastMath.sin(FastMath.PI / 3f) * dy);
                float dyn = (FastMath.sin(FastMath.PI / 3f) * dx + FastMath.cos(FastMath.PI / 3f) * dy);
                dx = dxn;
                dy = dyn;
            }
        }
    }
    
    private void addLight() {
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(ColorRGBA.White);
        this.addLight(ambient);
    }
}
