

var __aspxExternalTableSuffix = "_ET";
var __aspxErrorCellSuffix = "_EC";
var __aspxErrorTextCellSuffix = "_ETC";
var __aspxErrorImageSuffix = "_EI";
ASPxClientEditBase = _aspxCreateClass(ASPxClientControl, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
    },
    GetValue: function() {
        var element = this.GetMainElement();
        if(_aspxIsExistsElement(element))
            return element.innerHTML;
        return "";
    },
    GetValueString: function(){
        var value = this.GetValue();
        return value == null ? null : value.toString();
    },
    SetValue: function(value) {
        if(value==null)
            value = "";
        var element = this.GetMainElement();
        if(_aspxIsExistsElement(element))
            element.innerHTML = value;
    }
});

ASPxValidationPattern = _aspxCreateClass(null, {
    constructor: function(errorText) {
        this.errorText = errorText;
    }
});

ASPxRequiredFieldValidationPattern = _aspxCreateClass(ASPxValidationPattern, {
    constructor: function(errorText) {
        this.constructor.prototype.constructor.call(this, errorText);
    },
    EvaluateIsValid: function(value) {
        if ((typeof(value)).toUpperCase() == "BOOLEAN")
            return value;
        else
            return (value != null) && (_aspxTrim(value.toString()) != "");
    }
});

ASPxRegularExpressionValidationPattern = _aspxCreateClass(ASPxValidationPattern, {
    constructor: function(errorText, pattern) {
        this.constructor.prototype.constructor.call(this, errorText);
        this.pattern = pattern;
    },
    EvaluateIsValid: function(value) {
        if (value == null) 
            return true;
        var strValue = "" + value;
        if (_aspxTrim(strValue).length == 0)
            return true;
        var regEx = new RegExp(this.pattern);
        var matches = regEx.exec(strValue);
        return (matches != null && strValue == matches[0]);
    }
});

function _aspxIsEditorFocusable(inputElement) {
    return _aspxIsFocusableCore(inputElement, function(container) {
        return container.getAttribute("errorFrame") == "errorFrame";
    });
}

var __aspxInvalidEditorElementToBeFocused = null;
ASPxClientEdit = _aspxCreateClass(ASPxClientEditBase, {
    constructor: function(name) {
        this.constructor.prototype.constructor.call(this, name);
        
        this.isASPxClientEdit = true;
        
        this.inputElement = null;
        this.convertEmptyStringToNull = true;
        this.isClientVisible = true;
        
        // size correction
        this.widthCorrectionRequired = false;
        this.heightCorrectionRequired = false;
        
        // validation
        this.customValidationEnabled = false;
        this.initialErrorText = "";
        this.causesValidation = false;
        this.validateOnLeave = true;
        this.validationGroup = "";
        this.sendPostBackWithValidation = null;
        this.validationPatterns = null;
        this.setFocusOnError = false;
        this.errorDisplayMode = "it";
        this.errorText = "";
        this.isValid = true;
        this.errorImageIsAssigned = false;
        this.GotFocus = new ASPxClientEvent();
        this.LostFocus = new ASPxClientEvent();
        this.Validation = new ASPxClientEvent();
        this.ValueChanged = new ASPxClientEvent();
    },
    Initialize: function() {
        this.initialErrorText = this.errorText;
        this.constructor.prototype.Initialize.call(this);
    },
    FindInputElement: function(){
        return null;
    },
    GetElementBySuffix: function(suffix) {
        return _aspxGetElementById(this.name + suffix);
    },
    GetErrorImage: function() {
        return this.GetElementBySuffix(__aspxErrorImageSuffix);
    },
    GetErrorTextCell: function() {
        return this.GetElementBySuffix(this.errorImageIsAssigned ? __aspxErrorTextCellSuffix : __aspxErrorCellSuffix);
    },
    GetExternalTable: function(){
        return this.GetElementBySuffix(__aspxExternalTableSuffix);
    },
    GetInputElement: function(){
        if(!_aspxIsExistsElement(this.inputElement))
            this.inputElement = this.FindInputElement();
        return this.inputElement;
    },
    
    GetClientVisible: function(){
        return !this.customValidationEnabled ? ASPxClientControl.prototype.GetClientVisible.call(this) : 
            this.GetClientVisibleWithErrorFrame();
    },
    SetClientVisible: function(isVisible){
        return !this.customValidationEnabled ? ASPxClientControl.prototype.SetClientVisible.call(this, isVisible) :
            this.SetClientVisibleWithErrorFrame(isVisible);
    },
    
    SetClientVisibleWithErrorFrame: function(isVisible) {
        if (this.isClientVisible && isVisible || !this.isClientVisible && !isVisible)
            return;
        var errorFrame = this.GetExternalTable();
        if (!isVisible) {
            errorFrame.__aspxSavedClientVisibility = errorFrame.style.visibility;
            errorFrame.__aspxSavedClientDisplay = errorFrame.style.display;
            _aspxSetElementDisplay(errorFrame, false);
            this.isClientVisible = false;
        } else {
            errorFrame.style.visibility = errorFrame.__aspxSavedClientVisibility;
            errorFrame.style.display = errorFrame.__aspxSavedClientDisplay;
            errorFrame.__aspxSavedClientVisibility = void(0);
            errorFrame.__aspxSavedClientDisplay = void(0);
            this.isClientVisible = true;
        }
        if (isVisible)
            this.CorrectSize(__aspxCheckSizeCorrectedFlag);
    },
    GetClientVisibleWithErrorFrame: function() {
        return this.isClientVisible;
    },
    
    GetValueInputToValidate: function() {
        return this.GetInputElement();
    },
    IsVisible: function() {
        if (!this.isClientVisible)
            return false;
        var element = this.GetMainElement();
        while(_aspxIsExists(element) && element.tagName != "BODY") {
            if (element.getAttribute("errorFrame") != "errorFrame" && (!_aspxGetElementVisibility(element) || !_aspxGetElementDisplay(element)))
                return false;
            element = element.parentNode;
        }
        return true;
    },
    // Size correction
    CorrectSizeCore: function() {
        var mainElement = this.GetMainElement();
        var mainElementCurStyle = _aspxGetCurrentStyle(mainElement);
        // collapse control
        this.CollapseControl();
        // correct width
        if (this.widthCorrectionRequired && mainElementCurStyle.width != "" && mainElementCurStyle.width != "auto")
            this.CorrectEditorWidth();
        else
            this.UnstretchInputElement();
        // correct height
        if (this.heightCorrectionRequired)
            this.CorrectEditorHeight();
    },
    CorrectEditorWidth: function() {
    },
    CorrectEditorHeight: function() {
    },
    UnstretchInputElement: function() {
    },
    OnFocus: function() {
        if (!this.isInitialized) 
            return;
        if(_aspxIsExists(this.RaiseFocus)) {
            this.RaiseFocus();
        }
    },
    OnLostFocus: function() {
        if (!this.isInitialized) 
            return;
        if(_aspxIsExists(this.RaiseLostFocus))
            this.RaiseLostFocus();
        if (this.validateOnLeave)
            this.SetFocusOnError();
    },
    OnValidation: function(isPersonalValidation) {
        if (!this.isInitialized || !this.customValidationEnabled || !this.IsVisible())
            return;
        this.errorText = this.initialErrorText;
        this.isValid = true;
        this.ValidateWithPatterns();
        if(_aspxIsExists(this.RaiseValidation))
            this.RaiseValidation();
        if (!isPersonalValidation)
            this.UpdateErrorFrame();
        else if (this.validateOnLeave || this.isValid)
            this.UpdateErrorFrame(!this.validateOnLeave);
    },
    OnValueChanged: function() {
        var processOnServer = this.RaiseValueChangedEvent();
        processOnServer = this.RaiseValidationInternal(true) && processOnServer;
        if (processOnServer)
            this.SendPostBackInternal("");
    },
    ParseValue: function() {
    },
    RaisePersonalStandardValidation: function() {
        if (_aspxIsFunction(window.ValidatorOnChange)) {
            var inputElement = this.GetValueInputToValidate();
            if (_aspxIsExists(inputElement.Validators))
                window.ValidatorOnChange({ srcElement: inputElement });
        }
    },
    RaiseValidationInternal: function(isPersonalValidation) {
        if (this.autoPostBack && this.causesValidation && this.validateOnLeave)
            return ASPxClientEdit.ValidateGroup(this.validationGroup);
        else {
            this.OnValidation(isPersonalValidation);
            return this.isValid;
        }
    },
    RaiseValueChangedEvent: function(){
        if(_aspxIsExists(this.RaiseValueChanged))
            return this.RaiseValueChanged();
        return this.autoPostBack;
    },
    SendPostBackInternal: function(postBackArg) {
        if (_aspxIsFunction(this.sendPostBackWithValidation))
            this.sendPostBackWithValidation(postBackArg);
        else
            this.SendPostBack(postBackArg);
    },
    SetElementToBeFocused: function() {
        var input = this.GetInputElement();
        if (_aspxIsExistsElement(input) && _aspxIsExists(input.focus) && this.IsVisible())
            __aspxInvalidEditorElementToBeFocused = input;
    },
    SetFocus: function(){
        var inputElement = this.FindInputElement();
        if (_aspxGetActiveElement() != inputElement && _aspxIsEditorFocusable(inputElement)) 
            _aspxSetFocus(inputElement);
    },
    SetFocusOnError: function() {
        var input = this.GetInputElement();
        if (__aspxInvalidEditorElementToBeFocused == input) {
            input.focus();
            __aspxInvalidEditorElementToBeFocused = null;
        }
    },
    UpdateErrorFrame: function(doNotFocusOnError) {
        var externalTable = this.GetExternalTable();
        if (this.isValid) {
            externalTable.style.visibility = "hidden";
        } else {
            this.UpdateErrorCellContent();
            externalTable.style.visibility = "visible";
            if (!doNotFocusOnError && this.setFocusOnError && __aspxInvalidEditorElementToBeFocused == null)
                this.SetElementToBeFocused();
        }
    },
    UpdateErrorCellContent: function() {
        if (this.errorDisplayMode.indexOf("t") > -1)
            this.UpdateErrorText();
        if (this.errorDisplayMode == "i")
            this.UpdateErrorImage();
    },
    UpdateErrorImage: function() {
        var image = this.GetErrorImage();
        if (_aspxIsExistsElement(image)) {
            image.alt = this.errorText;
            image.title = this.errorText;
        } else {
            this.UpdateErrorText();
        }
    },
    UpdateErrorText: function() {
        var errorTextCell = this.GetErrorTextCell();
        if (_aspxIsExistsElement(errorTextCell)) {
            if (_aspxIsExistsElement(errorTextCell.firstChild))
                errorTextCell.replaceChild(document.createTextNode(this.errorText), errorTextCell.firstChild);
            else
                errorTextCell.appendChild(document.createTextNode(this.errorText));
        }     
    },
    ValidateWithPatterns: function() {
        if (this.validationPatterns != null) {
            var value = this.GetValue();
            for (var i = 0; i < this.validationPatterns.length; i++) {
                var validator = this.validationPatterns[i];
                if (!validator.EvaluateIsValid(value)) {
                    this.isValid = false;
                    this.errorText = validator.errorText;
                    return;
                }
            }
        }
    },
    // API
    RaiseFocus: function(){
        if(!this.GotFocus.IsEmpty()){
            var args = new ASPxClientEventArgs();
            this.GotFocus.FireEvent(this, args);
        }
    },
    RaiseLostFocus: function(){
        if(!this.LostFocus.IsEmpty()){
            var args = new ASPxClientEventArgs();
            this.LostFocus.FireEvent(this, args);
        }
    },
    RaiseValidation: function() {
        if (this.customValidationEnabled && !this.Validation.IsEmpty()) {
            var currentValue = this.GetValue();
            var args = new ASPxClientEditValidationEventArgs(currentValue, this.errorText, this.isValid);
            this.Validation.FireEvent(this, args);
            this.errorText = args.errorText;
            this.isValid = args.isValid;
            if (currentValue != args.value)
                this.SetValue(args.value);
        }
    },
    RaiseValueChanged: function(){
        var processOnServer = this.autoPostBack;
        if(!this.ValueChanged.IsEmpty()){
            var args = new ASPxClientProcessingModeEventArgs(processOnServer);
            this.ValueChanged.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;  
    },
    Focus: function(){
        this.SetFocus();
    },
    GetIsValid: function(){
        return this.isValid;
    },
    GetErrorText: function(){
        return this.errorText;
    },
    SetIsValid: function(isValid){
        if (this.customValidationEnabled) {
            this.isValid = isValid;
            this.UpdateErrorFrame();
        }
    },
    SetErrorText: function(errorText){
        if (this.customValidationEnabled) {
            this.errorText = errorText;
            this.UpdateErrorFrame();
        }
    },
    Validate: function(){
        this.ParseValue();
        this.OnValidation();
    }
});

ASPxIdent.IsASPxClientEdit = function(obj) {
    return _aspxIsExists(obj.isASPxClientEdit) && obj.isASPxClientEdit;
};
ASPxClientEdit.ClearEditorsInContainer = function(container, validationGroup) {
    __aspxInvalidEditorElementToBeFocused = null;
    _aspxProcessEditorsInContainer(container, _aspxClearProcessingProc, 
        _aspxClearChoiceCondition, validationGroup);
}
ASPxClientEdit.ClearEditorsInContainerById = function(containerId, validationGroup) {
    var container = document.getElementById(containerId);
    if (container != null)
        this.ClearEditorsInContainer(container, validationGroup);
}
ASPxClientEdit.ClearGroup = function(validationGroup) {
    return this.ClearEditorsInContainer(null, validationGroup);
}
ASPxClientEdit.ValidateEditorsInContainer = function(container, validationGroup) {
    var isValid = _aspxProcessEditorsInContainer(container, _aspxValidateProcessingProc,
        _aspxValidateChoiceCondition, validationGroup);
    return isValid;
}
ASPxClientEdit.ValidateEditorsInContainerById = function(containerId, validationGroup) {
    var container = document.getElementById(containerId);
    return (container != null) ? this.ValidateEditorsInContainer(container, validationGroup) : true;
}
ASPxClientEdit.ValidateGroup = function(validationGroup) {
    return this.ValidateEditorsInContainer(null, validationGroup);
}
ASPxClientEditValidationEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
    constructor: function(value, errorText, isValid) {
        this.constructor.prototype.constructor.call(this);
        this.errorText = errorText;
        this.isValid = isValid;
        this.value = value;
    }
});

function aspxEGotFocus(name){
    var edit = aspxGetControlCollection().Get(name); 
    if(edit != null)
        edit.OnFocus();
}
function aspxELostFocus(name){
    var edit = aspxGetControlCollection().Get(name);
    if(edit != null) 
        edit.OnLostFocus();
}
function aspxEValueChanged(name){
    var edit = aspxGetControlCollection().Get(name);
    if(edit != null)
        edit.OnValueChanged();
}

// KeyBoardSupport
function _aspxAttachKBSupportEventsToElement(element, controlName) {
    _aspxAttachEventToElement(element, "keydown", _aspxCreateEventHandlerFunction("aspxKBSIKeyDown", controlName, true));
    if (__aspxNS || __aspxOpera)
        _aspxAttachEventToElement(element, "keypress", _aspxCreateEventHandlerFunction("aspxKBSIKeyPress", controlName, true));
}
function aspxKBSIKeyPress(name, evt){
    var control = aspxGetControlCollection().Get(name);
    if(control != null){
        var isProcessed = false;
        switch (evt.keyCode){
        case ASPxKeyConsts.KEY_ENTER:
            if(control.OnEnter)
                isProcessed = _aspxIsExists(control.enterProcessed) && control.enterProcessed;
            break;
        }
        if(isProcessed)
            return _aspxPreventEventAndBubble(evt);
    }
}
function aspxKBSIKeyDown(name, evt){
    var control = aspxGetControlCollection().Get(name);
    if(control != null){
        var isProcessed = false;
        switch (evt.keyCode){
        case ASPxKeyConsts.KEY_ENTER:
            if(control.OnEnter)
                isProcessed = control.OnEnter(evt);
                control.enterProcessed = isProcessed;
            break;
        case ASPxKeyConsts.KEY_ESC:
            if(control.OnEscape)
                isProcessed = control.OnEscape();
            break;
        case ASPxKeyConsts.KEY_PAGEUP:
            if(control.OnPageUp)
                isProcessed = control.OnPageUp(evt);
            break;
        case ASPxKeyConsts.KEY_PAGEDOWN:
            if(control.OnPageDown)
                isProcessed = control.OnPageDown(evt);
            break;
        case ASPxKeyConsts.KEY_END:
            if(control.OnEndKeyDown)
                isProcessed = control.OnEndKeyDown(evt);
            break;
        case ASPxKeyConsts.KEY_HOME:
            if(control.OnHomeKeyDown)
                isProcessed = control.OnHomeKeyDown(evt);
            break;
        case ASPxKeyConsts.KEY_LEFT:
            if(control.OnArrowLeft)
                isProcessed = control.OnArrowLeft(evt);
            break;
        case ASPxKeyConsts.KEY_UP:
            if(control.OnArrowUp)
                isProcessed = control.OnArrowUp(evt);
            break;
        case ASPxKeyConsts.KEY_RIGHT:
            if(control.OnArrowRight)
                isProcessed = control.OnArrowRight(evt);
            break;
        case ASPxKeyConsts.KEY_DOWN:
            if(control.OnArrowDown)
                isProcessed = control.OnArrowDown(evt);
            break;
        }
        if(!isProcessed && control.OnKBSKeyDown)
            isProcessed = control.OnKBSKeyDown(evt);
        if(isProcessed)
            return _aspxPreventEventAndBubble(evt);
    }    
}

_aspxElementIsChildOfParent = function(element, parent) {
    if (element == null)
        return false;
    if (parent == null)
        return true;
    if (!_aspxIsExistsElement(element.parentNode))
        return false;
    return (element.parentNode == parent || 
        _aspxElementIsChildOfParent(element.parentNode, parent));
}

_aspxProcessEditorsInContainer = function(container, processingProc, choiceCondition, validationGroup) {
    var allProcessedSuccessfull = true;
    var firstFailured = null;
    __aspxInvalidEditorElementToBeFocused = "lock";
    var collection = aspxGetControlCollection();
    for (var key in collection.elements) {
        var element = collection.elements[key];
        if (element != null && ASPxIdent.IsASPxClientEdit(element)) {
            var inputElement = element.GetInputElement();
            if (_aspxElementIsChildOfParent(element.GetMainElement(), container) && 
                choiceCondition(element, validationGroup)) {
                allProcessedSuccessfull = processingProc(element) && allProcessedSuccessfull;
                if (!allProcessedSuccessfull && element.setFocusOnError && firstFailured == null && element.IsVisible())
                    firstFailured = inputElement;
            }
        }
    }
    if (firstFailured != null)
        firstFailured.focus();
    __aspxInvalidEditorElementToBeFocused = firstFailured;
    return allProcessedSuccessfull;
}

_aspxClearChoiceCondition = function(edit, validationGroup) {
    return !_aspxIsExists(validationGroup) || (edit.validationGroup == validationGroup);
}
_aspxValidateChoiceCondition = function(edit, validationGroup) {
    return _aspxClearChoiceCondition(edit, validationGroup) && edit.customValidationEnabled;
}
_aspxClearProcessingProc = function(edit) {
    edit.SetValue(null);
    edit.SetIsValid(true);
    return true;
}
_aspxValidateProcessingProc = function(edit) {
    edit.OnValidation();
    return edit.isValid;
}