package org.opengroupware.jope.weextensions;

import java.util.Map;

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

public class WEContextKey extends WODynamicElement {
  
  protected WOAssociation key      = null;
  protected WOAssociation value    = null;
  protected WOElement     template = null;

  public WEContextKey(String _name, Map<String, WOAssociation> _assocs,
                      WOElement _template)
  {
    super(_name, _assocs, _template);
    
    this.key      = grabAssociation(_assocs, "key");
    this.value    = grabAssociation(_assocs, "value");
    this.template = _template;
    
    if (this.value == null)
      this.value = WOAssociation.associationWithValue(Boolean.TRUE);
  }

  /* responder */

  public void takeValuesFromRequest(WORequest _rq, WOContext _ctx) {
    if (this.template == null)
      return;
    
    String k = this.key.stringValueInComponent(_ctx.cursor());
    Object v = this.value.valueInComponent(_ctx.cursor());
    Object t = null;
    
    if (k != null && v != null) {
      t = _ctx.objectForKey(k); /* save old context value */
      _ctx.setObjectForKey(v, k);
    }
    
    this.template.takeValuesFromRequest(_rq, _ctx);

    if (k != null && v != null) _ctx.removeObjectForKey(k);
    if (k != null && t != null) _ctx.setObjectForKey(t, k); /* restore old */
  }
  
  public WOActionResults invokeAction(WORequest _rq, WOContext _ctx) {
    if (this.template == null)
      return null;
    
    String k = this.key.stringValueInComponent(_ctx.cursor());
    Object v = this.value.valueInComponent(_ctx.cursor());
    Object t = null;
    
    if (k != null && v != null) {
      t = _ctx.objectForKey(k); /* save old context value */
      _ctx.setObjectForKey(v, k);
    }
    
    WOActionResults result = this.template.invokeAction(_rq, _ctx);

    if (k != null && v != null) _ctx.removeObjectForKey(k);
    if (k != null && t != null) _ctx.setObjectForKey(t, k); /* restore old */
    
    return result;
  }
  
  public void appendToResponse(WOResponse _r, WOContext _ctx) {
    if (this.template == null)
      return;
    
    String k = this.key.stringValueInComponent(_ctx.cursor());
    Object v = this.value.valueInComponent(_ctx.cursor());
    Object t = null;
    
    if (k != null && v != null) {
      t = _ctx.objectForKey(k); /* save old context value */
      _ctx.setObjectForKey(v, k);
    }
    
    this.template.appendToResponse(_r, _ctx);

    if (k != null && v != null) _ctx.removeObjectForKey(k);
    if (k != null && t != null) _ctx.setObjectForKey(t, k); /* restore old */
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    
    this.appendAssocToDescription(_d, "key",   this.key);
    this.appendAssocToDescription(_d, "value", this.value);
  }  
}
