goog.provide('lime.Button');

goog.require('lime.Layer');

/**
 * Simple button element
 * @param {lime.Sprite} opt_upstate Object shown on normal state.
 * @param {lime.Sprite} opt_downstate Object show when button is pressed.
 * @constructor
 * @extends lime.Layer
 */
lime.Button = function(opt_upstate, opt_downstate) {
    lime.Layer.call(this);

    this.domClassName = goog.getCssName('lime-button');

    //set up state
    if (goog.isDef(opt_upstate)) {
        this.setUpState(opt_upstate);
    }

    //set down state
    if (goog.isDef(opt_downstate)) {
        this.setDownState(opt_downstate);
    }


    var t = this;
    goog.events.listen(this, ['mousedown', 'touchstart', 'touchmove'],
        function(e) {
            t.setState(lime.Button.State.DOWN);
            e.swallow('mousemove', function(e) {
                if (t.hitTest(e)) {
                    t.setState(lime.Button.State.DOWN);
                }
                else {
                    t.setState(lime.Button.State.UP);
                }
            });
            e.swallow('touchmove', function(e) {
                if (!t.hitTest(e)) {
                    t.setState(lime.Button.State.UP);
                    e.release();
                }
            });
            e.swallow(['mouseup', 'touchend'], function(e) {
                if (t.hitTest(e)) {
                    t.dispatchEvent({type: lime.Button.Event.CLICK});
               }
               this.setState(lime.Button.State.UP);
           });
        }
    );


};
goog.inherits(lime.Button, lime.Layer);

/**
 * Button states
 * @enum {number}
 */
lime.Button.State = {
    UP: 0,
    DOWN: 1
};

/**
 * Button event names
 * @enum {string}
 */
lime.Button.Event = {
    UP: 'up',
    DOWN: 'down',
    CLICK: 'click' // touchUpInside?
};

/**
 * Sets the sprite used as button up state
 * @param {lime.Sprite} upstate Object shown on normal state.
 * @return {lime.Button} object itself.
 */
lime.Button.prototype.setUpState = function(upstate) {
    this.upstate = upstate;
    this.appendChild(this.upstate);

    this.state_ = -1;
    return this.setState(lime.Button.State.UP);
};

/**
 * Sets the sprite used as button down state. Down state is hown if
 * mouse is down on button or finger is touching the button.
 * @param {lime.Sprite} downstate Object shown when button is pressed.
 * @return {lime.Button} object itself.
 */
lime.Button.prototype.setDownState = function(downstate) {
    this.downstate = downstate;
    this.appendChild(downstate);

    this.state_ = -1;
    return this.setState(lime.Button.State.UP);
};


/**
 * Returns current state of the button
 * @return {lime.Button.State} current state.
 */
lime.Button.prototype.getState = function() {
    return this.state_;
};


/**
 * Sets the state of the button. Also fires events is state changes.
 * @param {lime.Button.State} value State to be set.
 * @return {lime.Button} object itself.
 */
lime.Button.prototype.setState = function(value) {

    if (value == this.state_) return this;

    //event checking
    if (this.state_ == lime.Button.State.UP &&
            value == lime.Button.State.DOWN)
        this.dispatchEvent({type: lime.Button.Event.DOWN});

    if (this.state_ == lime.Button.State.DOWN &&
            value == lime.Button.State.UP)
        this.dispatchEvent({type: lime.Button.Event.UP});


    var state = this.upstate;

    if (goog.isDef(this.downstate)) {
        if (lime.Button.State.DOWN == value)
            state = this.downstate;
        else
            this.downstate.setHidden(true);
    }

    if (state != this.upstate) {
        this.upstate.setHidden(true);
    }

    state.setHidden(false);
    this.state_ = value;
    return this;
};

@@ -2752,24 +2752,231 @@
 state_;%0A%7D;%0A%0A
+/**%0A * @inheritDoc%0A */%0Alime.Button.prototype.hitTest = function(e) %7B%0A  if (e.type == 'click') return false // clicks have emulated through other events%0A  return lime.Layer.prototype.hitTest.call(this, e)%0A%7D;%0A
 %0A/**%0A * Sets

Fix button double click event