package net.mkonrad.synes.data;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;

import javax.lang.model.type.ErrorType;
import javax.vecmath.Color3f;

import sun.misc.Launcher;
import net.mkonrad.synes.data.instruments.Piano;
import net.mkonrad.synes.gui.style.Colors;
import net.mkonrad.synes.util.DbgTools;
import net.mkonrad.synes.util.ErrTools;

public class InstrumentCabinet
{
  private ArrayList<Instrument> _seqInstrList;
  private ArrayList<Instrument> _synthInstrList;

  public InstrumentCabinet()
  {
    _seqInstrList = new ArrayList<Instrument>();
    _synthInstrList = new ArrayList<Instrument>();

    loadInstruments("net.mkonrad.synes.data.instruments");
  }

  private void loadInstruments(String pckgname)
  {
    Color3f[] colors =
    { Colors.red, Colors.brightBlue, Colors.green };

    // Code from JWhich
    // ======
    // Translate the package name into an absolute path
    
    String name = new String(pckgname);
    
    if (!name.startsWith("/"))
    {
      name = "/" + name;
    }
    
    name = name.replace('.', '/');
    
    // Get a File object for the package
    URL url = Launcher.class.getResource(name);
    
    File directory;
    if (url.getProtocol().equals("jar"))  //program is started from JAR
      directory = new File("./plugins" + name);
    else
      directory = new File(url.getFile());

    if (directory.exists())
    {
      DbgTools.print("Loading Instruments from " + directory);
      
      // Get the list of the files contained in the package
      int colIndex = 0;
      String[] files = directory.list();
      Instrument currInstr;

      for (int i = 0; i < files.length; i++)
      {

        // we are only interested in .class files
        if (files[i].endsWith(".class"))
        {
          // removes the .class extension
          String classname = files[i].substring(0, files[i].length() - 6);
          try
          {
            // Try to create an instance of the object
            Object o = Class.forName(pckgname + "." + classname).newInstance();
            if (o instanceof Instrument)
            {
              currInstr = ((Instrument) o);
              //currInstr.setColor(colors[colIndex % colors.length]);

              if (currInstr instanceof SeqInstrument)
              {
                currInstr.setKey(_seqInstrList.size() + 1);
                _seqInstrList.add(currInstr);

                DbgTools.print("Added SeqInstrument " + currInstr.getName());
              }

              if (currInstr instanceof SynthInstrument)
              {
                currInstr.setKey(_synthInstrList.size() + 1);
                _synthInstrList.add(currInstr);

                DbgTools.print("Added SynthInstrument " + currInstr.getName());
              }

              colIndex++;
            }
          } catch (ClassNotFoundException cnfex)
          {
            ErrTools.print(cnfex);
          } catch (InstantiationException iex)
          {
            // We try to instantiate an interface
            // or an object that does not have a
            // default constructor
          } catch (IllegalAccessException iaex)
          {
            // The class is not public
          }
        }
      }
    }
    else
    {
      ErrTools.die("Failed loading Instruments from " + directory);
    }
  }

  public ArrayList<Instrument> get(int type)
  {
    if (type == Layer.TYPE_SEQUENCER)
      return _seqInstrList;
    else
      return _synthInstrList;
  }

  public Instrument get(int type, int index)
  {
    if (type == Layer.TYPE_SEQUENCER)
      return _seqInstrList.get(index);
    else
      return _synthInstrList.get(index);
  }
}
