package net.mkonrad.synes.data;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Vector3f;

import de.sciss.jcollider.Group;

/**
 * A layer that contains BeatGraphs which contain Beats
 * @author mako
 *
 */
public class Layer
{
  public static final int TYPE_SEQUENCER = 0;
  public static final int TYPE_SYNTH = 1;
  
  /** The id of the layer */
  private int _id;
  
  /** Holds all graphs of this layer */
  private HashMap<Integer, AbstractGraph> _graphs;
  
  /** Basic transform group for all elements in this scene */
  private TransformGroup _layerTG;
  
  /** Holds all scene elements of this layer */
  private BranchGroup _layerBG;
  
  /** The type can be either TYPE_SEQUENCER or TYPE_SYNTH */
  private int _type = TYPE_SEQUENCER;
  
  /** Each layer has an own group on the SC Server */
  private Group _scGroup = null;
  
  public Layer(int id, int type)
  {
    //Init object attributes
    _id = id;
    _type = type;
    _graphs = new HashMap<Integer, AbstractGraph>();
    
    //Create transform group
    _layerTG = new TransformGroup();
    _layerTG.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
    _layerTG.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
    _layerTG.setCapability(TransformGroup.ALLOW_PICKABLE_WRITE);
    
    //Create branch group
    _layerBG = new BranchGroup();
    _layerBG.setCapability(BranchGroup.ALLOW_DETACH);
    _layerBG.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
    _layerBG.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
    _layerBG.setCapability(BranchGroup.ALLOW_PICKABLE_WRITE);
    
    //Connect them
    _layerBG.addChild(_layerTG);
  }
  
  public int getId()
  {
    return _id;
  }
  
  public int getType()
  {
    return _type;
  }
  
  public void setType(int type)
  {
    _type = type;
  }

  public void addGraph(AbstractGraph b)
  {
    _graphs.put(new Integer(b.getId()), b);
  }
  
  public void removeGraph(int id)
  {
    _graphs.remove(id);
  }
  
  public Collection<AbstractGraph> getGraphs()
  {
    return _graphs.values();
  }
  
  public AbstractGraph getGraph(int id)
  {
    return _graphs.get(id);
  }
  
//  public BeatGraph[] getBeatGraphs()
//  {
//    return _beatGraphs.values().toArray(new BeatGraph[0]);
//  }
  
//  /**
//   * Get all beats in this layer
//   * @return
//   */
//  public Beat[] getBeats()
//  {
//    ArrayList<Beat> beats = new ArrayList<Beat>();
//    
//    BeatGraph bgs[] = new BeatGraph[_beatGraphs.size()];
//    _beatGraphs.values().toArray(bgs);
//    
//    for (int i = 0; i < bgs.length; i++)
//    {
//      BeatGraph bg = bgs[i];
//      for (int b = 0; b < bg.size(); b++)
//      {
//        beats.add(bg.getBeat(b));
//      }
//    }
//    
//    return beats.toArray(new Beat[0]);
//  }
  
//  public int getZPos()
//  {
//    return _id;
//  }
  
//  /**
//   * @param layerBG
//   */
//  public void setLayerBG(BranchGroup layerBG)
//  {
//    _layerBG = layerBG;
//  }
  
  public TransformGroup getLayerTG()
  {
    return _layerTG;
  }

  public BranchGroup getLayerBG()
  {
    return _layerBG;
  }

  public void setSCGroup(Group g)
  {
    _scGroup = g;
  }
  
  public Group getSCGroup()
  {
    return _scGroup;
  }

  public void setHeight(float h)
  {
    Transform3D t3d = new Transform3D();
    t3d.setTranslation(new Vector3f(0f, 0f, h));
    _layerTG.setTransform(t3d);
  }
}
