package sed.app;

import org.apache.log4j.Logger;

import sed.TempVars;
import sed.sky.CloudPlane;
import sed.sky.CloudProcessor;
import sed.weather.Weather;

import com.jme3.app.Application;
import com.jme3.app.state.AppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;

/**
 * <b>Higher layer</b> {@link AppState} responsible for cloud rendering.
 * 
 * @author cn
 */
public class CloudAppState extends BasicAppState {
    
    private static final Logger logger = Logger.getLogger(CloudAppState.class);
    private static final float UpdateInterval = 10f; // in seconds
    
    // exists only while AppState is attached
    private CloudProcessor cloudProcessor;
    private Geometry geom;

    private Vector3f cloudShift;
    
    public CloudAppState() {
        super(UpdateInterval);
    }
    
    @Override
    public void initialize(AppStateManager stateManager, Application baseApp) {
        super.initialize(stateManager, baseApp);
        
        cloudProcessor = new CloudProcessor(getApp().getAssetManager(), CloudProcessor.Mode.RenderGPU, UpdateInterval);
        getApp().getViewPort().addProcessor(cloudProcessor);
        
        //Quad cloudQuad = new Quad(10, 10);
        CloudPlane cloudQuad = new CloudPlane(750f, 50f, new Vector3f(0, 500, 0));
        geom = new Geometry("CloudPlane", cloudQuad);
        
        //Material mat = new Material(getApp().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        //mat.setColor("Color", ColorRGBA.Orange);
        //mat.getAdditionalRenderState().setWireframe(true);
        //mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
        
        Material mat = new Material(getApp().getAssetManager(), "shaders/CloudFinal.j3md");
        mat.setTexture("ColorMap", cloudProcessor.getCloudTex());
        //mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
        mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
        
        geom.setMaterial(mat);
        geom.setQueueBucket(Bucket.Transparent);
        
        // update before attaching since all SceneProcessors are initialized
        // then (and the CP requires some variables set)
        intervalUpdate();
        
        getSkyAppState().getSkyNode().attachChild(geom);
    }
    
    @Override
    public void cleanup() {
        super.cleanup();
        
        if(getSkyAppState().getSkyNode() != null) {
            getSkyAppState().getSkyNode().detachChild(geom);
        }
        getApp().getViewPort().removeProcessor(cloudProcessor);
        
        cloudProcessor = null;
        geom = null;
    }
    
    @Override
    protected void intervalUpdate() {
        cloudProcessor.setCloudCover(getWeather().getFloat("cloud.cover"));
        cloudProcessor.setCloudSharpness(getWeather().getFloat("cloud.sharpness"));
        cloudProcessor.setWayFactor(getWeather().getFloat("cloud.way-factor"));
        cloudProcessor.setZoom(getWeather().getInt("cloud.zoom"));
        
        TempVars vars = TempVars.get();
        
        Vector3f sunPosition = getSkyAppState().getSun().getSunPosition(vars.vect1);
        
        ColorRGBA sunLightColor = getSkyAppState().getSkyGradient().getSunLightColor(vars.color1);
        //ColorRGBA sunLightColor = ColorRGBA.White;
        System.out.println(sunLightColor);
        cloudProcessor.setSunLightColor(sunLightColor);

        cloudProcessor.setSunPosition(new Vector3f(-500, 256/2, 3000));
        
        if(cloudShift == null) {
            cloudShift = new Vector3f(Vector3f.ZERO);
        }
        cloudProcessor.setShift(cloudShift);
//        cloudShift.x += 0.025;
        
        // TODO: some movement (wind)/change (permutation) should be done (aka cloud physics)
        
        vars.release();
    }
    
    private Weather getWeather() {
        return getState(WeatherAppState.class).getWeather();
    }
    
    private SkyAppState getSkyAppState() {
        return getState(SkyAppState.class);
    }
}

@@ -3264,28 +3264,31 @@
     
-Vector3f sunPosition
+ColorRGBA sunLightColor
  = g
@@ -3311,49 +3311,62 @@
 getS
-un().getSunPosition
+kyGradient().getSunLightColor
 (vars.
-vect
+color
 1);%0A
+//
         
 %0A   
@@ -3365,104 +3365,229 @@
     
-%0A        ColorRGBA sunLightColor = getSkyAppState().getSkyGradient().getSunLightColor
+ColorRGBA sunLightColor = ColorRGBA.White;%0A//        System.out.println(sunLightColor);%0A        cloudProcessor.setSunLightColor(sunLightColor);%0A%0A        Vector3f vToSun = getSkyAppState().getSun().getSunPosition
 (vars.
-color
+vect
 1);%0A
@@ -3598,53 +3598,196 @@
     
-//ColorRGBA sunLightColor = ColorRGBA.White;%0A
+vToSun.set(vToSun.x, -vToSun.z, vToSun.y); // from J3D to Sky%0A        float x = vToSun.x; // from 1f to -1f%0A        Vector3f sunPosition = vars.vect2.set(+2.0f*x * 256, 0.5f*256, 5000);%0A//
     
@@ -3805,37 +3805,36 @@
 out.println(
-sunLightColor
+vToSun+%22 %22+x
 );%0A        c
@@ -3857,44 +3857,39 @@
 tSun
-LightColor(sunLightColor
+Position(sunPosition
 );%0A
-%0A
         
 clou
@@ -3876,32 +3876,34 @@
 ition);%0A        
+//
 cloudProcessor.s

Implement rudimentary sun position calculcation in clouds