// JigsawHttpServletReponse.java
// $Id: JigsawHttpServletResponse.java,v 1.11 1998/02/09 17:03:08 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigsaw.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.*;

import org.w3c.www.mime.*;
import org.w3c.www.http.*;
import org.w3c.jigsaw.http.*;

/**
 *  @author Alexandre Rafalovitch <alex@access.com.au>
 *  @author Anselm Baird-Smith <abaird@w3.org>
 */

public class JigsawHttpServletResponse implements HttpServletResponse 
{
    private final static int STATE_INITIAL = 0;
    private final static int STATE_HEADERS_DONE = 1;
    private final static int STATE_ALL_DONE = 2;

    private final static int STREAM_STATE_INITIAL = 0;
    private final static int STREAM_WRITER_USED = 1;
    private final static int OUTPUT_STREAM_USED = 2;

    private int stream_state = STREAM_STATE_INITIAL;
 
    public static final 
    String REMOVE_HEADER = "org.w3c.jigsaw.servlet.removeHeader";
   
    int   state = STATE_INITIAL;
    Reply reply = null;
    Request request = null;

    JigsawHttpServletResponse(Request request, Reply reply)
    {
	this.request = request;
	this.reply   = reply;
    }
    
    public void setContentLength(int i) {
	reply.setContentLength(i);
    }
    
    public void setContentType(String spec) {
	try {
	    MimeType type= new MimeType(spec);
	    reply.setContentType(type);
	} catch(MimeTypeFormatException ex) {
	    // FIXME what should I do?
	}
    }

    protected JigsawServletOutputStream output = null;

    public synchronized ServletOutputStream getOutputStream()
	throws IOException
    {
      if (stream_state == STREAM_WRITER_USED)
	throw new IllegalStateException("Writer used");
      stream_state = OUTPUT_STREAM_USED;
      return getJigsawOutputStream();
    }

    protected ServletOutputStream getJigsawOutputStream()
	throws IOException
    {
      if ( output != null )
	return output;
      
      if ( request.hasState(REMOVE_HEADER) )
	output = (new JigsawServletOutputStream
		  (this
		   , new DataOutputStream(reply.getOutputStream(false))));
      else
	output = (new JigsawServletOutputStream
		  (this
		   , new DataOutputStream(reply.getOutputStream())));
      return output;
    }
    
    public void setStatus(int i, String reason) {
	reply.setStatus(i);
	reply.setReason(reason);
    }
    
    public void setStatus(int i) {
	setStatus(i, reply.getStandardReason(i));
    }
    
    public void setHeader(String name, String value) {
	reply.setValue(name, value);
    }
    
    public void setIntHeader(String name, int value) {
	setHeader(name, String.valueOf(value));
    }
    
    public void setDateHeader(String name, long date) {
	setHeader(name, String.valueOf(date));
    }
    
    public void unsetHeader(String name) {
	setHeader(name, null);
    }
    
    public void sendError(int i, String msg) 
	throws IOException
    {
	setStatus(i);
	reply.setContent(msg);
	state = STATE_ALL_DONE;
    }
    
    public void sendError(int i)
        throws IOException
    {
	setStatus(i);
	reply.setContent(reply.getStandardReason(i));
	state = STATE_ALL_DONE;
    }
    
    public void sendRedirect(String url)
        throws IOException
    {
	URL loc = null;
	try {
	    loc = new URL(request.getURL(), url);
	    setStatus(SC_MOVED_TEMPORARILY);
	    reply.setLocation(loc);
	    state = STATE_ALL_DONE;
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
    }

  // method added

  public boolean containsHeader(String header) {
    //    return request.hasHeader(header);
    return reply.hasHeader(header);
  }

  //API 1.2:

  public void addCookie(Cookie cookie) {

  }

  public String encodeRedirectUrl(String url) {
    return url;
  }

  public String encodeUrl(String url) {
    return url;
  }

  public String getCharacterEncoding() {
    String enc = (reply.getContentType()).toString();
    if (enc == null)
      enc = "text/plain";
    return enc;
  }

  public PrintWriter writer = null;

  public synchronized PrintWriter getWriter() 
    throws IOException, UnsupportedEncodingException
  {
      if (stream_state == OUTPUT_STREAM_USED)
	throw new IllegalStateException("Output stream used");
      stream_state = STREAM_WRITER_USED;
      
      if (writer == null) {
	writer = new PrintWriter(
		    new OutputStreamWriter( getJigsawOutputStream(), 
					   getCharacterEncoding()));
    }
    return writer;
  }

}
