package org.pietschy.command;

import javax.swing.*;
import java.lang.reflect.Method;

/**
 * This implementation provides the basic infrastructure for translating the icon
 * values to method calls.  Subclasses must implement a method for every method type
 * specified by the configuration files.
 * <p/>
 * For example, a configuration of
 * <pre>   &lt;icon type="icon-factory"&gt;createColoredIcon(200,127,127)&lt;icon&gt;</pre>
 * will result in a reflective call to the method
 * <pre>   public Icon createColoredIcon(String s1, String s2, String s3)</pre>
 * on the subclass.
 *
 * @see CommandManager#setIconFactory(IconFactory)
 */
public abstract class
AbstractReflectionIconFactory
implements IconFactory
{
   /**
    * Converts the the iconValue into a method call on this class.
    * <p>
    * For example, a configuration of
    * <pre>   &lt;icon type="icon-factory"&gt;createColoredIcon(200,127,127)&lt;icon&gt;</pre>
    * will result in a reflective call to the method
    * <pre>   public Icon createColoredIcon(String s1, String s2, String s3)</pre>
    * on the subclass.
    *
    * @param iconValue the icon text specified in the configuration file which will be interpreted as a
    * method call on the subclass.
    * @return an Icon created by the method specified in iconValue.
    * @throws Exception if the subclass throws and exception, or if there is an error invoking
    * the method.
    */
   public Icon
   createIcon(String iconValue)
   throws Exception
   {
      Icon icon = null;
      String[] parts = iconValue.replaceAll(" ", "").split("\\(|,|\\)");
      Class factoryClass = getClass();

      Class[] arguments = new Class[parts.length - 1];
      String[] values = new String[parts.length - 1];
      for (int i = 0; i < arguments.length; i++)
      {
         arguments[i] = String.class;
         values[i] = parts[i + 1];
      }
      Method factoryMethod = factoryClass.getMethod(parts[0], arguments);
      icon = (Icon) factoryMethod.invoke(this, values);


      return icon;
   }
}
