# Source: ui/base/abstract-toggle-switch.js

    /*global require, exports*/

    /**
     * @module montage/ui/base/abstract-toggle-switch.reel
     * @requires montage/composer/press-composer
    */
    var AbstractControl = require("./abstract-control").AbstractControl,
        PressComposer = require("../../composer/press-composer").PressComposer;

    /**
     * @class AbstractToggleSwitch
     * @extends AbstractControl
     * @fires AbstractToggleSwitch#action
     */
    var AbstractToggleSwitch = exports.AbstractToggleSwitch = AbstractControl.specialize( /** @lends AbstractToggleSwitch# */ {

        /**
         * Dispatched when the switch is toggled through a mouse click, finger tap,
         * or when focused and the spacebar is pressed.
         * @event action
         * @memberof AbstractToggleSwitch
         * @property {Map} detail - The detail object as defined in {@link AbstractControl#detail}
         */

        constructor: {
            value: function AbstractToggleSwitch() {
                if(this.constructor === AbstractToggleSwitch) {
                    throw new Error("AbstractToggleSwitch cannot be instantiated.");
                }

                this._pressComposer = new PressComposer();
                this.addComposer(this._pressComposer);

                this.defineBindings({
                    "classList.has('montage-ToggleSwitch--checked')": {
                        "<-": "checked"
                    },
                    "classList.has('montage--disabled')": {
                        "<-": "!enabled"
                    }
                });
            }
        },

        _enabled: {
            value: true
        },

        /**
         * Enables or disables the toggle switch from user input. When this
         * property is set to `false`, the "montage--disabled" CSS style is applied
         * to the button's DOM element during the next draw cycle. When set to
         * `true` the "montage--disabled" CSS class is removed from the element's
         * class list.
         * @type {boolean}
         */
        enabled: {
            get: function () {
                return this._enabled;
            },
            set: function (value) {
                this._enabled = value;
                this.needsDraw = true;
            }
        },

        acceptsActiveTarget: {
            value: function () {
                return this.enabled;
            }
        },

        _pressComposer: {
            value: null
        },

        _checked: {
            value: false
        },

        checked: {
            get: function () {
                return this._checked;
            },
            set: function (value) {
                this._checked = value;
                this.needsDraw = true;
            }
        },

        prepareForActivationEvents: {
            value: function () {
                this._pressComposer.addEventListener("press", this, false);
            }
        },

        /**
         * Called when the user has interacted with the toggle switch.
         * @private
         */
        handlePress: {
            value: function (event) {
                if(!this.enabled) {
                    return;
                }

                this.checked = !this.checked;
                this.dispatchActionEvent();
            }
        },

        handleKeyup: {
            value: function (event) {
                if(!this.enabled) {
                    return;
                }

                // action event on spacebar
                if (event.keyCode === 32) {
                    this.checked = !this.checked;
                    this.dispatchActionEvent();
                }
            }
        },

        enterDocument: {
            value: function (firstDraw) {
                this.element.setAttribute("role", "checkbox");
                this.element.addEventListener("keyup", this, false);
            }
        },

        draw: {
            value: function () {
                this.element.setAttribute("aria-checked", this._checked);
                this.element.setAttribute("aria-disabled", !this._enabled);
            }
        }

    });