"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var core_1 = require('@angular/core');
var config_1 = require('../../config/config');
var util_1 = require('../../util/util');
/**
  * @name Button
  * @module ionic
  *
  * @description
  * Buttons are simple components in Ionic. They can consist of text and icons
  * and be enhanced by a wide range of attributes.
  *
  * @property [outline] - A transparent button with a border.
  * @property [clear] - A transparent button without a border.
  * @property [round] - A button with rounded corners.
  * @property [block] - A button that fills its parent container with a border-radius.
  * @property [full] - A button that fills its parent container without a border-radius or borders on the left/right.
  * @property [small] - A button with size small.
  * @property [large] - A button with size large.
  * @property [disabled] - A disabled button.
  * @property [fab] - A floating action button.
  * @property [fab-left] - Position a fab button to the left.
  * @property [fab-right] - Position a fab button to the right.
  * @property [fab-center] - Position a fab button towards the center.
  * @property [fab-top] - Position a fab button towards the top.
  * @property [fab-bottom] - Position a fab button towards the bottom.
  * @property [fab-fixed] - Makes a fab button have a fixed position.
  * @property [color] - Dynamically set which predefined color this button should use (e.g. primary, secondary, danger, etc).
  *
  * @usage
  *
  * ```html
  *
  *  <!-- Colors -->
  *  <button ion-button>Default</button>
  *
  *  <button ion-button color="secondary">Secondary</button>
  *
  *  <button ion-button color="danger">Danger</button>
  *
  *  <button ion-button color="light">Light</button>
  *
  *  <button ion-button color="dark">Dark</button>
  *
  *  <!-- Shapes -->
  *  <button ion-button full>Full Button</button>
  *
  *  <button ion-button block>Block Button</button>
  *
  *  <button ion-button round>Round Button</button>
  *
  *  <button ion-button fab>FAB</button>
  *
  *  <!-- Outline -->
  *  <button ion-button full outline>Outline + Full</button>
  *
  *  <button ion-button block outline>Outline + Block</button>
  *
  *  <button ion-button round outline>Outline + Round</button>
  *
  *  <button ion-button fab outline>FAB</button>
  *
  *  <!-- Icons -->
  *  <button ion-button icon-left>
  *    <ion-icon name="star"></ion-icon>
  *    Left Icon
  *  </button>
  *
  *  <button ion-button icon-right>
  *    Right Icon
  *    <ion-icon name="star"></ion-icon>
  *  </button>
  *
  *  <button ion-button icon-only>
  *    <ion-icon name="star"></ion-icon>
  *  </button>
  *
  *  <!-- Sizes -->
  *  <button ion-button large>Large</button>
  *
  *  <button ion-button>Default</button>
  *
  *  <button ion-button small>Small</button>
  * ```
  *
  * @demo /docs/v2/demos/button/
  * @see {@link /docs/v2/components#buttons Button Component Docs}
 */
var Button = (function () {
    function Button(menuToggle, ionButton, config, _elementRef, _renderer) {
        this._elementRef = _elementRef;
        this._renderer = _renderer;
        /** @internal */
        this._role = 'button'; // bar-button
        /** @internal */
        this._mt = false; // menutoggle
        /** @internal */
        this._size = null; // large/small/default
        /** @internal */
        this._style = 'default'; // outline/clear/solid
        /** @internal */
        this._shape = null; // round/fab
        /** @internal */
        this._display = null; // block/full
        /** @internal */
        this._color = null; // primary/secondary
        /** @internal */
        this._disabled = false; // disabled
        var element = _elementRef.nativeElement;
        if (config.get('hoverCSS') === false) {
            _renderer.setElementClass(element, 'disable-hover', true);
        }
        if (element.hasAttribute('disabled')) {
            this._disabled = true;
        }
        if (ionButton.trim().length > 0) {
            this.setRole(ionButton);
        }
        // menuToggle can be added with or without a string
        // but if the attribute isn't added it will be null
        if (menuToggle !== null) {
            this._mt = true;
        }
    }
    Object.defineProperty(Button.prototype, "large", {
        /**
         * @input {string} Large button.
         */
        set: function (val) {
            this._attr('_size', 'large', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "small", {
        /**
         * @input {string} Small button.
         */
        set: function (val) {
            this._attr('_size', 'small', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "default", {
        /**
         * @input {string} Default button.
         */
        set: function (val) {
            this._attr('_size', 'default', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "outline", {
        /**
         * @input {string} A transparent button with a border.
         */
        set: function (val) {
            this._attr('_style', 'outline', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "clear", {
        /**
         * @input {string} A transparent button without a border.
         */
        set: function (val) {
            this._attr('_style', 'clear', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "solid", {
        /**
         * @input {string} Force a solid button. Useful for buttons within an item.
         */
        set: function (val) {
            this._attr('_style', 'solid', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "round", {
        /**
         * @input {string} A button with rounded corners.
         */
        set: function (val) {
            this._attr('_shape', 'round', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "fab", {
        /**
         * @input {string} A floating action button.
         */
        set: function (val) {
            this._attr('_shape', 'fab', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "block", {
        /**
         * @input {string} A button that fills its parent container with a border-radius.
         */
        set: function (val) {
            this._attr('_display', 'block', val);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Button.prototype, "full", {
        /**
         * @input {string} A button that fills its parent container without a border-radius or borders on the left/right.
         */
        set: function (val) {
            this._attr('_display', 'full', val);
        },
        enumerable: true,
        configurable: true
    });
    Button.prototype._attr = function (type, attrName, attrValue) {
        if (type === '_style') {
            this._setColor(this._color, util_1.isTrueProperty(attrValue));
        }
        this._setClass(this[type], false);
        if (util_1.isTrueProperty(attrValue)) {
            this[type] = attrName;
            this._setClass(attrName, true);
        }
        else {
            // Special handling for '_style' which defaults to 'default'.
            this[type] = (type === '_style' ? 'default' : null);
            this._setClass(this[type], true);
        }
    };
    Object.defineProperty(Button.prototype, "color", {
        /**
         * @input {string} Dynamically set which predefined color this button should use (e.g. primary, secondary, danger, etc).
         */
        set: function (val) {
            this._updateColor(val);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @private
     */
    Button.prototype.ngAfterContentInit = function () {
        this._init = true;
        this._assignCss(true);
    };
    /**
     * @internal
     */
    Button.prototype._updateColor = function (newColor) {
        this._setColor(this._color, false);
        this._setColor(newColor, true);
        this._color = newColor;
    };
    /**
     * @private
     */
    Button.prototype.addClass = function (className) {
        this._renderer.setElementClass(this._elementRef.nativeElement, className, true);
    };
    /**
     * @private
     */
    Button.prototype.setRole = function (val) {
        this._assignCss(false);
        this._role = val;
        this._assignCss(true);
    };
    /**
     * @internal
     */
    Button.prototype._assignCss = function (assignCssClass) {
        var role = this._role;
        if (role) {
            this._renderer.setElementClass(this._elementRef.nativeElement, role, assignCssClass); // button
            this._setClass('menutoggle', this._mt); // menutoggle
            this._setClass(this._style, assignCssClass); // button-clear
            this._setClass(this._shape, assignCssClass); // button-round
            this._setClass(this._display, assignCssClass); // button-full
            this._setClass(this._size, assignCssClass); // button-small
            this._setColor(this._color, assignCssClass); // button-secondary, bar-button-secondary
        }
    };
    /**
     * @internal
     */
    Button.prototype._setClass = function (type, assignCssClass) {
        if (type && this._init) {
            this._renderer.setElementClass(this._elementRef.nativeElement, this._role + '-' + type.toLowerCase(), assignCssClass);
        }
    };
    /**
     * @internal
     */
    Button.prototype._setColor = function (color, isAdd) {
        if (color && this._init) {
            // The class should begin with the button role
            // button, bar-button
            var className = this._role;
            // If the role is not a bar-button, don't apply the solid style
            var style = this._style;
            style = (this._role !== 'bar-button' && style === 'solid' ? 'default' : style);
            className += (style !== null && style !== '' && style !== 'default' ? '-' + style.toLowerCase() : '');
            if (color !== null && color !== '') {
                this._renderer.setElementClass(this._elementRef.nativeElement, className + "-" + color, isAdd);
            }
        }
    };
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "large", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "small", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "default", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "outline", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "clear", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "solid", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "round", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "fab", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "block", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean), 
        __metadata('design:paramtypes', [Boolean])
    ], Button.prototype, "full", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', String), 
        __metadata('design:paramtypes', [String])
    ], Button.prototype, "color", null);
    Button = __decorate([
        core_1.Component({
            selector: '[ion-button]',
            // NOTE: template must not contain spaces between elements
            template: '<span class="button-inner"><ng-content></ng-content></span><ion-button-effect></ion-button-effect>',
            changeDetection: core_1.ChangeDetectionStrategy.OnPush,
            encapsulation: core_1.ViewEncapsulation.None,
        }),
        __param(0, core_1.Attribute('menuToggle')),
        __param(1, core_1.Attribute('ion-button')), 
        __metadata('design:paramtypes', [String, String, config_1.Config, core_1.ElementRef, core_1.Renderer])
    ], Button);
    return Button;
}());
exports.Button = Button;
