<?php
/**
 * MessageBehavior.
 * @package magic.core
 * @subpackage helper.message
 */
/**
 * メッセージクラスをロードして、メッセージを取得します.
 * <p>
 * ロケール別にメッセージクラスを分ける場合は、{@link PathConfigure::getDefaultMessageFileName()}
 * のドキュメントを参照してください。<br/>
 * メッセージクラスの記述方法は、{@link SystemMessage}クラスを参照してください。
 * </p>
 * @package magic.core
 * @subpackage helper.message
 * @author T.Okumura
 * @version 1.0.0
 * @final
 * @see PathConfigure::getDefaultMessageFileName()
 * @see SystemMessage
 */
final class MessageBehavior {
    /**
     * メッセージクラス.
     * @staticvar object
     */
    private static $_class = NULL;
    /**
     * コンストラクタ.
     */
    private function __construct() {
    }
    /**
     * メッセージクラスを設定します.
     * @param PathConfigure $path [optional] クラスパス設定クラス
     * @throws MagicException メッセージクラスが不正な場合
     * @static
     */
    public static function setMessageClass(PathConfigure $path = NULL) {
        $locale = LocaleProvider::getLocale();
        switch (strtolower($locale)) {
            case 'en':
                self::$_class = new SystemMessage_en();
                break;
            case 'ja':
                self::$_class = new SystemMessage();
                break;
            default:
                self::$_class = new SystemMessage();
        }
        if (!is_null($path)) {
            $classPath = $path->getMessagePath();
            $className = $path->getDefaultMessageFileName();
            $class = NULL;
            if (@include_once $classPath . $className . '_' . $locale . '.php') {
                $className = $className . '_' . $locale;
                $class = new $className();
            } elseif (@include_once $classPath . $className . '.php') {
                $class = new $className();
            }
            if (is_null($class)) {
                throw new MagicException(self::getMessage('SYS001', $classPath . $className));
            }
            if (!($class instanceof SystemMessage)) {
                throw new MagicException(self::getMessage('SYS002', array('SystemMessage', get_class($class))));
            }
            self::$_class = $class;
        }
    }
    /**
     * コードからメッセージを取得します.
     * @param string $code メッセージコード
     * @param mixed $replacement [optional] 置換文字またはその配列(オプション)
     * @return string メッセージ文字列
     * @throws MagicException コードまたは置換文字列が不正
     * @static
     */
    public static function getMessage($code, $replacement = array()) {
        $class = get_class(self::$_class);
        if (defined($class . '::' . $code)) {
            $message = constant($class . '::' . $code);
            $replacement = is_array($replacement) ? $replacement : array($replacement);
            foreach ($replacement as &$replace) {
                if (defined($class . '::' . $replace)) {
                    $replace = constant($class . '::' . $replace);
                }
            }
            if ($result = @vsprintf($message, $replacement)) {
                return $result;
            }
            throw new MagicException(
                    self::getMessage('SYS008',
                            array($message, (empty($replacement) ? 'NOTHING' : implode(', ', $replacement)), $class,
                                    $code)));
        }
        throw new MagicException(self::getMessage('SYS009', array($code, $class)));
    }
}
// EOF.