package net.mkonrad.synes.ctrl;

import java.io.IOException;

import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import net.mkonrad.synes.data.IdCounter;
import net.mkonrad.synes.data.Layer;
import net.mkonrad.synes.gui.SceneCore;
import net.mkonrad.synes.gui.SceneCoreOSC;
import net.mkonrad.synes.util.DbgTools;
import net.mkonrad.synes.util.ErrTools;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.universe.ViewingPlatform;

import de.sciss.jcollider.Group;

public class GuiCtrl
{
  private SceneCore _sceneCore;
  //private Grid _grid;
  //private Canvas3D _canvas;
  private ViewingPlatform _view;
  private OrbitBehavior _orbit;
  
  private static final float USER_Z_DISTANCE = 12.50f;
  
  public GuiCtrl(SceneCore sceneCore)
  {
    _sceneCore = sceneCore;
    //_grid = _sceneCore.getGrid();
    _view = _sceneCore.getViewingPlatform();
    initOrbitControls();
    _orbit.setEnable(false);
    updateUserPosition();
  }
  
  public OrbitBehavior getOrbitControl()
  {
    return _orbit;
  }
  
  private void initOrbitControls()
  {
    _orbit = new OrbitBehavior(_sceneCore.getCanvas3D(),
        OrbitBehavior.REVERSE_ALL);
    _orbit.setSchedulingBounds(SceneCore.getSceneBounds());

    _view.setViewPlatformBehavior(_orbit);      
  }

/*  private void setNewUserPosition(Point3d pos)
  {
    setNewUserPosition(pos, new Point3d(0,0,0));
  }
*/  

  private void setNewUserPosition(Point3d pos, Point3d lookAt)
  {
    TransformGroup steerTG = _view.getViewPlatformTransform();
    Transform3D t3d = new Transform3D();
    steerTG.getTransform(t3d);

    t3d.lookAt(pos, lookAt, new Vector3d(0,1,0));
    t3d.invert();

    steerTG.setTransform(t3d);
  }
  
  
  public void comeUp()
  {    
    int newLayerLevel;
    
    //we have to create a new layer?
    if (_sceneCore.getLayerSet().getLayerNum() < _sceneCore.getCurrLayer().getId() + 2)
    {
      newLayerLevel = _sceneCore.createNewLayer(Layer.TYPE_SYNTH, true, true).getId();
    }
    else
    {
      newLayerLevel = _sceneCore.getCurrLayer().getId() + 1;
    }
    
    changeToLayerLevel(newLayerLevel);
  }
  
  
  private void changeToLayerLevel(int newLayerLevel)
  {
    if (_sceneCore.isOrbitMode())
      _sceneCore.changeOrbitMode();
    
    _sceneCore.changeLayer(newLayerLevel, null);
    _sceneCore.getHUD().updateLayerInfo();
    _sceneCore.getHUD().updateAvailableInstr();
    updateUserPosition();
  }

  public void dive()
  {
    int level = _sceneCore.getCurrLayer().getId();
    if (level > 0)
    {
      changeToLayerLevel(level - 1);
    }
  }
    
  private void updateUserPosition()
  {
    setNewUserPosition(
      new Point3d(0, 0, USER_Z_DISTANCE + _sceneCore.getCurrLevelHeight()),
      new Point3d(0, 0, _sceneCore.getCurrLevelHeight())
    ); 
  }
}
