package net.mkonrad.synes.ctrl;

import java.io.IOException;

import javax.media.j3d.Node;
import javax.vecmath.Point3f;

import net.mkonrad.synes.data.AbstractGraph;
import net.mkonrad.synes.data.Modulator;
import net.mkonrad.synes.data.SynthGraph;
import net.mkonrad.synes.data.SynthObj;
import net.mkonrad.synes.gui.elements.AbstractGraphLine;
import net.mkonrad.synes.gui.elements.instruments.InstrumentShape;
import net.mkonrad.synes.util.DbgTools;
import net.mkonrad.synes.util.ErrTools;

public class SynthObjPickingCtrl extends AbstractPickableObj
{
  private Modulator _selectedModulator = null;
  
  public SynthObjPickingCtrl(CentralPickingCtrl pickCtrl)
  {
    super(pickCtrl);
  }

  public boolean clicked(Node pickedObj, Point3f intercept, int mouseState)
  {
    if (_pickCtrl.getState() == CentralPickingCtrl.STATE_GRAPH_CREATE
        && _pickCtrl.getCurrGraph().size() > 1)
    {
      _pickCtrl.getLayerPickingCtrl().cleanUp();
      _pickCtrl.getCurrGraphLine().cleanUpTail();
      _pickCtrl.getLayerPickingCtrl().finishGraph(intercept);
    }
    else if (_pickCtrl.getState() == CentralPickingCtrl.STATE_READY)
    {
      _selectedModulator = null;
      _selectedSynthObj = null;
      _selectedGraphLine = null;
      
      try
      {
        _selectedSynthObj = _selectedModulator = (Modulator)pickedObj.getUserData();
        _selectedGraphLine = _selectedModulator.getGraph().getGraphLine();
      }
      catch (ClassCastException e)  //if it's not a Modulator, then it has to be a SynthObj
      {
        _selectedSynthObj = (SynthObj)pickedObj.getUserData();
        _selectedGraphLine = _selectedSynthObj.getGraph().getGraphLine();
      }
      
      //check if its an impro synth graph and we clicked while pressing CTRL
      SynthGraph synthGraph = (SynthGraph) _selectedGraphLine.getGraph();
      if (synthGraph.getState() == SynthGraph.STATE_IMPRO
          && _pickCtrl.getMouseEvent().isControlDown())
      {
        if (_selectedModulator != null)
        {
          playSynthGraph(synthGraph);
        }
        else
        {
          playSynth(_selectedSynthObj);
        }
      }
      
      startEditMode();
    }
    
    return true;
  }

  public boolean dragged(Point3f intercept, int mouseState)
  {
    SynthObj synthObj = null;
    
    if (_selectedModulator != null)
    {
      synthObj = _selectedModulator;
    }
    else if (_selectedSynthObj != null)
    {
      synthObj = _selectedSynthObj;
    }
    
    if (synthObj != null)
    {
      synthObj.getInstrumentShape().setPos(intercept);
      
      SynthObj[] synthsToModify = null;
      Modulator mod = null;
      if (_selectedModulator != null) //we have the Modulator in the hand
      {
        mod = _selectedModulator;
        AbstractGraph graph = _selectedGraphLine.getGraph();
        synthsToModify = new SynthObj[graph.size() - 1];  //without Modulator!
        int synthI = 0;
        for (int i = 0; i < graph.size(); i++)
        {
          if (graph.get(i) != mod)
          {
            synthsToModify[synthI] = (SynthObj)graph.get(i);
            synthI++;
          }
        }
      }
      else  //we have single SynthObj in the hand
      {
        synthsToModify = new SynthObj[1];
        synthsToModify[0] = synthObj;
        mod = ((SynthGraph)_selectedGraphLine.getGraph()).getModulator();
      }
      
      if (_coreCtrl.isOSCMode())
      {
        try
        {
          for (int i = 0; i < synthsToModify.length; i++)
          {
            if (synthsToModify[i].getSynth() != null)
              synthsToModify[i].getSynth().modSynthSynth(mod);
          }
        }
        catch (IOException e)
        {
          ErrTools.print(e);
        }
      }
      
      _selectedGraphLine.movedObj(synthObj);
    }
    
    return true;
  }

  public boolean moved(Node pickedObj, Point3f where, int mouseState)
  {
    return false;
  }

  public boolean released(Point3f intercept, int mouseState)
  {
    _selectedGraphLine.releaseMove(intercept);
    
    //check if its an impro synth graph and we clicked while pressing CTRL
    SynthGraph synthGraph = (SynthGraph) _selectedGraphLine.getGraph();
    if (synthGraph.getState() == SynthGraph.STATE_IMPRO)
    {
      releaseSynthGraph(synthGraph);
    }
    
    _selectedModulator = null;
    _selectedSynthObj = null;
    _selectedGraphLine = null;
    
    stopEditMode();
    
    return true;
  }

}
