/*
 * Paraselene
 * Copyright (c) 2009  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene.supervisor;

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

import paraselene.*;

/**
 * 遷移先指定。
 */
public class Forward implements Serializable {
	private static final long serialVersionUID = 2L;
	private int	error = 0;
	private URI	redirect_uri = null;
	private PageID	out_page = null;
	boolean history_f = false;
	boolean session_clear_f = false;
	ArrayList<Cookie>	out_cookie = new ArrayList<Cookie>();
	boolean done_f = false;

	/**
	 * クッキーの追加。
	 * クライアントに返したいクッキーを設定します。
	 * @param c クッキー。
	 */
	public void addCookie( Cookie c ) {
		out_cookie.add( c );
	}

	/**
	 * コンストラクタ。エラーを戻す。
	 * <br>セッションは常に解放されます。
	 * @param stat 404等。
	 */
	public Forward( int stat ) {
		error = stat;
		session_clear_f = true;
	}

	/**
	 * コンストラクタ。リダイレクト指定。
	 * @param uri 管理外のサイト等。
	 * @param session_off true:セッションを解放する、false:セッションを維持する
	 */
	public Forward( URI uri, boolean session_off ) {
		redirect_uri = uri;
		session_clear_f = session_off;
	}

	/**
	 * コンストラクタ。ページへ遷移。
	 * @param id 指定ページの出力。
	 * @param history_use true:履歴にあれば履歴インスタンスを使用、
	 * false:履歴にあっても新規インスタンスを使用
	 * @param session_off true:セッションを解放する、false:セッションを維持する
	 */
	public Forward( PageID id, boolean history_use, boolean session_off ) {
		out_page = id;
		history_f = history_use;
		session_clear_f = session_off;
	}

	/**
	 * コンストラクタ。ページへ遷移。new Forward( id, true, false )と等価です。
	 * @param id 指定ページの出力。
	 */
	public Forward( PageID id ) {
		this( id, true, false );
	}

	Page getPage( Page from ) {
		if ( out_page == null )	return null;
		if ( from != null ) {
			if ( out_page == from.getID() )	return from;
		}
		return out_page.getPageFactory().getPage( out_page.getID() );
	}

	/**
	 * 遷移先ページの取得。
	 * @return 遷移先のページID。エラー指定やリダイレクトの場合、nullを返します。
	 */
	public PageID getPageID() {
		return out_page;
	}

	/**
	 * リダイレクト先の取得。
	 * @return 遷移先のURI。エラー指定やページ指定の場合、nullを返します。
	 */
	public URI getRedirectURI() {
		return redirect_uri;
	}

	/**
	 * ステータスの取得。
	 * @return 返却ステータス。ページ指定やリダイレクトの場合、0を返します。
	 */
	public int getStatus() {
		return error;
	}

	/**
	 * 画面遷移。
	 * @param res レスポンス。
	 */
	void Action( Supervisor sp, HttpServletResponse res ) throws Exception {
		if ( done_f )	return;
		done_f = true;
		if ( error != 0 ) {
			if ( error == 403 ) {
//Thread.dumpStack();
			}
			res.sendError( error );
			return;
		}
		if ( redirect_uri != null ) {
			res.sendRedirect( Supervisor.makeWithSessionURI( redirect_uri.toString(), null, null ) );
			return;
		}
	}

	/**
	 * 設定内容取得。
	 * @return 設定値を文字列にして返します。
	 */
	public String toString() {
		if ( error != 0 ) {
			return "status:" + Integer.toString( error );
		}
		if ( redirect_uri != null ) {
			return "redirect:" + redirect_uri.toString();
		}
		return "page:" + getPageID().toString();
	}
}

