/*
 * CharacterConfigCollection.cs
 * Copyright (c) 2007-2009 kbinani
 *
 * This file is part of LipSync.
 *
 * LipSync is free software; you can redistribute it and/or
 * modify it under the terms of the BSD License.
 *
 * LipSync 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.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

namespace LipSync {

    /// <summary>
    /// キャラクタ設定ファイルのリストを管理するクラス
    /// </summary>
    public static class CharacterConfigCollection {

        /// <summary>
        /// リストの最大長
        /// </summary>
        const int MAX_DICT_LEN = 128;
        static List<CharacterConfigSpecifier> m_list = new List<CharacterConfigSpecifier>();

        /// <summary>
        /// IDがidであるキャラクタ設定ファイルがリストに登録されているかどうかを返します
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool IsRegistered( string id ) {
            foreach ( CharacterConfigSpecifier item in m_list ) {
                if ( item.ID == id ) {
                    return true;
                }
            }
            return false;
        }


        /// <summary>
        /// 現在のリストの内容を逐次返すiterator
        /// </summary>
        /// <returns></returns>
        public static IEnumerator<CharacterConfigSpecifier> GetEnumerator() {
            foreach ( CharacterConfigSpecifier item in m_list ) {
                yield return item;
            }
            yield break;
        }


        /// <summary>
        /// ファイル名がidであるキャラクタ設定ファイルのプレビューを返します．未登録の場合はnullを返します
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Image GetPreviewImage( string id ) {
            foreach ( CharacterConfigSpecifier item in m_list ) {
                if ( item.ID == id ) {
                    return item.Image;
                }
            }
            return null;
        }


        /// <summary>
        /// ファイル名がfileであるキャラクタ設定ファイルを読み込み，リストに登録します．
        /// 既に登録済みであっても，登録された時点よりファイルが新しければ，登録内容を更新します
        /// </summary>
        /// <param name="file"></param>
        public static void Register( string file ) {
#if DEBUG
            Common.DebugWriteLine( "CharacterConfigCollection.Register(String); m_list.Count=" + m_list.Count );
#endif
            if ( !File.Exists( file ) ) {
                return;
            }
            DateTime date = File.GetLastWriteTimeUtc( file );
            DateTime date_registered = new DateTime();
            int index = -1;
            for( int i = 0; i < m_list.Count; i++ ){
                if ( m_list[i].ID == file  ) {
                    index = i;
                    date_registered = m_list[i].LastModefied;
                    break;
                }
            }

            // Character, Character3クラスを読み込んで，登録
            CharacterConfigSpecifier item = null;
            if ( Path.GetFileName( file ).ToLower() == "content.xml" ) {
                Character3 ch = Character3.FromXml( file );
                item = new CharacterConfigSpecifier( ch, file, File.GetLastWriteTimeUtc( file ) );
            } else {
                try {
                    Character3 ch = Character3.FromFile( file );
                    item = new CharacterConfigSpecifier( ch, file, File.GetLastWriteTimeUtc( file ) );
                } catch {
                    try {
                        Character t = LipSync.Character.FromFile( file );
                        item = new CharacterConfigSpecifier( t, file, File.GetLastWriteTimeUtc( file ) );
                    } catch {
                        item = new CharacterConfigSpecifier( file, File.GetLastWriteTimeUtc( file ) );
                    }
                }
            }
            if ( item != null ) {
#if DEBUG
                string dir = Path.GetDirectoryName( file );
                Common.GetThumbnailImage( item.Image, 128, 128 ).Save( Path.Combine( dir, Path.GetFileNameWithoutExtension( file ) ) + ".png" );
#endif
                if ( index >= 0 ) {
                    if ( date > date_registered ) {
                        m_list.RemoveAt( index );
                        if ( m_list.Count > MAX_DICT_LEN ) {
                            m_list.RemoveAt( 0 );
                        }
                        m_list.Add( item );
                    }
                } else {
                    m_list.Add( item );
                }
            }
        }

    }

}
