/**
 * @file Button组件。
 * @module GMU
 * @import core/widget.js, extend/highlight.js
 * @importCss icons.css
 */
(function( gmu, $, undefined ) {

    /**
     * Button组件。支持icon, icon位置设置。
     *
     * [![Live Demo](qrcode:http://gmu.baidu.com/demo/widget/button/button.html)](http://gmu.baidu.com/demo/widget/button/button.html "Live Demo")
     *
     * @class Button
     * @constructor
     * html部分, 可以是以下任意dom实例化button
     * ```html
     * <a class="btn">按钮</a>
     * <span class="btn">按钮</span>
     * <button class="btn">按钮</button>
     * <input class="btn" type="button" value="按钮" />
     * <input class="btn" type="reset" value="按钮" />
     * <input class="btn" type="button" value="按钮" />
     * ```
     *
     * Javascript部分
     * ```javascript
     * $( '.btn' ).button();
     * ```
     *
     * 如果希望支持checkbox radio按钮，请查看[input插件](#GMU:Button.input)。
     * @grammar new gmu.Button( el[, options]) => instance
     * @grammar $( el ).button([ options ]) => zepto
     */
    gmu.define( 'Button', {
        options: {

            /**
             * @property {String} [label] 按钮文字。
             * @namespace options
             */

            /**
             * @property {String} [icon] 图标名称。系统提供以下图标。home, delete, plus, arrow-u, arrow-d, check, gear, grid, star, arrow-r, arrow-l, minus, refresh, forward, back, alert, info, search,
             * @namespace options
             */

            /**
             * @property {String} [iconpos] 图片位置。支持：left, right, top, bottom, notext.
             * @namespace options
             */
            iconpos: 'left'

            /**
             * @property {String} [state]
             * @description 设置初始状态。如果状态值为`disbaled`，按钮将不可点击。
             * @namespace options
             */

            /**
             * @property {String} [{$state}Text]
             * @description 设置对应状态文字，当button进入此状态时，按钮将显示对应的文字。
             * @namespace options
             */
        },

        template: {
            icon: '<span class="ui-icon ui-icon-<%= name %>"></span>',
            text: '<span class="ui-btn-text"><%= text %></span>'
        },

        _getWrap: function( $el ) {
            return $el;
        },

        _init: function(){
            var me = this;

            me.$el = me.$el === undefined ? $('<span/>').appendTo( document.body ) : me.$el;
        },

        _create: function() {
            var me = this,
                opts = me._options,
                $wrap = me.$wrap = me._getWrap( me.getEl() ),
                input = $wrap.is( 'input' ),
                $label = $wrap.find( '.ui-btn-text' ),
                $icon = $wrap.find( '.ui-icon' );

            // 处理label
            // 如果是空字符串，则表示dom中写了data-label=""
            opts.label = opts.label === undefined ? $wrap[ input ? 'val' : 'text' ]() : opts.label;
            input || opts.label === undefined || !$label.length && ($label = $( me.tpl2html( 'text', {
                text: opts.label
            } ) )).appendTo( $wrap.empty() );
            me.$label = $label.length && $label;
            opts.resetText = opts.resetText || opts.label;

            // 如果传入了icon而dom中没有，则创建
            input || opts.icon && !$icon.length && ($icon = $( me.tpl2html( 'icon', {
                name: opts.icon
            } ) )).appendTo( $wrap );
            me.$icon = $icon.length && $icon;

            $wrap.addClass( 'ui-btn ' + (opts.label && opts.icon ?
                    'ui-btn-icon-' + opts.iconpos : opts.label ?
                    'ui-btn-text-only' : 'ui-btn-icon-only') );

            opts.state && setTimeout( function(){
                me.state( opts.state );
            }, 0 );
        },

        /**
         * 设置或者获取按钮状态值。
         *
         * 如果传入的state为"disabled", 此按钮将变成不可点击状态。
         *
         * ```javascript
         * // 初始化的时候可以给diabled状态设置Text
         * var btn = $( '#btn' ).button({
         *     disabledText: '不可点'
         * });
         *
         * // 按钮将变成不可点击状态。同时文字也变成了”不可点“
         * btn.button( 'state', 'disabled' );
         *
         * // 还原按钮状态
         * // 文字也还原。
         * btn.button( 'state', 'reset' );
         *
         * ```
         * @method state
         * @grammar state( value ) => self
         * @grammar state() => String
         * @param  {String} [state] 状态值。
         * @return {String} 当没有传入state值时，此方法行为为getter, 返回当前state值。
         * @return {self} 当传入了state值时，此方法行为为setter, 返回实例本身，方便链式调用。
         */
        state: function( state ) {

            // getter
            if ( state === undefined ) {
                return this._state;
            }

            // setter
            var me = this,
                $wrap = me.$wrap,
                input = $wrap.is( 'input' ),
                text = me._options[ state + 'Text' ];

            me.$wrap.removeClass( 'ui-state-' + me._state )
                    .addClass( 'ui-state-' + state );

            text === undefined || (input ? $wrap : me.$label)[ input ?
                    'val' : 'text' ]( text );

            me._state !== state && me.trigger( 'statechange', state, me._state );
            me._state = state;
            return me;
        },

        /**
         * 切换按钮选中状态
         * @method toggle
         * @grammar toggle() => self
         * @example
         * var btn = $( '#btn' );
         *
         * btn.on( 'click', function() {
         *     btn.button( 'toggle' );
         * } );
         */
        toggle: function() {
            this.state( this._state === 'active' ? 'reset' : 'active' );
            return this;
        }

        /**
         * @event ready
         * @param {Event} e gmu.Event对象
         * @description 当组件初始化完后触发。
         */

        /**
         * @event statechange
         * @param {Event} e gmu.Event对象
         * @param {String} state 当前state值
         * @param {String} preState 前一次state的值
         * @description 当组件状态变化时触发。
         */

        /**
         * @event destroy
         * @param {Event} e gmu.Event对象
         * @description 当组件被销毁的时候触发。
         */
    } );

    // dom ready
    $(function() {

        // 按下态。
        $( document.body ).highlight( 'ui-state-hover', '.ui-btn:not(.ui-state-disabled)' );
    });
})( gmu, gmu.$ );