/*
 * VsqBPList.java
 * Copyright (c) 2008 kbinani
 *
 * This file is part of jp.sourceforge.lipsync.vsq.
 *
 * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or
 * modify it under the terms of the BSD License.
 *
 * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package jp.sourceforge.lipsync.vsq;

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

/**
 * ～BPListのデータ部分を取り扱うためのクラス。
 *@author  kbinani
 */
public class VsqBPList implements Cloneable {
    TreeMap<Integer, Integer> _list = new TreeMap<Integer, Integer>();
    int _default = 0;
    int _maximum = 127;
    int _minimum = 0;

    public Object clone() {
        VsqBPList res = new VsqBPList( _default, _minimum, _maximum );
        Set<Integer> enumerator = _list.keySet();
        for ( Iterator itr = enumerator.iterator(); itr.hasNext();) {
            Integer key = (Integer)itr.next();
            res._list.put( key, _list.get( key ) );
        }
        return res;
    }

    /**
     * コンストラクタ。デフォルト値はココで指定する。
     * @param default_value
     */
    public VsqBPList( int default_value, int minimum, int maximum ) {
        _default = default_value;
        _maximum = maximum;
        _minimum = minimum;
    }

    /**
     * このリストに設定された最大値を取得します。
     */
    public int getMaximum() {
        return _maximum;
    }

    /**
     * このリストに設定された最小値を取得します
    /*
    public int getMinimum() {
    return _minimum;
    }
    
    
    /* // <summary>
    /// _listへのアクセッサ
    /// </summary>
    public SortedList<int, int> List {
    get {
    return _list;
    }
    }*/
    public Set<Integer> keyClockSet() {
        return _list.keySet();
    }
    
    
    public Iterator<Integer> keyClockIterator(){
        return _list.keySet().iterator();
    }

    public void remove( int clock ) {
        if ( _list.containsKey( clock ) ) {
            _list.remove( clock );
        }
    }

    public boolean containsKey( int clock ) {
        return _list.containsKey( clock );
    }

    public int size() {
        return _list.size();
    }

    public void clear() {
        _list.clear();
    }

    /**
     * 新しいデータ点を追加します。
     *
     * @param clock 
     * @param value
     */
    public void add( int clock, int value ) {
        _list.put( clock, value );
    }

    public int get( int clock ) {
        if ( _list.size() == 0 ) {
            return _default;
        } else {
            if ( _list.containsKey( clock ) ) {
                return _list.get( clock );
            } else {
                int index = 0;
                int prev = 0;
                for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) {
                    Integer key = (Integer)itr.next();
                    if ( clock < key ) {
                        index = prev;
                        break;
                    }
                    prev = key;
                }
                if ( _list.containsKey( index ) ) {
                    return _list.get( index );
                } else {
                    return _default;
                }
            }
        }
    }

    /**
     * このBPListのデフォルト値を取得します
     */
    public int getDefault() {
        return _default;
    }

    /**
     * このBPListの内容をテキストファイルに書き出します
     *
     * @param writer
     */
    public void print( BufferedWriter writer ) throws IOException {
        boolean first = true;
        for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) {
            Integer key = (Integer)itr.next();
            int val = _list.get( key );
            if ( first ) {
                writer.write( key + "=" + val + "\n" );
                first = false;
            } else {
                writer.write( key + "=" + val + "\n" );
            }
        }
    }

    /**
     * このBPListの内容をテキストファイルに書き出します
     *
     * @param writer
     */
    public void print( TextMemoryStream writer, int start, String header ) {
        boolean first = true;
        for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) {
            Integer key = (Integer)itr.next();
            if ( start <= key ) {
                if ( first ) {
                    writer.writeLine( header );
                    first = false;
                }
                int val = _list.get( key );
                writer.writeLine( key + "=" + val );
            }
        }
    }

    /**
     * テキストファイルからデータ点を読込み、現在のリストに追加します
     *
     * @param reader
     * @returns
     */
    public String readFrom( TextMemoryStream reader ) {
        String last_line = reader.readLine();
        while ( !last_line.startsWith( "[" ) ) {
            String[] spl = last_line.split( "=" );
            int i1 = Integer.parseInt( spl[0] );
            int i2 = Integer.parseInt( spl[1] );
            _list.put( i1, i2 );
            if ( reader.peek() < 0 ) {
                break;
            } else {
                last_line = reader.readLine();
            }
        }
        return last_line;
    }

}
