ctlClientButton = _ctlCreateClass(ctlClientControl, {
    constructor: function(name) {    
        this.constructor.prototype.constructor.call(this, name);
        
        this.allowFocus = true;
        this.autoPostBackFunction = null;
        this.causesValidation = true;                
        this.enabled = true;
        this.checked = false;
        this.groupName = "";            
        this.focused = false;
        this.focusElementSelected = false;
        this.isNative = false;                            
        this.pressed = false;        
        this.validationGroup = "";           
        
        this.buttonCell = null;
        this.contentDiv = null;
        this.checkedInput = null;
        this.buttonImage = null;                 
        this.internalButton = null;        
        this.textElement = null; 
        this.textControl = null;

        this.CheckedChanged = new ctlClientEvent();        
        this.GotFocus = new ctlClientEvent();
        this.LostFocus = new ctlClientEvent();
        this.Click = new ctlClientEvent();                                                              
    },    
	Initialize: function(){	
	    this.constructor.prototype.Initialize.call(this);
        this.InitializeEvents();
        this.SetEnabledInternal(this.enabled, true);
        this.SetCheckedInternal(this.checked, true);
        if (!this.isNative) {
	        this.AttachNativeHandlerToMainElement("focus", "SetFocus");
	        this.AttachNativeHandlerToMainElement("click", "OnClick");
	    }
    },
    AttachNativeHandlerToMainElement: function(handlerName, correspondingMethodName) {
        var mainElement = this.GetMainElement();
        if (!_ctlIsExistsElement(mainElement))
            return;
        eval("mainElement." + handlerName + " = function() { _ctlBCallButtonMethod('" + this.name + "', '" + correspondingMethodName + "'); }");
    },
    InitializeEvents: function(){                
        if (!this.isNative){
            var element = this.GetInternalButton();                                                
            if(_ctlIsExists(element)) _ctlRemoveAttribute(element, "onfocus");

	        var textControl = this.GetTextControl();
	        if (_ctlIsExists(textControl)){           
                if (__ctlIE)
                    _ctlAttachEventToElement(textControl, "onmouseup", _ctlClearSelection);                        
                _ctlPreventElementDragAndSelect(textControl, false);          
            }	         
        }
        
        var name = this.name;            
        this.onClick =  function() {return ctlBClick(name); };        
        this.onGotFocus =  function() {ctlBGotFocus(name); };
        this.onLostFocus =  function() {ctlBLostFocus(name); };
        this.onKeyUp =  function(evt) {ctlBKeyUp(evt, name); };
        this.onKeyDown =  function(evt) {ctlBKeyDown(evt, name); };    
    },    
    
    GetContentDiv: function(){
        if(!_ctlIsExistsElement(this.contentDiv))
            this.contentDiv = this.GetChild("_T");
        return this.contentDiv;
    },                         
    GetButtonCell: function(){
        if(!_ctlIsExistsElement(this.buttonCell))
            this.buttonCell = this.GetChild("_B");
        return this.buttonCell;
    },   
    GetButtonCheckedInput: function(){    
        if(!_ctlIsExistsElement(this.checkedInput))
            this.checkedInput = _ctlGetElementById(this.name + "_CH");
        return this.checkedInput;        
    },  
    GetButtonImage: function(){
        if(!_ctlIsExistsElement(this.buttonImage))
            this.buttonImage = _ctlGetChildByTagName(this.GetButtonCell(), "IMG", 0);
        return this.buttonImage;
    },          
    GetInternalButton: function(){
        if(!_ctlIsExistsElement(this.internalButton))
            this.internalButton = this.isNative ? this.GetMainElement() : _ctlGetChildByTagName(this.GetMainElement(), "INPUT", 0);
        return this.internalButton;
    },            
    GetTextElement: function(){
        if(!_ctlIsExistsElement(this.textElement)){
            var contentDiv = this.GetContentDiv();
            if (this.GetButtonImage() == null) 
                this.textElement = contentDiv;
            else {
                this.textElement = _ctlGetChildByTagName(contentDiv, "TD", 0);
                var img = _ctlGetChildByTagName(this.textElement, "IMG", 0);
                if (_ctlIsExists(img))
                    this.textElement = _ctlGetChildByTagName(contentDiv, "TD", 1);                                                           
            }    
        }
        return this.textElement;
    },    
    GetTextControl: function(){    
        if(!_ctlIsExistsElement(this.textControl))            
            this.textControl = _ctlGetParentByTagName(this.GetTextElement(), "table");
        if (!_ctlIsExistsElement(this.textControl) || (this.textControl.id == this.name))
            this.textControl = this.GetTextElement();            
        return this.textControl;
    },        
    
    GetPostfixes: function(){
        return this.isNative ? [""] : ["_B"];
    },
    IsHovered: function(){
        var hoverElement = this.isNative ? this.GetMainElement() : this.GetButtonCell();
        return ctlGetStateController().currentHoverItemName == hoverElement.id;
    },      
    
    ChangeEnabledEventsAttributes: function(method){
        var element = this.GetMainElement();
        method(element, "click", this.onClick);                  
        if (this.allowFocus){        
            if (!this.isNative) 
                element = this.GetInternalButton();
            method(element, "focus", this.onGotFocus);
            method(element, "blur", this.onLostFocus);                
            if (!this.isNative){
                method(element, "keyup",  this.onKeyUp);                
                method(element, "blur",  this.onKeyUp);                                
                method(element, "keydown", this.onKeyDown);                                                                
            }                            
        }    
    },
    SetEnabledInternal: function(enabled, initialization){
        this.enabled = enabled;
        if(!initialization || !enabled){
            if(!this.isNative){
                if (!enabled)
                    ctlGetStateController().DisableElement(this.GetButtonCell());
                else
                    ctlGetStateController().EnableElement(this.GetButtonCell());
                this.UpdateFocusedStyle();
            }
            else
                this.GetMainElement().disabled = !enabled;
        }
        this.ChangeEnabledEventsAttributes(enabled ? _ctlAttachEventToElement : _ctlDetachEventFromElement);
    },    

    OnFocus: function(){    
        if(!this.allowFocus) return false;
        
        this.focused = true;            
        if(this.isInitialized && _ctlIsExists(this.RaiseFocus))
            this.RaiseFocus();            
        this.UpdateFocusedStyle();
    },        
    OnLostFocus: function() {
        if(!this.allowFocus) return false;
        
        this.focused = false;            
        if(this.isInitialized && _ctlIsExists(this.RaiseLostFocus))
            this.RaiseLostFocus();         
        this.UpdateFocusedStyle();
    },            
    OnClick: function(){
        if (this.groupName != ""){
            var list = this.GetCheckedGroupList();
            if(list.length > 1 && this.checked)
                return;
        }

        this.SetFocus();
        var processOnServer = this.autoPostBack || this.IsServerEventAssigned("Click");
        if(_ctlIsExists(this.RaiseClick))
            processOnServer = this.RaiseClick();                      
        if (this.causesValidation && _ctlIsExistsType(typeof(ctlClientEdit)))
            processOnServer = ctlClientEdit.ValidateGroup(this.validationGroup) && processOnServer;
        if (processOnServer) 
            this.SendPostBack();
        else if (this.groupName != ""){
            var list = this.GetCheckedGroupList();
            if(list.length == 1)
                this.SetCheckedInternal(!this.checked, false);
            else{
                this.SetCheckedInternal(true, false);
                this.ClearButtonGroupChecked(true);
            }
            if(_ctlIsExists(this.RaiseCheckedChanged))
                processOnServer = this.RaiseCheckedChanged();                      
            if (processOnServer) 
                this.SendPostBack();
        }
    },     
    OnKeyUp: function(evt) {  
       if(this.pressed)      
            this.SetUnpressed();
    },
    OnKeyDown: function(evt) {           
       if((evt.keyCode == 13) || (evt.keyCode == 32))
           this.SetPressed();                  
    },  

    GetChecked: function(){        
        return  this.groupName != "" ? this.GetButtonCheckedInput().value == "1" : false;                      
    },  
    GetCheckedGroupList: function(){
        var collection = ctlGetControlCollection();    
        var result = new Array();
        for(var name in collection.elements) {
            var element = collection.elements[name];
            if (element != null && ctlClientButton.prototype.isPrototypeOf(element) &&
                (element.groupName == this.groupName))
                _ctlArrayPush(result, element);
        }
        return result;
    },
    ClearButtonGroupChecked: function(raiseCheckedChanged){
        var list = this.GetCheckedGroupList();
        for(var i = 0; i < list.length; i ++){
            if(list[i] != this && list[i].checked) {
                list[i].SetCheckedInternal(false, false);
                
                if(raiseCheckedChanged && _ctlIsExists(this.RaiseCheckedChanged))
                    this.RaiseCheckedChanged();                      
            }
        }
    },
    ApplyCheckedStyle: function(){
        if(this.IsHovered()) 
            ctlGetStateController().SetCurrentHoverElement(null);        
        ctlGetStateController().SelectElementBySrcElement(this.GetButtonCell());    
    }, 
    ApplyUncheckedStyle: function(){
        if(this.IsHovered()) 
            ctlGetStateController().SetCurrentHoverElement(null);        
        ctlGetStateController().DeselectElementBySrcElement(this.GetButtonCell());    
    },     
    SetCheckedInternal: function(checked, initialization){
        if(initialization && checked || (this.checked != checked)){
            this.checked = checked;
            var inputElement = this.GetButtonCheckedInput();
            if(_ctlIsExists(inputElement)) inputElement.value = checked ? "1" : "0";                                    
            if(checked)
                this.ApplyCheckedStyle();
            else
                this.ApplyUncheckedStyle();
        }
    },
    
    ApplyPressedStyle: function(){
        ctlGetStateController().OnMouseDownOnElement(this.GetButtonCell());
    },
    ApplyUnpressedStyle: function(){    
        ctlGetStateController().OnMouseUpOnElement(this.GetButtonCell());
    },
    SetPressed: function(){
        this.pressed = true;
        this.ApplyPressedStyle();
    }, 
    SetUnpressed: function(){    
        this.pressed = false;
        this.ApplyUnpressedStyle();        
    },
    
    SetFocus: function(){
        if (this.allowFocus){
            var element = this.GetInternalButton();
            if (_ctlIsFocusable(element) && _ctlGetActiveElement() != element) 
                element.focus();                             
         }       
    },    
    ApplyFocusedStyle: function(){
        if(this.focusElementSelected) return;
        ctlGetStateController().SelectElementBySrcElement(this.GetContentDiv());
        this.focusElementSelected = true;
    },
    ApplyUnfocusedStyle: function(){    
        if(!this.focusElementSelected) return;
        ctlGetStateController().DeselectElementBySrcElement(this.GetContentDiv());
        this.focusElementSelected = false;
    },
    UpdateFocusedStyle: function(){  
        if(this.isNative) return;
        if(this.enabled && this.allowFocus && this.focused)
            this.ApplyFocusedStyle();
        else
            this.ApplyUnfocusedStyle();
    },
    
    SendPostBack: function(){
        if(_ctlIsExists(this.autoPostBackFunction))
            this.autoPostBackFunction();
        else 
            ctlClientControl.prototype.SendPostBack.call(this, "");
    }
});

function _ctlBCallButtonMethod(name, methodName) {
    var button = ctlGetControlCollection().Get(name); 
    if (button != null)
        eval("button." + methodName + "()");
}

function ctlBGotFocus(name){
    var button = ctlGetControlCollection().Get(name); 
    if(button != null)
        return button.OnFocus();
}
function ctlBLostFocus(name){
    var button = ctlGetControlCollection().Get(name);
    if(button != null) 
        return button.OnLostFocus();
}
function ctlBClick(name){
    var button = ctlGetControlCollection().Get(name); 
    if(button != null)
        button.OnClick();
    return false;    
}
function ctlBKeyDown(evt,name){
    var button = ctlGetControlCollection().Get(name); 
    if(button != null)
        button.OnKeyDown(evt);
}
function ctlBKeyUp(evt,name){
    var button = ctlGetControlCollection().Get(name); 
    if(button != null)
        button.OnKeyUp(evt);
}