/*
  Copyright (C) 2006 Helge Hess

  This file is part of JOPE.

  JOPE is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version.

  JOPE is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with JOPE; see the file COPYING.  If not, write to the
  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
*/

package org.opengroupware.jope.appserver.templates;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.opengroupware.jope.appserver.core.WOAssociation;
import org.opengroupware.jope.appserver.core.WOContext;
import org.opengroupware.jope.appserver.core.WOElement;
import org.opengroupware.jope.appserver.core.WORequest;
import org.opengroupware.jope.appserver.core.WOResponse;

/*
 * WOTemplate
 * 
 * This is just a simple element wrapper used for the root element of a 
 * template. It can transport additional information like the URL the
 * template is living at.
 */
public class WOTemplate extends WOElement {
  
  protected URL       url         = null;
  protected WOElement rootElement = null;
  protected Map<String, WOSubcomponentInfo> subcomponentInfos = null;
  
  public WOTemplate(URL _url, WOElement _root) {
    this.url         = _url;
    this.rootElement = _root;
  }
  
  /* accessors */
  
  public void setRootElement(WOElement _element) {
    this.rootElement = _element;    
  }
  public WOElement rootElement() {
    return this.rootElement;
  }

  public String addSubcomponent(String _name,
                                Map<String, WOAssociation> _assocs)
  {
    WOSubcomponentInfo info = new WOSubcomponentInfo(_name, _assocs);
    
    if (this.subcomponentInfos == null)
      this.subcomponentInfos = new HashMap<String, WOSubcomponentInfo>(16);

    /* generate unique component name */
    
    String cname = _name;
    if (this.subcomponentInfos.containsKey(cname)) {
      cname = null;
      for (int i = 0; i < 200; i++) {
        cname = _name + "[" + i + "]";
        if (!this.subcomponentInfos.containsKey(cname))
          break;
        cname = null;
      }
      if (cname == null) {
        // TODO: improve logging
        System.err.println("ERROR: failed to generate unique component name!");
        return _name; /* reuse first entry ..., not exactly a solution */
      }
    }
    
    /* register info */
    this.subcomponentInfos.put(cname, info);
    return cname /* return the name we registered the component under */;
  }
  
  public Map<String, WOSubcomponentInfo> subcomponentInfos() {
    return this.subcomponentInfos;
  }
  
  /* responder */
  
  public void takeValuesFromRequest(WORequest _rq, WOContext _ctx) {
    this.rootElement.takeValuesFromRequest(_rq, _ctx);
  }
  
  public Object invokeAction(WORequest _rq, WOContext _ctx) {
    return this.rootElement.invokeAction(_rq, _ctx);
  }
  
  public void appendToResponse(WOResponse _r, WOContext _ctx) {
    this.rootElement.appendToResponse(_r, _ctx);
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    
    if (this.url != null)
      _d.append(" url=" + this.url);
    
    if (this.rootElement == null)
      _d.append(" no-root");
  }
}
