package click.runtime;

import java.io.IOException;
import java.util.Vector;

import click.util.StringUtils;

/**
 * Adapts {@link ClickAdapter} to {@link ClickInterface}
 * @author kurth
 *
 */
public class ClickInterfaceSimImpl implements ClickInterface {

  protected ClickAdapter _adapter;

  public ClickInterfaceSimImpl(ClickAdapter _adapter) {
    super();
    this._adapter = _adapter;
  }

  public ClickAdapter getAdaptee() {
    return _adapter;
  }


  /* (non-Javadoc)
   * @see click.gui.ControlInterface#socketName()
   */
  public String name() {
    return _adapter.toString();
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#toString()
   */
  public String toString() {
    return name();
  }


  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getRouterConfig()
   */
  public String getRouterConfig()
          throws ClickException, IOException {
    return readString(null, "config");
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getRouterFlatConfig()
   */
  public String getRouterFlatConfig()
          throws ClickException, IOException {
    return readString(null, "flatconfig");
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getRouterVersion()
   */
  public String getRouterVersion()
          throws ClickException, IOException {
    return readString(null, "version").trim();
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getConfigElementNames()
   */
  public Vector getConfigElementNames()
          throws ClickException, IOException {
    char[] buf = read(null, "list");

    // how many elements?
    int i;
    for (i = 0; i < buf.length && buf[i] != '\n'; i++)
      ; // do it

    int numElements = 0;
    try {
      numElements = Integer.parseInt(new String(buf, 0, i));
    } catch (NumberFormatException ex) {
      throw new ClickException.HandlerFormatException("element list");
    }

    Vector v = StringUtils.split(buf, i + 1, '\n');
    if (v.size() != numElements)
      throw new ClickException.HandlerFormatException("element list");
    return v;
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getRouterClasses()
   */
  public Vector getRouterClasses()
          throws ClickException, IOException {
    char[] buf = read(null, "classes");
    return StringUtils.split(buf, 0, '\n');
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getRouterPackages()
   */
  public Vector getRouterPackages()
          throws ClickException, IOException {
    char[] buf = read(null, "packages");
    return StringUtils.split(buf, 0, '\n');
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getConfigRequirements()
   */
  public Vector getConfigRequirements()
          throws ClickException, IOException {
    char[] buf = read(null, "requirements");
    return StringUtils.split(buf, 0, '\n');
  }


  /* (non-Javadoc)
   * @see click.gui.ControlInterface#getElementHandlers(java.lang.String)
   */
  public Vector getElementHandlers(String elementName)
          throws ClickException, IOException {
    Vector v = new Vector();
    Vector vh;

    try {
      char[] buf = read(elementName, "handlers");
      vh = StringUtils.split(buf, 0, '\n');
    } catch (ClickException.NoSuchHandlerException e) {
      return v;
    }

    for (int i = 0; i < vh.size(); i++) {
      String s = (String) vh.elementAt(i);
      int j;
      for (j = 0; j < s.length() && !Character.isWhitespace(s.charAt(j)); j++)
        ; // find record split
      if (j == s.length())
        throw new ClickException.HandlerFormatException(elementName + ".handlers");
      HandlerInfo hi = new HandlerInfo(this, elementName, s.substring(0, j).trim());
      while (j < s.length() && Character.isWhitespace(s.charAt(j)))
        j++;
      for (; j < s.length(); j++) {
        char c = s.charAt(j);
        if (Character.toLowerCase(c) == 'r')
          hi.canRead = true;
        else if (Character.toLowerCase(c) == 'w')
          hi.canWrite = true;
        else if (Character.isWhitespace(c))
          break;
      }
      v.addElement(hi);
    }
    return v;
  }


  /* (non-Javadoc)
   * @see click.gui.ControlInterface#read(java.lang.String, java.lang.String)
   */
  public char[] read(String elementName, String handlerName)
          throws ClickException, IOException {
    return _adapter.click_read_handler(elementName, handlerName).toCharArray();
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#readString(java.lang.String, java.lang.String)
   */
  public String readString(String el, String handler)
          throws ClickException, IOException {
    return _adapter.click_read_handler(el, handler);
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#readString(click.gui.ControlSocket.HandlerInfo)
   */
  public String readString(HandlerInfo hinfo) throws ClickException {
    return _adapter.click_read_handler(hinfo.elementName, hinfo.handlerName);
  }


  /* (non-Javadoc)
   * @see click.gui.ControlInterface#write(java.lang.String, java.lang.String, java.lang.String)
   */
  public int write(String elementName, String handlerName, String data)
          throws ClickException, IOException {
    return _adapter.click_write_handler(elementName, handlerName, data);
  }

  /* (non-Javadoc)
   * @see click.gui.ControlInterface#write(click.gui.ControlSocket.HandlerInfo, java.lang.String)
   */
  public int write(HandlerInfo info, String data)
          throws ClickException, IOException {
    return write(info.elementName, info.handlerName, data);
  }

  /*
   * (non-Javadoc)
   * @see click.runtime.ControlInterface#send(int, int, byte[], boolean)
   */
  public void send(int ifid, int type, byte[] data, boolean txfeedback)
      throws ClickException, IOException {
    _adapter.click_send(ifid, type, data, 0, 0, 0, txfeedback);
  }

  /*
   * (non-Javadoc)
   * @see click.runtime.ControlInterface#close()
   */
  public void close() {
    // TODO
  }

}
