import { Component, Optional, ElementRef, EventEmitter, Input, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
import { NgControl } from '@angular/forms';
import { App } from '../app/app';
import { Config } from '../../config/config';
import { Content } from '../content/content';
import { DomController } from '../../util/dom-controller';
import { Form } from '../../util/form';
import { InputBase } from './input-base';
import { isTrueProperty } from '../../util/util';
import { Item } from '../item/item';
import { NativeInput, NextInput } from './native-input';
import { NavController } from '../../navigation/nav-controller';
import { Platform } from '../../platform/platform';
/**
 * @name Input
 * @description
 *
 * `ion-input` is meant for text type inputs only, such as `text`,
 * `password`, `email`, `number`, `search`, `tel`, and `url`. Ionic
 * still uses an actual `<input type="text">` HTML element within the
 * component, however, with Ionic wrapping the native HTML input
 * element it's able to better handle the user experience and
 * interactivity.
 *
 * Similarily, `<ion-textarea>` should be used in place of `<textarea>`.
 *
 * An `ion-input` is **not** used for non-text type inputs, such as a
 * `checkbox`, `radio`, `toggle`, `range`, `select`, etc.
 *
 *
 * @usage
 * ```html
 * <ion-list>
 *   <ion-item>
 *     <ion-label color="primary">Inline Label</ion-label>
 *     <ion-input placeholder="Text Input"></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-label color="primary" fixed>Fixed Label</ion-label>
 *     <ion-input type="tel" placeholder="Tel Input"></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-input type="number" placeholder="Number Input with no label"></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-label color="primary" stacked>Stacked Label</ion-label>
 *     <ion-input type="email" placeholder="Email Input"></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-label color="primary" stacked>Stacked Label</ion-label>
 *     <ion-input type="password" placeholder="Password Input"></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-label color="primary" floating>Floating Label</ion-label>
 *     <ion-input></ion-input>
 *   </ion-item>
 *
 *   <ion-item>
 *     <ion-input placeholder="Clear Input" clearInput></ion-input>
 *   </ion-item>
 * </ion-list>
 * ```
 *
 * @demo /docs/v2/demos/src/input/
 */
export class TextInput extends InputBase {
    constructor(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl, dom) {
        super(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl, dom);
        /**
         * @private
         */
        this._clearInput = false;
        /**
         * @input {string} The placeholder for the input
         */
        this.placeholder = '';
        /**
         * @output {event} Expression to call when the input no longer has focus
         */
        this.blur = new EventEmitter();
        /**
         * @output {event} Expression to call when the input has focus
         */
        this.focus = new EventEmitter();
        this.mode = config.get('mode');
    }
    /**
     * @input {bool} A clear icon will appear in the input when there is a value. Clicking it clears the input.
     */
    get clearInput() {
        return this._clearInput;
    }
    set clearInput(val) {
        this._clearInput = isTrueProperty(val);
    }
    /**
     * @input {string} The text value of the input
     */
    get value() {
        return this._value;
    }
    set value(val) {
        super.setValue(val);
    }
    /**
     * @input {string} The HTML input type (text, password, email, number, search, tel, or url)
     */
    get type() {
        return this._type;
    }
    set type(val) {
        super.setType(val);
    }
    /**
     * @input {bool} If the input should be disabled or not
     */
    get disabled() {
        return this._disabled;
    }
    set disabled(val) {
        super.setDisabled(val);
    }
    /**
     * @input {string} The mode to apply to this component.
     */
    set mode(val) {
        this._setMode(val);
    }
    /**
     * @input {boolean} whether to clear the input upon editing or not
     */
    get clearOnEdit() {
        return this._clearOnEdit;
    }
    set clearOnEdit(val) {
        super.setClearOnEdit(val);
    }
    /**
     * @private
     */
    set _nativeInput(nativeInput) {
        super.setNativeInput(nativeInput);
    }
    /**
     * @private
     */
    set _nextInput(nextInput) {
        super.setNextInput(nextInput);
    }
    /**
     * @private
     */
    inputBlurred(ev) {
        this.blur.emit(ev);
    }
    /**
     * @private
     */
    inputFocused(ev) {
        this.focus.emit(ev);
    }
    /**
     * @private
     */
    ngOnInit() {
        if (this._item) {
            this._item.setElementClass('item-input', true);
            this._item.registerInput(this._type);
        }
        // By default, password inputs clear after focus when they have content
        if (this.type === 'password' && this.clearOnEdit !== false) {
            this.clearOnEdit = true;
        }
    }
    /**
     * @private
     */
    ngAfterContentChecked() {
        this.setItemInputControlCss();
    }
    /**
     * @private
     */
    ngOnDestroy() {
        this._form.deregister(this);
        this._scrollStart.unsubscribe();
        this._scrollEnd.unsubscribe();
    }
    /**
     * @private
     */
    clearTextInput() {
        (void 0) /* console.debug */;
        this._value = '';
        this.onChange(this._value);
        this.writeValue(this._value);
    }
}
TextInput.decorators = [
    { type: Component, args: [{
                selector: 'ion-input',
                template: '<input [type]="type" [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input" [ngClass]="\'text-input-\' + _mode">' +
                    '<input [type]="type" aria-hidden="true" next-input *ngIf="_useAssist">' +
                    '<button ion-button clear [hidden]="!clearInput" type="button" class="text-input-clear-icon" (click)="clearTextInput()" (mousedown)="clearTextInput()"></button>' +
                    '<div (touchstart)="pointerStart($event)" (touchend)="pointerEnd($event)" (mousedown)="pointerStart($event)" (mouseup)="pointerEnd($event)" class="input-cover" tappable *ngIf="_useAssist"></div>',
                encapsulation: ViewEncapsulation.None,
            },] },
];
/** @nocollapse */
TextInput.ctorParameters = [
    { type: Config, },
    { type: Form, },
    { type: Item, decorators: [{ type: Optional },] },
    { type: App, },
    { type: Platform, },
    { type: ElementRef, },
    { type: Renderer, },
    { type: Content, decorators: [{ type: Optional },] },
    { type: NavController, decorators: [{ type: Optional },] },
    { type: NgControl, decorators: [{ type: Optional },] },
    { type: DomController, },
];
TextInput.propDecorators = {
    'placeholder': [{ type: Input },],
    'clearInput': [{ type: Input },],
    'value': [{ type: Input },],
    'type': [{ type: Input },],
    'disabled': [{ type: Input },],
    'mode': [{ type: Input },],
    'clearOnEdit': [{ type: Input },],
    '_nativeInput': [{ type: ViewChild, args: [NativeInput,] },],
    '_nextInput': [{ type: ViewChild, args: [NextInput,] },],
    'blur': [{ type: Output },],
    'focus': [{ type: Output },],
};
/**
 * @name TextArea
 * @description
 *
 * `ion-textarea` is is used for multi-line text inputs. Ionic still
 * uses an actual `<textarea>` HTML element within the component;
 * however, with Ionic wrapping the native HTML text area element, Ionic
 * is able to better handle the user experience and interactivity.
 *
 * Note that `<ion-textarea>` must load its value from the `value` or
 * `[(ngModel)]` attribute. Unlike the native `<textarea>` element,
 * `<ion-textarea>` does not support loading its value from the
 * textarea's inner content.
 *
 * When requiring only a single-line text input, we recommend using
 * `<ion-input>` instead.
 *
 * @usage
 * ```html
 *  <ion-item>
 *    <ion-label>Comments</ion-label>
 *    <ion-textarea></ion-textarea>
 *  </ion-item>
 *
 *  <ion-item>
 *    <ion-label stacked>Message</ion-label>
 *    <ion-textarea [(ngModel)]="msg"></ion-textarea>
 *  </ion-item>
 *
 *  <ion-item>
 *    <ion-label floating>Description</ion-label>
 *    <ion-textarea></ion-textarea>
 *  </ion-item>
 *
 * <ion-item>
 *    <ion-label>Long Description</ion-label>
 *    <ion-textarea rows="6" placeholder="enter long description here..."></ion-textarea>
 *  </ion-item>
 * ```
 *
 * @demo /docs/v2/demos/src/textarea/
 */
export class TextArea extends InputBase {
    constructor(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl, dom) {
        super(config, form, item, app, platform, elementRef, renderer, scrollView, nav, ngControl, dom);
        /**
         * @input {string} The placeholder for the textarea
         */
        this.placeholder = '';
        /**
         * @output {event} Expression to call when the textarea no longer has focus
         */
        this.blur = new EventEmitter();
        /**
         * @output {event} Expression to call when the textarea has focus
         */
        this.focus = new EventEmitter();
        this.mode = config.get('mode');
    }
    /**
     * @input {string} The value of the textarea
     */
    get value() {
        return this._value;
    }
    set value(val) {
        super.setValue(val);
    }
    /**
     * @input {bool} Whether the textarea should be disabled or not
     */
    get disabled() {
        return this._disabled;
    }
    set disabled(val) {
        super.setDisabled(val);
    }
    /**
     * @input {string} The mode to apply to this component.
     */
    set mode(val) {
        this._setMode(val);
    }
    /**
     * @private
     */
    set _nativeInput(nativeInput) {
        super.setNativeInput(nativeInput);
    }
    /**
     * @private
     */
    set _nextInput(nextInput) {
        super.setNextInput(nextInput);
    }
    /**
     * @private
     */
    ngOnInit() {
        if (this._item) {
            this._item.setElementClass('item-textarea', true);
            this._item.setElementClass('item-input', true);
            this._item.registerInput(this._type);
        }
    }
    /**
     * @private
     */
    ngAfterContentChecked() {
        this.setItemInputControlCss();
    }
    /**
     * @private
     */
    ngOnDestroy() {
        this._form.deregister(this);
        this._scrollStart.unsubscribe();
        this._scrollEnd.unsubscribe();
    }
    /**
     * @private
     */
    inputBlurred(ev) {
        this.blur.emit(ev);
    }
    /**
     * @private
     */
    inputFocused(ev) {
        this.focus.emit(ev);
    }
}
TextArea.decorators = [
    { type: Component, args: [{
                selector: 'ion-textarea',
                template: '<textarea [(ngModel)]="_value" (blur)="inputBlurred($event)" (focus)="inputFocused($event)" [placeholder]="placeholder" class="text-input" [ngClass]="\'text-input-\' + _mode"></textarea>' +
                    '<input type="text" aria-hidden="true" next-input *ngIf="_useAssist">' +
                    '<div (touchstart)="pointerStart($event)" (touchend)="pointerEnd($event)" (mousedown)="pointerStart($event)" (mouseup)="pointerEnd($event)" class="input-cover" tappable *ngIf="_useAssist"></div>',
                encapsulation: ViewEncapsulation.None,
            },] },
];
/** @nocollapse */
TextArea.ctorParameters = [
    { type: Config, },
    { type: Form, },
    { type: Item, decorators: [{ type: Optional },] },
    { type: App, },
    { type: Platform, },
    { type: ElementRef, },
    { type: Renderer, },
    { type: Content, decorators: [{ type: Optional },] },
    { type: NavController, decorators: [{ type: Optional },] },
    { type: NgControl, decorators: [{ type: Optional },] },
    { type: DomController, },
];
TextArea.propDecorators = {
    'placeholder': [{ type: Input },],
    'value': [{ type: Input },],
    'disabled': [{ type: Input },],
    'mode': [{ type: Input },],
    '_nativeInput': [{ type: ViewChild, args: [NativeInput,] },],
    '_nextInput': [{ type: ViewChild, args: [NextInput,] },],
    'blur': [{ type: Output },],
    'focus': [{ type: Output },],
};
//# sourceMappingURL=input.js.map