/**
 * SpeechUI 入口模块
 * @module speechui
 * @author yuwang@iflytek.com
 * @date 2013/06/09
 */
define(function (require, exports, module) {

    var _define = require('./code/define');

    /**
     * 卡片模块状态
     */
    var CardModuleState = {
        NotLoad: 0,
        Loading: 1,
        Loaded: 2
    }

    /**
     *
     * @param {卡片名称} cardName
     * @constructor
     */
    function CardModuleMeta(cardName) {
        /** @type {string} */
        this.name = cardName;

        /** @type {CardBase} */
        this.module = null;

        /** @type {Array.<*>} */
        this.pendding = [];

        /** @type {CardModuleState | number} */
        this.state = CardModuleState.NotLoad
    }

    // 卡片模块元数据定义
    var _cardModuleMetas = {};

    /**
     *
     * @param {CardModuleMeta} cardModuleMeta
     * @param module
     */
    function cardModuleLoadCallback(cardModuleMeta, module) {
        cardModuleMeta.module = module;
        cardModuleMeta.state = CardModuleState.Loaded;

        var pendding = cardModuleMeta.pendding;
        while (pendding.length > 0) {
            var options = pendding.shift();
            loadCard(cardModuleMeta.name, module, options);
        }
    }

    /**
     *
     * @param  {*} module
     * @param options
     * @return {CardBase}
     */
    function loadCard(cardName, module, options) {
        var card;
        if (cardName === _define.CardName.EnWordEval) {
            card = new module.Constructor();
            card.init(options);
        } else {
            card = new module.Constructor(options);
        }
        return card;
    }

    /**
     * 初始化SpeechUI
     * @export
     * @param {Array.<speechui.define.CardName>} 卡片列表
     */
    exports.init = function (cards) {
        if (cards instanceof Array) {
            for (var i = 0; i < cards.length; i++) {
                var cardName = cards[i];
                var cardMeta = _cardModuleMetas[cardName];
                if (!cardMeta) {
                    _cardModuleMetas[cardName] = cardMeta = new CardModuleMeta(cardName);
                }

                if (cardMeta.state !== CardModuleState.NotLoad) {
                    break;
                } else {
                    (function (cardMeta) {
                        cardMeta.state = CardModuleState.Loading;
                        switch (cardName) {
                            case _define.CardName.Gallery:
                                require.async('./code/cards/gallery', function (gallery) {
                                    cardModuleLoadCallback(cardMeta, gallery);
                                });
                                break;
                            case _define.CardName.CnWordEval:
                                require.async('./code/cards/cnwordeval', function (cnwordeval) {
                                    cardModuleLoadCallback(cardMeta, cnwordeval);
                                });
                                break;
                            case _define.CardName.EnWordEval:
                                require.async('./code/cards/enwordeval', function (enwordeval) {
                                    cardModuleLoadCallback(cardMeta, enwordeval);
                                });
                                break;
                            case _define.CardName.Poetry:
                                require.async('./code/cards/poetry', function (poetry) {
                                    cardModuleLoadCallback(cardMeta, poetry);
                                });
                                break;
                            case _define.CardName.Situ:
                                require.async('./code/cards/dialogue', function (dialogue) {
                                    cardModuleLoadCallback(cardMeta, dialogue);
                                });
                                break;
                            default:
                                throw new Error('unknown card name:' + cardName);
                        }
                    })(cardMeta)
                }
            }
        }
        else {
            throw new Error('cards is not instance of Array');
        }
    };

    /**
     * 加载卡片
     * @param {speechui.define.CardName}   卡片名称
     * @param {Object} options 初始化参数
     */
    exports.loadCard = function (cardName, options) {
        var cardModuleMeta = _cardModuleMetas[cardName];
        if (cardModuleMeta.state === CardModuleState.NotLoad) {
            throw new Error(cardName + ' card  is not initialized');
        } else if (cardModuleMeta.state === CardModuleState.Loading) {
            cardModuleMeta.pendding.push(options);
        } else {
            loadCard(cardModuleMeta.name, cardModuleMeta.module, options);
        }
    };
});