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

import	java.io.File;

import	java.net.MalformedURLException;
import	java.net.URL;

import	tsukuba_bunko.resource.Resources;

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

import	tsukuba_bunko.util.ResourceLocator;


/**
 * ディレクトリロケーション設定を構成する機能を提供します。
 * @author	$Author: ppoi $
 * @version	$Revision: 1.1.2.1 $
 */
public class LocationConfigurator	{

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


	/**
	 * インストールディレクトリを取得します。
	 * @return	インストールディレクトリのファイルシステム上の抽象パス
	 */
	protected File detectInstallDirectory()
	{
		File	baseLocation = null;
		try	{
			ResourceLocator	locator = ResourceLocator.newInstance();
			baseLocation = locator.findLocation( "tsukuba_bunko/peko/PekoSystem.class" );

			if( baseLocation.isFile() )	{
				baseLocation = baseLocation.getParentFile().getParentFile();
			}
			else	{
				baseLocation = baseLocation.getParentFile();
			}
		}
		catch( Exception e )	{
			Logger.fatal( MessageIDs.RES0006F, e );
			throw new InitializationError( "fail to detect install directory.", e );
		}
		Logger.debug( "install dir: " + baseLocation.getAbsolutePath() );

		return baseLocation;
	}

	/**
	 * ディレクトリ URL を構成します。指定されたディレクトリがファイルだった場合、JAR アーカイブとして処理します。
	 * @param	directory	データ格納ディレクトリ名
	 * @param	installDir	インストールディレクトリ
	 * @return	構成された URL
	 */
	protected URL configureDirectoryURL( String directory, File installDir )
	{
		File	dataDirectory = new File( installDir, directory );
		Logger.debug( "dir: " + dataDirectory );
		if( dataDirectory.isDirectory() )	{
			try	{
				return dataDirectory.toURL();
			}
			catch( MalformedURLException mue )	{
				InitializationError	ie = new InitializationError( "invalid data directory.", mue );
				Logger.fatal( MessageIDs.RES0008F, new Object[]{directory}, ie );
				throw ie;
			}
		}
		else if( dataDirectory.isFile() )	{
			try	{
				return new URL( "jar:" + dataDirectory.toURL().toString() + "!/" );
			}
			catch( MalformedURLException mue )	{
				InitializationError	ie = new InitializationError( "invalid data directory.", mue );
				Logger.fatal( MessageIDs.RES0008F, new Object[]{directory}, ie );
				throw ie;
			}
		}
		else	{
			InitializationError	ie = new InitializationError( "invalid data directory." );
			Logger.fatal( MessageIDs.RES0008F, new Object[]{directory}, ie );
			throw ie;
		}
	}

	protected File ensureSaveDirectory( String directory, File installDir )
	{
		File	saveDir = new File( installDir, directory );
		if( saveDir.exists() )	{
			if( saveDir.isDirectory() )	{
				return saveDir;
			}
			else	{
				InitializationError	ie = new InitializationError( "already exist file." );
				Logger.fatal( MessageIDs.RES0012F, ie );
				throw ie;
			}
		}
		else	{
			if( !saveDir.mkdir() )	{
				InitializationError ie = new InitializationError( "fail to create dir." );
				Logger.fatal( MessageIDs.RES0013F, ie );
				throw ie;
			}
			return saveDir;
		}
	}


	/**
	 * システム構成リソースの内容から構成された <code>LocationResources</code> を生成します。
	 * @param	systemResources	システム構成リソース
	 * @return	構成済みの <code>LocationResources</code> インスタンス
	 */
	public LocationResources configure( Resources systemResources )
	{
		LocationResources	locations = new LocationResources();

		File	installDir = detectInstallDirectory();

		String[]	keys = { "scenes", "images", "sounds", "misc" };
		URL	url = null;
		String	value = null;
		for( int i = 0; i < keys.length; ++i )	{
			value = (String)systemResources.getResource( "peko.system.location." + keys[i] );
			if( value == null )	{
				InitializationError	ie = new InitializationError( "directory is not specified." );
				Logger.fatal( MessageIDs.RES0011F, new Object[]{keys[i]}, ie );
				throw ie;
			}
			else	{
				url = configureDirectoryURL( value, installDir );
				Logger.debug( url.toString() );
				locations.setResource( "peko.system.location." + keys[i], url );
			}
		}

		String	saveDirectory = (String)systemResources.getResource( "peko.system.location.save" );
		if( saveDirectory == null )	{
			saveDirectory = "save";
		}
		locations.setResource( LocationResources.DIR_SAVE, ensureSaveDirectory(saveDirectory, installDir) );

		locations.setResource( LocationResources.DIR_INSTALL, installDir );

		return locations;
	}
}
