// ConvertObject.java
// $Id: ConvertObject.java,v 1.2 1997/07/30 14:05:46 ylafon Exp $  
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package w3c.tools.resources.converter;

import java.io.*;
import java.util.*;
import java.lang.reflect.*;

class ElementReader {
  byte buffer[] = null;
  int  bufptr = 0 ;
  StringBufferInputStream in = null;
  String parsed[] = null;
  int parsedptr = 0;
  int idx = 0;
  int ch = 0;

  public String nextElement() {
    if (! hasMoreElements()) return null;
    return parsed[idx++];
  }

  public boolean hasMoreElements() {
    if (idx > parsed.length) return false;
    if (parsed[idx] == null) return false;
    return true;
  }

  void append (int ch) {
    if ( bufptr + 1 >= buffer.length) {
      // resize buffer 
      byte nbuf[] = new byte[buffer.length * 2] ;
      System.arraycopy (buffer, 0, nbuf, 0, bufptr) ;
      buffer = nbuf ;
    }
    buffer[bufptr++] = (byte) ch ;
  }

  void addElement(String elem) {
    if (parsedptr + 1 >= parsed.length) {
      // resize array
      String nparsed[] = new String[parsed.length*2];
      System.arraycopy (parsed, 0, nparsed, 0, parsed.length);
      parsed = nparsed;
    }
    parsed[parsedptr++] = elem;
  }

  String parseElement() {
    int level = 1;
    while (level != 0) {
      switch(ch) {
      case '(': 
	level++;
	append(ch);
	break;
      case ')': 
	level--;
	if (level != 0) append(ch);
	break;
      default :
	append(ch);
      }
      ch = in.read();
    }
    return new String (buffer, 0, 0, bufptr);
  }

  public void parse() {
    ch = in.read();
    while ( true ) {
      if (ch != '(') return;
      else ch = in.read();
      addElement(parseElement());
      bufptr = 0;
    }
  }

  public ElementReader (String s) {
    this.in = new StringBufferInputStream (s);
    this.buffer = new byte[32] ;
    this.parsed = new String[10];
  }
}

public class ConvertObject implements Convert {

  protected Class initialClass = null;

  public void setInitialClass(Class c) {
    initialClass = c;
  }

  public Object defaultValue() {
    return new Object();
  }

  public String toString(Object O) 
    throws NoSuchConverterException
  {
    if (! initialClass.isArray()) 
      throw new NoSuchConverterException("Array of "+initialClass.getName());
    Object array[] = (Object[])O;
    StringBuffer buffer = new StringBuffer();
    int idx = 0;
    while (idx < array.length)
      buffer.append("("+ConvertRegistry.toString(array[idx++])+")");

    return new String(buffer);
  }

  public Object toObject(String S) 
    throws NoSuchConverterException
  {
    if (initialClass == null)
      throw new NoSuchConverterException("Array of Object");
    if (! initialClass.isArray()) 
      throw new NoSuchConverterException(initialClass.getName());
    Vector V = new Vector();
    ElementReader reader = new ElementReader(S);
    reader.parse();
    Class elemClass = initialClass.getComponentType();
    while (reader.hasMoreElements()) 
      V.addElement(ConvertRegistry.toObject(elemClass,
					    reader.nextElement()));
    Object array = Array.newInstance(elemClass,V.size());
    V.copyInto((Object[])array);
    return array;
  }

  public Class classConverted() {
    try {
      return Class.forName("java.lang.Object");
    } catch (ClassNotFoundException ex) {
      System.out.println(ex.getMessage());
      ex.printStackTrace();
      return null;
    }
  }

}
