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

import paraselene.*;

/**
 * 遷移先指定。
 * 直前のページ(直前に output したページ(履歴より取得します))に画面遷移します。<br>
 * 履歴にページが無い場合、{@link Feedback}と同じ動作をします。<br>
 * 元々{@link Popup}でポップアップ表示されたページであれば、
 * ポップアップを閉じます。
 */
public class Closure extends Forward {
	private static final long serialVersionUID = 2L;
	static final PageID	CLOSE = new PageID(){
		public boolean isSame( Page p ){ return false; }
		public int getID(){ return -1; }
		public PageID getPageID( int id ){ return null; }
		public PageFactory getPageFactory(){ return null; }
	};

	private static PageID getLastPage( Page myself, History history ) {
		if ( myself == null || history == null )	return CLOSE;
		Page	last = history.getPage( 0 );
		if ( myself == last ) {
			for ( int i = 1; last != null; i++ ) {
				last = history.getPage( i );
				if ( last != myself )	break;
			}
		}
		if ( last == null )	return CLOSE;
		return last.getID();
	}

	/**
	 * コンストラクタ。
	 * 履歴上で、直前にスタックされているページで output を処理します。<br>
	 * セッションは維持されます。
	 */
	public Closure() {
		super( getLastPage( SandBox.getCurrentPage(), SandBox.getCurrentRequestParameter().getHistory() ) );
	}

	Closure( PageID id ) {
		super( id );
	}

	static boolean isClosure( Page from, Page next, RequestParameter req ) {
		if ( from == null || next == null )	return false;
		return next.getID() == getLastPage( from, req.getHistory( from.getHistoryKey() ) );
	}
}

