/*
 * VsqID.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.text.*;
/// <summary>
/// メタテキストに埋め込まれるIDを表すクラス。
/// </summary>

public class VsqID implements Cloneable {
    public int value;
    public VsqIDType type;
    public int IconHandle_index;
    public IconHandle IconHandle;
    public int Length;
    public int Note;
    public int Dynamics;
    public int PMBendDepth;
    public int PMBendLength;
    public int PMbPortamentoUse;
    public int DEMdecGainRate;
    public int DEMaccent;
    public int LyricHandle_index;
    public LyricHandle LyricHandle;
    public int VibratoHandle_index;
    public VibratoHandle VibratoHandle;
    public int VibratoDelay;
    public static VsqID EOS = new VsqID( -1 );

    /// <summary>
    /// このインスタンスの簡易コピーを取得します。
    /// </summary>
    /// <returns>このインスタンスの簡易コピー</returns>
    public Object clone() {
        VsqID result = new VsqID( this.value );
        result.type = this.type;
        if ( this.IconHandle != null ) {
            result.IconHandle = (IconHandle)this.IconHandle.clone();
        }
        result.Length = this.Length;
        result.Note = this.Note;
        result.Dynamics = this.Dynamics;
        result.PMBendDepth = this.PMBendDepth;
        result.PMBendLength = this.PMBendLength;
        result.PMbPortamentoUse = this.PMbPortamentoUse;
        result.DEMdecGainRate = this.DEMdecGainRate;
        result.DEMaccent = this.DEMaccent;
        if ( this.LyricHandle != null ) {
            result.LyricHandle = (LyricHandle)this.LyricHandle.clone();
        }
        if ( this.VibratoHandle != null ) {
            result.VibratoHandle = (VibratoHandle)this.VibratoHandle.clone();
        }
        result.VibratoDelay = this.VibratoDelay;
        return result;
    }


    /// <summary>
    /// IDの番号（ID#****の****）を指定したコンストラクタ。
    /// </summary>
    /// <param name="a_value">IDの番号</param>
    public VsqID( int a_value ) {
        value = a_value;
    }


    /// <summary>
    /// テキストファイルからのコンストラクタ
    /// </summary>
    /// <param name="sr">読み込み対象</param>
    /// <param name="value"></param>
    /// <param name="last_line">読み込んだ最後の行が返されます</param>
    public VsqID( TextMemoryStream sr, int value, TextResult last_line ) {
        String[] spl;
        this.value = value;
        this.type = VsqIDType.Unknown;
        this.IconHandle_index = -2;
        this.LyricHandle_index = -1;
        this.VibratoHandle_index = -1;
        this.Length = 0;
        this.Note = 0;
        this.Dynamics = 0;
        this.PMBendDepth = 0;
        this.PMBendLength = 0;
        this.PMbPortamentoUse = 0;
        this.DEMdecGainRate = 0;
        this.DEMaccent = 0;
        //this.LyricHandle_index = -2;
        //this.VibratoHandle_index = -2;
        this.VibratoDelay = 0;
        last_line.set( sr.readLine() );
        while ( !last_line.get().startsWith( "[" ) ) {
            spl = last_line.get().split( "=" );
            if ( spl[0].equals( "Type" ) ) {
                if ( spl[1].equals( "Anote" ) ) {
                    type = VsqIDType.Anote;
                } else if ( spl[1].equals( "Singer" ) ) {
                    type = VsqIDType.Singer;
                } else {
                    type = VsqIDType.Unknown;
                }
            } else if ( spl[0].equals( "Length" ) ) {
                this.Length = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "Note#" ) ) {
                this.Note = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "Dynamics" ) ) {
                this.Dynamics = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "PMBendDepth" ) ) {
                this.PMBendDepth = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "PMBendLength" ) ) {
                this.PMBendLength = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "DEMdecGainRate" ) ) {
                this.DEMdecGainRate = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "DEMaccent" ) ) {
                this.DEMaccent = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "LyricHandle" ) ) {
                this.LyricHandle_index = VsqHandle.HandleIndexFromString( spl[1] );

            } else if ( spl[0].equals( "IconHandle" ) ) {
                this.IconHandle_index = VsqHandle.HandleIndexFromString( spl[1] );
            } else if ( spl[0].equals( "VibratoHandle" ) ) {
                this.VibratoHandle_index = VsqHandle.HandleIndexFromString( spl[1] );
            } else if ( spl[0].equals( "VibratoDelay" ) ) {
                this.VibratoDelay = Integer.parseInt( spl[1] );
            } else if ( spl[0].equals( "PMbPortamentoUse" ) ) {
                PMbPortamentoUse = Integer.parseInt( spl[1] );
            }
            if ( sr.peek() < 0 ) {
                break;
            }
            last_line.set( sr.readLine() );
        }
    }

    public String toString() {
        String ret = "{Type=" + type;
        DecimalFormat df = new DecimalFormat( "0000" );
        switch ( type ) {
            case Anote:
                ret += ", Length=" + Length;
                ret += ", Note#=" + Note;
                ret += ", Dynamics=" + Dynamics;
                ret += ", PMBendDepth=" + PMBendDepth;
                ret += ", PMBendLength=" + PMBendLength;
                ret += ", PMbPortamentoUse=" + PMbPortamentoUse;
                ret += ", DEMdecGainRate=" + DEMdecGainRate;
                ret += ", DEMaccent=" + DEMaccent;
                if ( LyricHandle != null ) {
                    ret += ", LyricHandle=h#" + df.format( LyricHandle_index );
                }
                if ( VibratoHandle != null ) {
                    ret += ", VibratoHandle=h#" + df.format( VibratoHandle_index );
                    ret += ", VibratoDelay=" + VibratoDelay;
                }
                break;
            case Singer:
                ret += ", IconHandle=h#" + df.format( IconHandle_index );
                break;
        }
        ret += "}";
        return ret;
    }


    /// <summary>
    /// インスタンスをテキストファイルに出力します
    /// </summary>
    /// <param name="sw">出力先</param>
    public void write( TextMemoryStream sw ) {
        DecimalFormat df = new DecimalFormat( "0000" );
        sw.writeLine( "[ID#" + df.format( value ) + "]" );
        sw.writeLine( "Type=" + type );
        switch ( type ) {
            case Anote:
                sw.writeLine( "Length=" + Length );
                sw.writeLine( "Note#=" + Note );
                sw.writeLine( "Dynamics=" + Dynamics );
                sw.writeLine( "PMBendDepth=" + PMBendDepth );
                sw.writeLine( "PMBendLength=" + PMBendLength );
                sw.writeLine( "PMbPortamentoUse=" + PMbPortamentoUse );
                sw.writeLine( "DEMdecGainRate=" + DEMdecGainRate );
                sw.writeLine( "DEMaccent=" + DEMaccent );
                if ( LyricHandle != null ) {
                    sw.writeLine( "LyricHandle=h#" + df.format( LyricHandle_index ) );
                }
                if ( VibratoHandle != null ) {
                    sw.writeLine( "VibratoHandle=h#" + df.format( VibratoHandle_index ) );
                    sw.writeLine( "VibratoDelay=" + VibratoDelay );
                }
                break;
            case Singer:
                sw.writeLine( "IconHandle=h#" + df.format( IconHandle_index ) );
                break;
        }
    }

}
