package edu.sc.seis.gee.configurator;

import org.apache.log4j.Category;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import edu.sc.seis.gee.task.SAXTask;
import edu.sc.seis.gee.task.Task;

/**
 * TaskConfigHandler.java
 *
 *
 * Created: Thu Jan  3 12:41:10 2002
 *
 * @author <a href="mailto:">Philip Crotwell</a>
 * @version
 */

public class TaskConfigHandler extends AbstractHandler {

    public TaskConfigHandler (org.xml.sax.XMLReader parser,
                              TaskHandler parent,
                              String classname,
                              Task task){
        this(parser, parent, classname);
        this.task = task;
    }

    public TaskConfigHandler (org.xml.sax.XMLReader parser,
                              TaskHandler parent,
                              String classname){
        super(parser, parent);
        this.classname = classname;
        try {
            taskClass = Class.forName(classname);
        } catch (ClassNotFoundException e) {
            // doesn't really matter, since if we cannot find the class, it
            // cannot be used, so just proceed. The configuration will
            // be messed up, but not really a worry as it will never be read
            logger.debug("Couldn't load class "+classname, e);
        } // end of try-catch

    }

    public void startElement(String namespaceURI,
                             String localName,
                             String qName,
                             Attributes atts) {
        if (localName.equals("name")) {
            parser.setContentHandler(new TaskConfigHandler.NameHandler(parser,
                                                                       this));
        } else if (localName.equals("complexValue")) {
            if (taskClass != null &&  SAXTask.class.isAssignableFrom(taskClass)) {
                AbstractHandler handler;
                try {
                    if ( task == null) {
                        task = (Task)taskClass.newInstance();
                        if ( parent instanceof TaskHandler) {
                            ((TaskHandler)parent).setTaskInstance(task);
                        } // end of if ()

                    } // end of if ()
                    handler =
                        ((SAXTask)task).getConfigureHandler(propName,
                                                            parser,
                                                            this);
                } catch (InstantiationException e) {
                    handler =
                        new TaskConfigHandler.ValueHandler(parser,
                                                           this);
                } catch (IllegalAccessException e) {
                    handler =
                        new TaskConfigHandler.ValueHandler(parser,
                                                           this);
                } // end of try-catch
                parser.setContentHandler(handler);

            } else {
                parser.setContentHandler(new TaskConfigHandler.ValueHandler(parser,
                                                                            this));
            }
        } else if (localName.equals("value")) {
            parser.setContentHandler(new TaskConfigHandler.ValueHandler(parser,
                                                                        this));

        } else {
            logger.warn("TaskConfigHandler unknown tag: "+localName);
        } // end of else



    }

    protected void finished() {
        ((TaskHandler)parent).addConfigParam(propName, propValue);
    }

    String propName = "";
    Object propValue = null;

    class NameHandler extends AbstractHandler {
        NameHandler(org.xml.sax.XMLReader parser,
                    AbstractHandler parent){
            super(parser, parent);
        }

        public void characters(char[] ch,
                               int start,
                               int length)
            throws SAXException {
            propName +=  new String(ch, start, length);
        }
    }

    class ValueHandler extends AbstractHandler {
        ValueHandler(org.xml.sax.XMLReader parser,
                     AbstractHandler parent){
            super(parser, parent);
        }

        public void characters(char[] ch,
                               int start,
                               int length)
            throws SAXException {
            if (propValue == null) {
                propValue =  new String(ch, start, length);
            } else if (propValue instanceof String) {
                propValue =  propValue + new String(ch, start, length);
            } else {
                throw new SAXException("Value is not of type String.");
            } // end of else
        }
    }

    String classname;

    Class taskClass;

    Task task = null;

    static Category logger = Category.getInstance(TaskConfigHandler.class.getName());

}// TaskConfigHandler
