package org.maachang.comet.conf ;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import org.maachang.conf.Config;
import org.maachang.conf.ReadIni;
import org.maachang.util.FileUtil;

/**
 * コンフィグファイル.
 *
 * @version 2007/08/19
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
public class IniFile {
    
    /**
     * キャラクタセット.
     */
    private static final String CHARSET = "UTF8" ;
    
    /**
     * 読み込み対象データ.
     */
    private Config iniParams = null ;
    
    /**
     * コンストラクタ.
     */
    public IniFile() {
        
    }
    
    /**
     * オープン.
     * <BR><BR>
     * ファイル名を指定してオープンします.
     * <BR>
     * @param name 対象名を設定します.
     * @exception Exception 例外.
     */
    public synchronized void open( String name ) throws Exception {
        this.close() ;
        this.addOpen( name,"" ) ;
    }
    
    /**
     * オープン.
     * <BR><BR>
     * ファイル名を指定してオープンします.
     * <BR>
     * @param name 対象名を設定します.
     * @param header 対象のセクションヘッダを設定します.
     * @exception Exception 例外.
     */
    public synchronized void open( String name,String header ) throws Exception {
        this.close() ;
        this.addOpen( name,header ) ;
    }
    
    /**
     * 追加オープン.
     * <BR><BR>
     * 現在のデータを保持したまま、別ファイル名を指定してオープンします.
     * <BR>
     * @param name 対象名を設定します.
     * @param header 対象のセクションヘッダを設定します.
     * @exception Exception 例外.
     */
    public synchronized void addOpen( String name ) throws Exception {
        this.addOpen( name,"" ) ;
    }
    
    /**
     * 追加オープン.
     * <BR><BR>
     * 現在のデータを保持したまま、別ファイル名を指定してオープンします.
     * <BR>
     * @param name 対象名を設定します.
     * @param header 対象のセクションヘッダを設定します.
     * @exception Exception 例外.
     */
    public synchronized void addOpen( String name,String header ) throws Exception {
        String fullPath = FileUtil.getFullPath( name ) ;
        BufferedReader buf = new BufferedReader(
            new InputStreamReader(
                new FileInputStream( fullPath ),CHARSET ) ) ;
        try {
            if( this.iniParams == null ) {
                this.iniParams = new Config() ;
            }
            ReadIni.analisys( iniParams,header,buf ) ;
        } catch( Exception e ) {
            this.close() ;
            throw e ;
        } finally {
            try {
                buf.close() ;
            } catch( Exception e ) {
            }
        }
    }
    
    /**
     * クローズ.
     * <BR><BR>
     * クローズ処理.
     */
    public synchronized void close() {
        iniParams = null ;
    }
    
    /**
     * 指定パラメータを取得.
     * <BR><BR>
     * 指定パラメータを取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @return String[] 対象の要素が返されます.
     */
    public synchronized String[] getAll( String section,String key ) {
        return iniParams.getAll( section,key ) ;
    }
    
    /**
     * 指定パラメータを取得.
     * <BR><BR>
     * 指定パラメータを取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @param no 対象の項番を設定します.
     * @return String 対象の要素が返されます.
     */
    public synchronized String get( String section,String key,int no ) {
        return iniParams.get( section,key,no ) ;
    }
    
    /**
     * 指定パラメータを取得.
     * <BR><BR>
     * 指定パラメータを取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @param no 対象の項番を設定します.
     * @return Integer 対象の要素が返されます.
     */
    public synchronized Integer getNumber( String section,String key,int no ) {
        String p = iniParams.get( section,key,no ) ;
        if( p == null || p.length() <= 0 ) {
            return null ;
        }
        Integer ret = null ;
        try {
            ret = new Integer( p ) ;
        } catch( Exception e ) {
            ret = null ;
        }
        return ret ;
    }
    
    /**
     * 指定パラメータを取得.
     * <BR><BR>
     * 指定パラメータを取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @param no 対象の項番を設定します.
     * @return Double 対象の要素が返されます.
     */
    public synchronized Double getFloat( String section,String key,int no ) {
        String p = iniParams.get( section,key,no ) ;
        if( p == null || p.length() <= 0 ) {
            return null ;
        }
        Double ret = null ;
        try {
            ret = new Double( p ) ;
        } catch( Exception e ) {
            ret = null ;
        }
        return ret ;
    }
    
    /**
     * 指定パラメータを取得.
     * <BR><BR>
     * 指定パラメータを取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @param no 対象の項番を設定します.
     * @return Boolean 対象の要素が返されます.
     */
    public synchronized Boolean getBoolean( String section,String key,int no ) {
        String p = iniParams.get( section,key,no ) ;
        if( p == null || p.length() <= 0 ) {
            return null ;
        }
        Boolean ret = null ;
        try {
            ret = new Boolean( p ) ;
        } catch( Exception e ) {
            ret = null ;
        }
        return ret ;
    }
    
    /**
     * 指定要素数を取得.
     * <BR><BR>
     * 指定要素数を取得します.
     * <BR>
     * @param section 対象のセクション名を設定します.
     * @param key 対象のキー名を設定します.
     * @return int 指定要素数が返されます.
     */
    public synchronized int size(String section, String key) {
        return iniParams.size( section,key ) ;
    }
    
    /**
     * 指定セクション数を取得.
     * <BR><BR>
     * 指定セクション数が返されます.
     * <BR>
     * @return int セクション数が返されます.
     */
    public synchronized int size() {
        return iniParams.size();
    }
    
    /**
     * 内部パラメータを取得.
     * <BR><BR>
     * 内部パラメータを取得します.
     * <BR>
     * @return IniParams 内部パラメータが返されます.
     */
    public synchronized Config getConfig() {
        return iniParams ;
    }
    
    /**
     * 文字列に変換.
     */
    public synchronized String toString() {
        if( iniParams != null ) {
            return iniParams.toString() ;
        }
        return "null" ;
    }
}

