/*
  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.elements;

import java.util.HashMap;
import java.util.Map;

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

/*
 * WOSwitchComponent
 * 
 * Bindings:
 *   WOComponentName - String [in]
 *   other bindings  - will be bindings for the instantiated component
 */
public class WOSwitchComponent extends WOHTMLDynamicElement {
  
  protected WOAssociation              componentName;
  protected WOElement                  template;
  protected Map<String, WOAssociation> bindings;
  
  public WOSwitchComponent(String _name, Map<String, WOAssociation> _assocs,
                           WOElement _template)
  {
    super(_name, _assocs, _template);

    this.componentName = grabAssociation(_assocs, "WOComponentName");
    this.template      = _template;
    
    if (_assocs != null) {
      _assocs.remove("NAME");
      this.bindings = new HashMap<String, WOAssociation>(_assocs);
      _assocs.clear();
    }
  }

  /* component lookup */
  
  protected WOComponent lookupComponent(String _name, WOContext _ctx) {
    if (_name == null)
      return null;
    
    WOComponent component = _ctx.component().pageWithName(_name);
    if (component == null)
      return null;
    
    component.setParent(_ctx.component());
    component.setBindings(this.bindings);
    return component;
  }
  
  /* responder */
  
  @Override
  public void takeValuesFromRequest(WORequest _rq, WOContext _ctx) {
    String      cname = this.componentName.stringValueInComponent(_ctx);
    WOComponent c     = this.lookupComponent(cname, _ctx);
    if (c == null) return;
    
    cname = cname.replace('.', '_'); /* escape for EID */
    _ctx.appendElementIDComponent(cname);
    _ctx.enterComponent(c, this.template);
    c.takeValuesFromRequest(_rq, _ctx);
    _ctx.leaveComponent(c);
    _ctx.deleteLastElementIDComponent();
  }
  
  @Override
  public Object invokeAction(WORequest _rq, WOContext _ctx) {
    // TODO: implement me to support component actions
    return null;
  }
  
  @Override
  public void appendToResponse(WOResponse _r, WOContext _ctx) {
    String cname = this.componentName.stringValueInComponent(_ctx.component());
    
    WOComponent c = this.lookupComponent(cname, _ctx);
    if (c == null) return;
    
    
    cname = cname.replace('.', '_'); /* escape for EID */
    _ctx.appendElementIDComponent(cname);
    _ctx.enterComponent(c, this.template);
    
    c.appendToResponse(_r, _ctx);
    
    _ctx.leaveComponent(c);
    _ctx.deleteLastElementIDComponent();
  }
  
  @Override
  public void walkTemplate(WOElementWalker _walker, WOContext _ctx) {
    String cname = this.componentName.stringValueInComponent(_ctx.component());
    
    WOComponent c = this.lookupComponent(cname, _ctx);
    if (c == null) return;
    
    
    cname = cname.replace('.', '_'); /* escape for EID */
    _ctx.appendElementIDComponent(cname);
    _ctx.enterComponent(c, this.template);
    
    c.walkTemplate(_walker, _ctx);
    
    _ctx.leaveComponent(c);
    _ctx.deleteLastElementIDComponent();
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    
    this.appendAssocToDescription(_d, "name", this.componentName);
  }  
}
