"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 core_1 = require('@angular/core');
var dropdown_service_1 = require('./dropdown.service');
var DropdownDirective = (function () {
    function DropdownDirective(el, ref) {
        this.onToggle = new core_1.EventEmitter(false);
        this.isOpenChange = new core_1.EventEmitter(false);
        this.addClass = true;
        // @Query('dropdownMenu', {descendants: false})
        // dropdownMenuList:QueryList<ElementRef>) {
        this.el = el;
        this._changeDetector = ref;
        // todo: bind to route change event
    }
    Object.defineProperty(DropdownDirective.prototype, "isOpen", {
        get: function () {
            return this._isOpen;
        },
        set: function (value) {
            this._isOpen = !!value;
            // todo: implement after porting position
            // if (this.appendToBody && this.menuEl) {
            //
            // }
            // todo: $animate open<->close transitions, as soon as ng2Animate will be
            // ready
            if (this.isOpen) {
                this.focusToggleElement();
                dropdown_service_1.dropdownService.open(this);
            }
            else {
                dropdown_service_1.dropdownService.close(this);
                this.selectedOption = void 0;
            }
            this.onToggle.emit(this.isOpen);
            this.isOpenChange.emit(this.isOpen);
            this._changeDetector.markForCheck();
            // todo: implement call to setIsOpen if set and function
        },
        enumerable: true,
        configurable: true
    });
    DropdownDirective.prototype.ngOnInit = function () {
        this.autoClose = this.autoClose || dropdown_service_1.NONINPUT;
        if (this.isOpen) {
        }
    };
    DropdownDirective.prototype.ngOnDestroy = function () {
        if (this.appendToBody && this.menuEl) {
            this.menuEl.nativeElement.remove();
        }
    };
    Object.defineProperty(DropdownDirective.prototype, "dropDownMenu", {
        set: function (dropdownMenu) {
            // init drop down menu
            this.menuEl = dropdownMenu.el;
            if (this.appendToBody) {
                window.document.body.appendChild(this.menuEl.nativeElement);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DropdownDirective.prototype, "dropDownToggle", {
        set: function (dropdownToggle) {
            // init toggle element
            this.toggleEl = dropdownToggle.el;
        },
        enumerable: true,
        configurable: true
    });
    DropdownDirective.prototype.toggle = function (open) {
        return this.isOpen = arguments.length ? !!open : !this.isOpen;
    };
    DropdownDirective.prototype.focusDropdownEntry = function (keyCode) {
        // If append to body is used.
        var hostEl = this.menuEl ?
            this.menuEl.nativeElement :
            this.el.nativeElement.getElementsByTagName('ul')[0];
        if (!hostEl) {
            // todo: throw exception?
            return;
        }
        var elems = hostEl.getElementsByTagName('a');
        if (!elems || !elems.length) {
            // todo: throw exception?
            return;
        }
        // todo: use parseInt to detect isNumber?
        // todo: or implement selectedOption as a get\set pair with parseInt on set
        switch (keyCode) {
            case (40):
                if (typeof this.selectedOption !== 'number') {
                    this.selectedOption = 0;
                    break;
                }
                if (this.selectedOption === elems.length - 1) {
                    break;
                }
                this.selectedOption++;
                break;
            case (38):
                if (typeof this.selectedOption !== 'number') {
                    return;
                }
                if (this.selectedOption === 0) {
                    // todo: return?
                    break;
                }
                this.selectedOption--;
                break;
            default:
                break;
        }
        elems[this.selectedOption].focus();
    };
    DropdownDirective.prototype.focusToggleElement = function () {
        if (this.toggleEl) {
            this.toggleEl.nativeElement.focus();
        }
    };
    __decorate([
        core_1.HostBinding('class.open'),
        core_1.Input(), 
        __metadata('design:type', Boolean)
    ], DropdownDirective.prototype, "isOpen", null);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', String)
    ], DropdownDirective.prototype, "autoClose", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean)
    ], DropdownDirective.prototype, "keyboardNav", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Boolean)
    ], DropdownDirective.prototype, "appendToBody", void 0);
    __decorate([
        core_1.Output(), 
        __metadata('design:type', core_1.EventEmitter)
    ], DropdownDirective.prototype, "onToggle", void 0);
    __decorate([
        core_1.Output(), 
        __metadata('design:type', core_1.EventEmitter)
    ], DropdownDirective.prototype, "isOpenChange", void 0);
    __decorate([
        core_1.HostBinding('class.dropdown'), 
        __metadata('design:type', Boolean)
    ], DropdownDirective.prototype, "addClass", void 0);
    DropdownDirective = __decorate([
        core_1.Directive({ selector: '[dropdown]' }), 
        __metadata('design:paramtypes', [core_1.ElementRef, core_1.ChangeDetectorRef])
    ], DropdownDirective);
    return DropdownDirective;
}());
exports.DropdownDirective = DropdownDirective;
