package org.opengroupware.jope.appserver.templates;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.opengroupware.jope.foundation.NSClassLookupContext;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class WOxTemplateBuilder extends WOTemplateBuilder {

  static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  
  /* entry points */
  
  public WOTemplate buildTemplate(URL _template, URL _bindings,
                                  NSClassLookupContext _rm)
  {
    if (_bindings != null)
      this.log.warn("got bindings for WOx template?");

    return this.buildTemplate(_template);
  }
  
  public WOTemplate buildTemplate(URL _url) {
    InputStream in;
    
    try {
      in = _url.openStream();
    }
    catch (IOException e) {
      this.log.error("could not open stream to read WOx from URL: " + _url);
      return null;
    }

    Document d;
    if ((d = this.parseDOM(in, _url.toString())) == null)
      return null;
    
    return this.buildTemplate(d, null);
  }
  
  public WOTemplate buildTemplate(String _template) {
    if (_template == null)
      return null;
    
    ByteArrayInputStream in = null;
    try {
      in = new ByteArrayInputStream(_template.getBytes("utf8"));
    }
    catch (UnsupportedEncodingException uee) {
      this.log.error("could not convert template to UTF-8", uee);
      return null;
    }
    if (in == null)
      return null;

    Document d;
    if ((d = this.parseDOM(in, "<string>")) == null)
      return null;
    
    return this.buildTemplate(d, null);
  }
  
  /* primary template building class */
  
  public WOTemplate buildTemplate(Document _doc, URL _url) {
    /*
     * TODO:
     * WOxElemBuilder builder = this.builderForDocument(_doc);
     * root = builder.buildTemplateFromDocument(_doc);
     * template = new WOTemplate(_url, ..., root);
     */
    System.err.println("TODO: build template from DOM: " + _doc);
    // TODO: implement me
    return null;
  }
  
  /* XML processing */
  
  protected DocumentBuilder createDocumentBuilder() {
    try {
       return dbf.newDocumentBuilder();
    }
    catch (ParserConfigurationException e) {
      // TODO: add some log
      return null;
    }
  }
  
  protected Document parseDOM(InputStream _in, String _systemId) {
    DocumentBuilder db;
    
    if ((db = this.createDocumentBuilder()) == null)
      return null;

    try {
      return db.parse(_in, _systemId);
    }
    catch (SAXException e) {
      // TODO: add some log
      return null;
    }
    catch (IOException e) {
      // TODO: add some log
      return null;
    }
  }
}
