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

import java.util.*;
import java.io.*;

/**
 * 画面遷移履歴セット。スレッドセーフです。
 */
class HistorySet implements Serializable {
	private static final long serialVersionUID = 2L;
	static final int	ROOT = 0;
	static final int	RAND = 0x7fffffff;
	private HashMap<String,Integer>		set_no = new HashMap<String,Integer>();
	private HashMap<Integer,History>	hist = new HashMap<Integer,History>();

	HistorySet() {
		newNo( ROOT );
	}

	synchronized History get( int key ) {
		return hist.get( key );
	}

	synchronized void remove( int key ) {
		if ( set_no.containsValue( new Integer( key ) ) )	return;
		hist.remove( key );
	}

	synchronized private int newNo( int no ) {
		while ( true ) {
			if ( no == RAND || hist.get( no ) != null ) {
				no++;
				if ( no < 0 )	no = 1;
				continue;
			}
			hist.put( no, new History( no ) );
			return no;
		}
	}

	int toInt() {
		return newNo( (int)new Date().getTime() & 0x7fffffff );
	}

	synchronized int toInt( String name, int org ) {
		if ( name == null )	return org;
		if ( name.isEmpty() )	return org;
		if ( "_self".equals( name ) )	return org;
		if ( "_top".equals( name ) )	return ROOT;
		if ( "_blank".equals( name ) || "_parent".equals( name ) ) {
			return RAND;
		}
		if ( name.indexOf( "paraselene" ) >= 0 )	return org;
		Integer	ret = set_no.get( name );
		if ( ret != null )	return ret;
		int	n = newNo( name.hashCode() );
		set_no.put( name, n );
		return n;
	}
}

