// DirectoryResource.java
// $Id: IfCommand.java,v 1.2 1998/02/24 13:03:53 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.ssi.commands;

import java.util.*;

import org.w3c.www.http.*;
import org.w3c.jigsaw.http.*;
import org.w3c.tools.resources.*;
import org.w3c.util.*;
import org.w3c.jigsaw.ssi.*;

/**
 * Implementation of the SSI <code>if</code> command.  
 * @author Benoit Mahe <bmahe@sophia.inria.fr>
 */
public class IfCommand implements ControlCommand {
  private final static String  NAME  = "if";
  private final static boolean debug = true;
    
  private static final String keys[] = { 
    "name",
    "command",
    "var",
    "equals"
  };

  protected static Hashtable ifstore = null;

  static {
     ifstore = new Hashtable(23);
  }
  /**
   * Returns the (String) value of the given variable.
   * @return a String instance.
   */
  public String getValue(Dictionary variables, String var, Request request) {
    return null;
  }

  protected static int getPosition(String name) 
    throws ControlCommandException    
  {
    Integer pos = (Integer)ifstore.get(name);
    if (pos == null)
      throw new ControlCommandException(NAME,"Position unknown.");
     else return pos.intValue();
  }

  /**
   * register the command position in the structure
   * witch store the SSIFrame.
   */
  public void setPosition(SSIFrame ssiframe,
			  Request request,
			  CommandRegistry registry,
			  ArrayDictionary parameters,
			  Dictionary variables,
			  int position) 
  {
    Object values[] = parameters.getMany(keys);
    String name     = (String) values[0];
    if (name != null)
      ifstore.put(ssiframe.getResource().getURLPath()+
		  ":"+name, new Integer(position));
  }
  /**
   * Executes this command. Might modify variables.
   * Must <em>not</em> modify the parameters.
   * <P> It may handle conditional requests, <em>except</em> that if
   * it replies with a status of HTTP.NOT_MODIFIED, it <em>must</em>
   * still reply with a content (the same content that it would have
   * returned for an inconditional request).  This is because
   * further SSI commands down the line may decide thay they have
   * been modified, and then a content must be emitted by SSIFrame.
   *
   * @param request the original HTTP request
   * @param parameters The parameters for this command
   * @param variables The global variables for the parse 
   * @return a Reply with the output from the command */
  public Reply execute(SSIFrame ssiframe
		       , Request request
		       , ArrayDictionary parameters
		       , Dictionary variables) 
  {
    return ssiframe.createCommandReply(request, HTTP.OK);
  }

  protected boolean check(CommandRegistry registry
			  , ArrayDictionary parameters
			  , Dictionary variables
			  , Request request)
  {
    Object values[] = parameters.getMany(keys);
    String name     = (String) values[0];
    String command  = (String) values[1];
    String var      = (String) values[2];
    String equals   = (String) values[3];
    
    if ((command == null) || (var == null) || (equals == null))
      return false;
    Command cmd = registry.lookupCommand(command);
    String value = cmd.getValue(variables,var, request);
    return value.equals(equals);
  }

  /**
   * Give the next position in the structure witch
   * store the SSIFrame.
   */
  public int jumpTo(SSIFrame ssiframe,
		    Request request,
		    CommandRegistry registry,
		    ArrayDictionary parameters,
		    Dictionary variables)
    throws ControlCommandException
  {
    Object values[] = parameters.getMany(keys);
    String name     = (String) values[0];
    if (name != null) {
      if (check(registry,parameters,variables,request))
	return getPosition(ssiframe.getResource().getURLPath()+":"+name)+1;
      try {
	return (ElseCommand.getPosition(ssiframe.getResource().getURLPath()+
					":"+name)+1);
      } catch (ControlCommandException ex) {
	return (EndifCommand.getPosition(ssiframe.getResource().getURLPath()+
					 ":"+name)+1);
      }
    }
    throw new ControlCommandException(NAME,"name not initialized.");    
  }
  /** 
   * Returns the name of this command. <em>(Case sensitivity is up to
   * the <code>lookupCommand</code> method in the command registry.)</em>
   *
   * @return the name of the command
   * @see org.w3c.jigsaw.ssi.CommandRegistry#lookupCommand
   */
  public String getName() {
    return NAME;
  }

}
