/*
 * "Peko" Visual Novel System
 *
 * All Rights Reserved.
 * Copyright (c) 1999-2003 Tsukuba Bunko.
 *
 * $Id: TypeMapping.java,v 1.1.2.1 2003/12/11 11:11:53 ppoi Exp $
 */
package tsukuba_bunko.peko.resource;

import	java.io.InputStream;
import	java.io.IOException;

import	java.util.Properties;

import	tsukuba_bunko.peko.InitializationError;
import	tsukuba_bunko.peko.Logger;

import	tsukuba_bunko.resource.DeserializerMapping;
import	tsukuba_bunko.resource.ResourceDeserializer;


/**
 * リソース ID と データ型のマッピングを管理します。
 * @author	$Author: ppoi $
 * @version	$Revision: 1.1.2.1 $
 */
public class TypeMapping	{

	/**
	 * 唯一のインスタンス
	 */
	private static TypeMapping	_instance = null;


	/**
	 * リソース ID - データ型マップ
	 */
	private Properties	_typeMapping = null;

	/**
	 * DeserializerMapping
	 */
	private DeserializerMapping	_deserializerMapping = null;


	/**
	 * <code>TypeMapping</code> のインスタンスを作成します。
	 */
	protected TypeMapping()
	{
		super();
	}


	/**
	 * 指定されたリソースのデータ型名を取得します。
	 * @param	resourceID	リソース ID
	 * @return	データ型名
	 */
	public String getDataType( String resourceID )
	{
		return _typeMapping.getProperty( resourceID );
	}

	/**
	 * 指定されたリソースをデシリアライズする ResourceDeserializer を取得します。
	 * @param	resourceID	リソース ID
	 * @return	ResourceDeserializer
	 */
	public ResourceDeserializer getResourceDeserializer( String resourceID )
	{
		String	type = _typeMapping.getProperty( resourceID );
		if( type != null )	{
			return _deserializerMapping.getResourceDeserializer( type );
		}
		else	{
			return null;
		}
	}

	/**
	 * DeserializerMapping を取得します。
	 * @return	DeserializerMapping
	 */
	public DeserializerMapping getDeserializerMapping()
	{
		return _deserializerMapping;
	}

	/**
	 * <cpde>TypeMapping</code> を初期化します。
	 * @throws	InitializationError	初期化に失敗した場合
	 */
	protected void initialize()
	{
		ClassLoader	cl = getClass().getClassLoader();
		InputStream	is = cl.getResourceAsStream( "resources.def" );
		if( is == null )	{
			throw new InitializationError( "resources.def not found." );
		}

		Properties	props = new Properties();
		try	{
			props.load( is );
		}
		catch( IOException ioe )	{
			Logger.fatal( "[resource] fail to initialize TypeMapping.", ioe );
			throw new InitializationError( "fail to initialize TypeMapping.", ioe );
		}
		finally	{
			try	{
				is.close();
			}
			catch( IOException ioe )	{
				Logger.fatal( "[resource] fail to initialize TypeMapping.", ioe );
			}
		}
		_typeMapping = props;

		_deserializerMapping = DeserializerMapping.newInstance( "tsukuba_bunko.peko.resource.mapping" );
	}



	/**
	 * 唯一の <code>TypeMapping</code> のインスタンスを取得します。
	 * @return	唯一の <code>TypeMapping</code> のインスタンス
	 * @throws	InitializationError	初期化に失敗した場合
	 */
	public static TypeMapping getInstance()
	{
		if( _instance == null )	{
			synchronized( TypeMapping.class )	{
				if( _instance == null )	{
					_instance = new TypeMapping();
					_instance.initialize();
				}
			}
		}
		return _instance;
	}
}
