# Source: composer/press-composer.info/sample/ui/square.reel/square.js

    /* global console */
    /**
     * @module ui/square.reel
     */
    var Component = require("montage/ui/component").Component,
        PressComposer = require("montage/composer/press-composer").PressComposer;

    /**
     * @class Square
     * @extends Component
     */
    var Square = exports.Square = Component.specialize(/** @lends Square# */ {

        __pressComposer: {
            value: null
        },

        _pressComposer: {
            get: function () {
                if (!this.__pressComposer) {
                    this.__pressComposer = new PressComposer();
                    this.addComposer(this.__pressComposer);
                }

                return this.__pressComposer;
            }
        },

        _state: {
            value: null
        },

        state: {
            get: function () {
                return this._state;
            },
            set: function (state) {
                if (state !== this._state) {
                    if (typeof state === "string" && state !== Square.PRESS_START_STATE) {
                        this._scheduleReset();
                    }

                    this._state = state;

                    this.needsDraw = true;
                }
            }
        },

        resetTimeout: {
            value: 200 // ms
        },

        _resetTimeoutID: {
            value: null
        },

        //lazy function
        _handleReset: {
            value: null
        },

        enterDocument: {
            value: function () {
                this._startListenToPressStartIfNeeded();
            }
        },

        exitDocument: {
            value: function () {
                this._stopListenToPressStartIfNeeded();
            }
        },

        prepareForActivationEvents: {
            value: function () {
                this._startListenToPressStartIfNeeded(true);
            }
        },

        handlePressStart: {
            value: function (event) {
                this.state = Square.PRESS_START_STATE;
                this._logEvent(event);

                this._addEventListeners();
            }
        },

        handlePressCancel: {
            value: function (event) {
                this.state = Square.PRESS_CANCEL_STATE;
                this._logEvent(event);

                this._removeEventListeners();
            }
        },

        handlePress: {
            value: function (event) {
                this.state = Square.PRESS_STATE;
                this._logEvent(event);

                this._removeEventListeners();
            }
        },

        _startListenToPressStartIfNeeded: {
            value: function (force) {
                if (force || this.preparedForActivationEvents) {
                    this._pressComposer.addEventListener("pressStart", this, false);
                }
            }
        },

        _stopListenToPressStartIfNeeded: {
            value: function () {
                if (this.preparedForActivationEvents) {
                    this._pressComposer.removeEventListener("pressStart", this, false);
                }
            }
        },

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

        _removeEventListeners: {
            value: function () {
                this._pressComposer.removeEventListener("press", this, false);
                this._pressComposer.removeEventListener("pressCancel", this, false);
            }
        },

        _scheduleReset: {
            value: function () {
                if (this._resetTimeoutID) {
                    clearTimeout(this._resetTimeoutID);
                    this._resetTimeoutID = null;
                }

                if (!this._handleReset) {
                    var handleReset = function () {
                        if (this.state !== Square.PRESS_START_STATE) {
                            this.state = null;
                            this._logEvent();
                        }
                    };

                    this._handleReset = handleReset.bind(this);
                }

                this._resetTimeoutID = setTimeout(this._handleReset, this.resetTimeout);
            }
        },

        _logEvent: {
            value: function (event) {
                console.log(this.identifier, event ? event.type : "reset");
            }
        },

        draw: {
            value: function () {
                if (this.state === Square.PRESS_START_STATE) {
                    this.classList.remove(Square.PRESS_CANCEL_STATE);
                    this.classList.remove(Square.PRESS_STATE);
                    this.classList.add(Square.PRESS_START_STATE);

                } else if (this.state === Square.PRESS_CANCEL_STATE) {
                    this.classList.remove(Square.PRESS_START_STATE);
                    this.classList.remove(Square.PRESS_STATE);
                    this.classList.add(Square.PRESS_CANCEL_STATE);

                } else if (this.state === Square.PRESS_STATE) {
                    this.classList.remove(Square.PRESS_CANCEL_STATE);
                    this.classList.remove(Square.PRESS_START_STATE);
                    this.classList.add(Square.PRESS_STATE);

                } else {
                    this.classList.remove(Square.PRESS_START_STATE);
                    this.classList.remove(Square.PRESS_STATE);
                    this.classList.remove(Square.PRESS_CANCEL_STATE);
                }
            }
        }

    }, {

        PRESS_START_STATE: {
            value: "active"
        },

        PRESS_CANCEL_STATE: {
            value: "canceled"
        },

        PRESS_STATE: {
            value: "pressed"
        }

    });