package net.mkonrad.synes.data;

import javax.vecmath.Point3f;

import net.mkonrad.synes.gui.SceneCore;
import net.mkonrad.synes.gui.elements.GroundShape;
import net.mkonrad.synes.gui.elements.Keyboard;
import net.mkonrad.synes.gui.elements.instruments.InstrumentShape;
import net.mkonrad.synes.synth.SynthExt;
import net.mkonrad.synes.util.DbgTools;

public class Beat extends SynthObj implements Cloneable
{
  /**
   * Sustain value for that beat. Describes, how long the beat plays parallel
   * to his successor
   */
  private float _sustain;
  
  /** Duration of this beat. Describes, how long this beat lasts */
  private float _dur;
  
  /** previous beat in the beat graph */
  private Beat _prevBeat = null;
  
  /** next beat in the beat graph */
  private Beat _nextBeat = null;
  
  /**
   * Construct a new beat, based on an Instrument, its duration, volume and
   * sustain value
   * 
   * @param instrument
   * @param dur
   * @param amp
   * @param sustain
   */
  public Beat(Instrument instrument, float dur, float amp, float sustain)
  {
    super(instrument, amp);
    _dur = dur;
    _sustain = sustain;
  }
  
  public Beat getPrevBeat()
  {
    return _prevBeat;
  }

  public void setPrevBeat(Beat prevBeat)
  {
    _prevBeat = prevBeat;
  }
  
  public Beat getNextBeat()
  {
    return _nextBeat;
  }

  public void setNextBeat(Beat nextBeat)
  {
    _nextBeat = nextBeat;
  }

  public float getDur()
  {
    return _dur;
  }

  public void setDur(float dur)
  {
    _dur = dur;
  }

  public float getSustain()
  {
    return _sustain;
  }

  public void setSustain(float sustain)
  {
    _sustain = sustain;
  }
  
  public String constructOSCMsgPart()
  {
    return constructOSCMsgPart(_dur);
  }
  
  public String constructOSCMsgPart(float customDur)
  {
    float oldDur = _dur;
    _dur = customDur;
    Object[] extraSeqValues = ((SeqInstrument)getInstrument()).getExtraSeqValues(this);
    float[] values = ((SeqInstrument)getInstrument()).getAllSynthValues(this);
    _dur = oldDur;
    
    String msg = "";
    
    for (int i = 0; i < extraSeqValues.length; i++)
    {
      msg += extraSeqValues[i] + ",";
    }
    
    for (int i = 0; i < values.length; i++)
    {
      msg += values[i];
      
      if (i < values.length - 1)
        msg += ",";
    }
    
    _dur = oldDur;
    
    return msg; 
  }

  /**
   * Generate an OSC message to update the sequencer-data for this beat,
   * because this beat's data had been changed.
   * 
   * @return OSC message for update
   */
  public Object[] generateOSCUpdate()
  {
    Object[] data;
    String msgHeader = "updateBeat;" + _graph.getId() + ";0;";
    
    if (_graph.getState() == BeatGraph.STATE_OPENED)
    {
      data = new Object[2]; //the beat appears again on the "back way"
    }
    else
    {
      data = new Object[1];
    }
    
    data[0] = msgHeader + _graph.indexOf(this) + ";" +
      constructOSCMsgPart();
    
    //DbgTools.print(data[0].toString());
    
    //generate the data for the "back way beat"
    if (_graph.getState() == BeatGraph.STATE_OPENED && _prevBeat != null
        && _nextBeat != null)
    {
      int lastI = _graph.size() - 1;
      data[1] = msgHeader + (2 * lastI - _graph.indexOf(this)) + ";" +
        constructOSCMsgPart(_prevBeat.getDur());
      
      //DbgTools.print(data[1].toString());
    }
     
    return data;
  }
}
