include('../view.js');
include('observable.js');

/**
 * @class
 */
uki.view.Focusable = new function() {/** @lends uki.view.Focusable.prototype */ 
    
    // dom: function() {
    //     return null; // should implement
    // },
    this._focusable = true; // default value
    this._focusOnClick = true;
    
    this.focusOnClick = uki.newProp('_focusOnClick');
    
    this.focusable = uki.newProp('_focusable', function(v) {
        this._focusable = v;
        if (v) this._initFocusable();
        this._updateFocusable();
    }),
    
    this.disabled = uki.newProp('_disabled', function(d) {
        this._disabled = d;
        if (d) this.blur();
        this._updateFocusable();
        if (this._updateBg) this._updateBg();
    }),
    
    this._updateFocusable = function() {
        if (this._preCreatedFocusTarget) return;
        
        if (this._focusable && !this._disabled) {
            this._focusTarget.style.display = 'block';
        } else {
            this._focusTarget.style.display = 'none';
        }
    }, 
    
    this._initFocusable = function(preCreatedFocusTarget) {
        if ((!preCreatedFocusTarget && !this._focusable) || this._focusTarget) return;
        this._focusTarget = preCreatedFocusTarget;
        this._preCreatedFocusTarget = preCreatedFocusTarget;
        
        if (!preCreatedFocusTarget) {
            this._focusTarget = uki.createElement('input', 'position:absolute;left:-9999px;top:0;width:1px;height:1px;');
            this.dom().appendChild(this._focusTarget);
        }
        this._hasFocus = false;
        this._firstFocus = true;
            
        uki.dom.bind(this._focusTarget, 'focus', uki.proxy(function(e) {
            if (!this._hasFocus) this._focus(e);
        }, this));
        
        uki.dom.bind(this._focusTarget, 'blur', uki.proxy(function(e) {
            if (this._hasFocus) {
                this._hasFocus = false;
                setTimeout(uki.proxy(function() { // wait for mousedown refocusing
                    if (!this._hasFocus) this._blur(e);
                }, this),1);
            }
        }, this));
        
        if (!preCreatedFocusTarget) this.bind('mousedown', function(e) {
            if (this._focusOnClick) {
                if (this._focusable && !this._disabled && !this._hasFocus) this._focus();
                setTimeout(uki.proxy(this.focus, this), 1);
            }
        });
        this._updateFocusable();
    }
    
    this._focus = function(e) {
        this._hasFocus = true;
        this._firstFocus = false;
    }
    
    this._blur = function(e) {
        this._hasFocus = false;
    }
    
    this.focus = function() {
        try {
            if (this._focusable && !this._disabled) {
                this._focusTarget.focus();
            }
        } catch(e) {}
        return this;
    },
    
    this.blur = function() {
        try {
            this._focusTarget.blur();
        } catch(e) {}
        return this;
    }
    
    this.hasFocus = function() {
        return this._hasFocus;
    }
    
    this._bindToDom = function(name) {
        if (!this._focusTarget || 'keyup keydown keypress focus blur'.indexOf(name) == -1) return false;

        return uki.view.Observable._bindToDom.call(this, name, this._focusTarget);
    }
    

};
@@ -595,24 +595,70 @@
 nction(d) %7B%0A
+        var changed = d !== !!this._disabled;%0A
         this
@@ -673,16 +673,16 @@
 ed = d;%0A
-
         
@@ -742,24 +742,35 @@
         if (
+changed && 
 this._update
@@ -837,32 +837,32 @@
  = function() %7B%0A
-
         if (this
@@ -876,32 +876,54 @@
 eatedFocusTarget
+ %7C%7C !this._focusTarget
 ) return;%0A      
@@ -2155,20 +2155,21 @@
 , this),
+ 
 1);%0A
-
         
@@ -2315,173 +2315,21 @@
 ck) 
-%7B%0A                if (this._focusable && !this._disabled && !this._hasFocus) this._focus();%0A                setTimeout(uki.proxy(this.focus, this), 1);%0A            %7D
+this.focus();
 %0A   
@@ -2661,68 +2661,125 @@
 bled
-) %7B%0A                this._focusTarget.focus();%0A            %7D
+ && !this._hasFocus) this._focus();%0A            setTimeout(uki.proxy(this._focusTarget.focus, this._focusTarget), 1);
 %0A   

update bg only if disabled changed, moved focusing code to focus