import * as commonModule from './common';
import { Color, Utils, Enums, EditableTextBase, Font, colorProperty, fontInternalProperty, widthProperty, paddingBottomProperty, paddingTopProperty, paddingLeftProperty, paddingRightProperty, marginLeftProperty, marginTopProperty, marginRightProperty, marginBottomProperty, borderLeftWidthProperty, borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, visibilityProperty } from '@nativescript/core';
import { AutoCompleteDisplayMode } from 'nativescript-ui-autocomplete';
export * from './common';
var TKDataFormDelegateImplementation = /** @class */ (function (_super) {
    __extends(TKDataFormDelegateImplementation, _super);
    function TKDataFormDelegateImplementation() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TKDataFormDelegateImplementation.new = function () {
        return _super.new.call(this);
    };
    TKDataFormDelegateImplementation.prototype.initWithOwner = function (owner) {
        this._owner = new WeakRef(owner);
        return this;
    };
    /**
     * Called when a row with the corresponding property is selected.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidSelectEditorForProperty = function (dataForm, editor, property) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var args = {
            eventName: commonModule.RadDataForm.editorSelectedEvent,
            object: this._owner.get(),
            editor: editor,
            entityProperty: property,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
        if (entityProperty.editor) {
            entityProperty.editor.notify({ eventName: EditableTextBase.focusEvent, object: entityProperty.editor });
        }
    };
    /**
     * Called when a row with the corresponding property is deselected.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidDeselectEditorForProperty = function (dataForm, editor, property) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var args = {
            eventName: commonModule.RadDataForm.editorDeselectedEvent,
            object: this._owner.get(),
            editor: editor,
            entityProperty: property,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
        if (entityProperty.editor) {
            entityProperty.editor.notify({ eventName: EditableTextBase.blurEvent, object: entityProperty.editor });
        }
    };
    /**
     * Called after a property is edited.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidEditProperty = function (dataForm, property) {
        var args = {
            eventName: commonModule.RadDataForm.propertyEditedEvent,
            object: this._owner.get(),
            editor: undefined,
            entityProperty: property,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * Called after a property is validated.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidValidatePropertyEditor = function (dataForm, property, editor) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var group = this._owner.get().getGroupByName(property.groupName);
        var args = {
            eventName: commonModule.RadDataForm.propertyValidatedEvent,
            object: this._owner.get(),
            editor: entityProperty.editor,
            entityProperty: entityProperty,
            propertyName: property.name,
            group: group,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * Called after validate method has been called to notify that the process has ended.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidFinishValidation = function (dataForm, result) {
        if (this._owner.get()._validateResolve != null) {
            this._owner.get()._validateResolve(result);
            this._owner.get()._validateResolve = null;
        }
        return true;
    };
    /**
     * Called after commit method has been called to notify that the process has ended.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidFinishCommit = function (dataForm, result) {
        if (this._owner.get()._commitResolve != null) {
            this._owner.get()._commitResolve(result);
            this._owner.get()._commitResolve = null;
        }
        return true;
    };
    /**
     * Called when a property has to be validated.
     */
    TKDataFormDelegateImplementation.prototype.dataFormValidatePropertyEditor = function (dataForm, property, editor) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var validatedValue = property.valueCandidate;
        var group = this._owner.get().getGroupByName(property.groupName);
        var args = {
            eventName: commonModule.RadDataForm.propertyValidateEvent,
            object: this._owner.get(),
            editor: entityProperty.editor,
            entityProperty: entityProperty,
            propertyName: property.name,
            group: group,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
        var result = Promise.resolve(args.returnValue);
        dataForm.onValidationStartedEditor(property, editor);
        result.then(function (answer) {
            if (answer === false) {
                property.errorMessage = entityProperty.errorMessage;
                dataForm.onValidationResultValuePropertyEditor(false, validatedValue, property, editor);
            }
            else {
                property.positiveMessage = entityProperty.successMessage;
                dataForm.onValidationResultValuePropertyEditor(true, validatedValue, property, editor);
            }
        });
        return args.returnValue;
    };
    /**
     *  Called once when the data form creates its editors. This method lets you to set properties that are not going to be changed.
     */
    TKDataFormDelegateImplementation.prototype.dataFormSetupEditorForProperty = function (dataForm, editor, property) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        if (!entityProperty) {
            entityProperty = this._owner.get()._createPropertyFromNative(property);
            if (!this._owner.get().properties) {
                this._owner.get().properties = new Array();
            }
            this._owner.get().properties.push(entityProperty);
        }
        entityProperty._updateNativeEditor(editor);
        var args = {
            eventName: commonModule.RadDataForm.editorSetupEvent,
            object: this._owner.get(),
            editor: editor,
            entityProperty: property,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    TKDataFormDelegateImplementation.prototype.dataFormDidLayoutEditorForProperty = function (dataForm, editor, property) {
        if (this._owner.get().source === undefined) {
            return;
        }
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        if (entityProperty) {
            var propertyEditor = entityProperty.editor;
            if (propertyEditor) {
                var editorPosition = this.getPositionFromFrame(editor.frame);
                propertyEditor.layout(editorPosition.left, editorPosition.top, editorPosition.right, editorPosition.bottom);
                var labelPosition = this.getPositionFromFrame(editor.textLabel.frame);
                propertyEditor.label.layout(labelPosition.left, labelPosition.top, labelPosition.right, labelPosition.bottom);
                var editorCorePosition = this.getPositionFromFrame(editor.editorCore.frame);
                propertyEditor.editorCore.layout(editorCorePosition.left, editorCorePosition.top, editorCorePosition.right, editorCorePosition.bottom);
            }
        }
    };
    /**
     *  Called when the data is reloaded in the native RadDataForm component (reloadData). This method lets you to set the PropertyChanged callbacks for all {N} properties.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidFinishEditorIntitialization = function (dataForm) {
        if (this._owner.get().source === undefined) {
            return;
        }
        if (this._owner.get().properties) {
            for (var i = 0; i < this._owner.get().properties.length; i++) {
                var entityProperty = this._owner.get().properties[i];
                this.updatePropertyEditor(entityProperty);
            }
        }
        if (this._owner.get().groups) {
            for (var i = 0; i < this._owner.get().groups.length; i++) {
                var group = this._owner.get().groups[i];
                if (group.properties) {
                    for (var j = 0; j < group.properties.length; j++) {
                        var entityProperty = group.properties[j];
                        this.updatePropertyEditor(entityProperty);
                    }
                }
            }
        }
        this._owner.get()._onCssStateChange();
    };
    TKDataFormDelegateImplementation.prototype.updatePropertyEditor = function (entityProperty) {
        this._owner.get()._attachEntityPropertyPropertyChangeListener(entityProperty);
        if (!entityProperty.editor) {
            return;
        }
        entityProperty._updateNativeEditor(entityProperty.editor.ios);
        if (!entityProperty.parent && !entityProperty.editor.parent) {
            this._owner.get()._addView(entityProperty);
            entityProperty._addView(entityProperty.editor);
        }
        var ngKey = this._owner.get()._ngKey;
        if (ngKey) {
            // Add any newly created editors to the same scope as RadDataForm
            // in order to apply component-specific css in angular
            var ngValue = this._owner.get()[ngKey];
            entityProperty[ngKey] = ngValue;
            entityProperty.editor[ngKey] = ngValue;
            entityProperty.editor.label[ngKey] = ngValue;
            entityProperty.editor.editorCore[ngKey] = ngValue;
        }
    };
    TKDataFormDelegateImplementation.prototype.getPositionFromFrame = function (frame) {
        var left = Utils.layout.round(Utils.layout.toDevicePixels(frame.origin.x));
        var top = Utils.layout.round(Utils.layout.toDevicePixels(frame.origin.y));
        var right = Utils.layout.round(Utils.layout.toDevicePixels(frame.origin.x + frame.size.width));
        var bottom = Utils.layout.round(Utils.layout.toDevicePixels(frame.origin.y + frame.size.height));
        return { left: left, right: right, top: top, bottom: bottom };
    };
    /**
     * Called before an editor is displayed to the screen or after validation. This method lets you change the visual styles and setting of TKDataFormEditor object.
     */
    TKDataFormDelegateImplementation.prototype.dataFormUpdateEditorForProperty = function (dataForm, editor, property) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        PropertyEditorHelper.applyStyle(entityProperty.editor);
        var args = {
            eventName: commonModule.RadDataForm.editorUpdateEvent,
            object: this._owner.get(),
            editor: editor,
            entityProperty: property,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * This method lets you change the visual styles and setting of TKEntityPropertyGroupView object.
     */
    TKDataFormDelegateImplementation.prototype.dataFormUpdateGroupViewForGroupAtIndex = function (dataForm, groupView, groupIndex) {
        if (groupView == null || groupView.group == null) {
            return;
        }
        var groupName = groupView.group.name;
        var group = this._owner.get().getGroupByName(groupName);
        if (group) {
            groupView.collapsible = group.collapsible;
            if (group.collapsible) {
                if (groupView.isCollapsed !== group.collapsed) {
                    if (group.collapsed) {
                        groupView.collapse();
                    }
                    else {
                        groupView.expand();
                    }
                }
            }
            groupView.titleView.hidden = group.titleHidden;
            this._owner.get()._updateGroupLayout(group, groupView);
            this._owner.get()._applyGroupTitleStyle(groupView, group.titleStyle);
        }
        // throw event for additional customizations
        var args = {
            eventName: commonModule.RadDataForm.groupUpdateEvent,
            object: this._owner.get(),
            editor: undefined,
            entityProperty: undefined,
            propertyName: undefined,
            group: groupView,
            groupName: groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * Called just before a property value will be committed to the business object.
     */
    TKDataFormDelegateImplementation.prototype.dataFormWillCommitProperty = function (dataForm, property) {
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var args = {
            eventName: commonModule.RadDataForm.propertyCommitEvent,
            object: this._owner.get(),
            editor: undefined,
            entityProperty: entityProperty,
            propertyName: property.name,
            group: undefined,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
        return args.returnValue;
    };
    TKDataFormDelegateImplementation.prototype.isUsingBooleanEditor = function (property) {
        return property.editorClass === TKDataFormSwitchEditor.class();
    };
    TKDataFormDelegateImplementation.prototype.isUsingNumericEditor = function (property) {
        return property.editorClass === TKDataFormDecimalEditor.class() || property.editorClass === TKDataFormNumberEditor.class() || property.editorClass === TKDataFormStepperEditor.class() || property.editorClass === TKDataFormSliderEditor.class();
    };
    TKDataFormDelegateImplementation.prototype.isUsingDateTimeEditor = function (property) {
        return property.editorClass === TKDataFormDatePickerEditor.class() || property.editorClass === TKDataFormTimePickerEditor.class();
    };
    TKDataFormDelegateImplementation.prototype.convertToTypedValue = function (oldValue, newValue, nativeProperty) {
        // The newValue is of type object, we try to deduct the desired type mostly based
        // on the type of the old value, so we can cast the newValue to the correct type
        if (newValue === null) {
            return null;
        }
        if (typeof oldValue === 'number' || this.isUsingNumericEditor(nativeProperty)) {
            return Number(newValue);
        }
        if (typeof oldValue === 'boolean' || this.isUsingBooleanEditor(nativeProperty)) {
            return String(newValue) === 'true';
        }
        if (this.isUsingDateTimeEditor(nativeProperty)) {
            // The Date/Time Editors can edit properties of types Date and String.
            if (typeof oldValue === 'string') {
                return String(newValue);
            }
            else {
                return new Date(newValue);
            }
        }
        if (newValue instanceof NSArray) {
            var jsArray = [];
            for (var i = 0; i < newValue.count; i++) {
                jsArray.push(newValue.objectAtIndex(i));
            }
            newValue = jsArray;
        }
        return newValue;
    };
    /**
     * Called after a property value is committed to the business object.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidCommitProperty = function (dataForm, property) {
        if (this._owner.get().source.hasOwnProperty(property.name)) {
            var oldValue = this._owner.get().source[property.name];
            var newValue = property.originalValue;
            var typedValue = this.convertToTypedValue(oldValue, newValue, property);
            this._owner.get().source[property.name] = typedValue;
        }
        var entityProperty = this._owner.get().getPropertyByName(property.name);
        var args = {
            eventName: commonModule.RadDataForm.propertyCommittedEvent,
            object: this._owner.get(),
            editor: null,
            entityProperty: entityProperty,
            propertyName: property.name,
            group: null,
            groupName: property.groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * Called after a group is collapsed.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidCollapseGroupView = function (dataForm, groupView) {
        var groupName = groupView != null && groupView.group != null ? groupView.group.name : null;
        var group = this._owner.get().getGroupByName(groupName);
        if (group) {
            group.collapsed = true;
        }
        var args = {
            eventName: commonModule.RadDataForm.groupCollapsedEvent,
            object: this._owner.get(),
            editor: undefined,
            entityProperty: undefined,
            propertyName: undefined,
            group: groupView,
            groupName: groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    };
    /**
     * Called after a group is expanded.
     */
    TKDataFormDelegateImplementation.prototype.dataFormDidExpandGroupView = function (dataForm, groupView) {
        var groupName = groupView != null && groupView.group != null ? groupView.group.name : null;
        var group = this._owner.get().getGroupByName(groupName);
        if (group) {
            group.collapsed = false;
        }
        var args = {
            eventName: commonModule.RadDataForm.groupExpandedEvent,
            object: this._owner.get(),
            editor: undefined,
            entityProperty: undefined,
            propertyName: undefined,
            group: groupView,
            groupName: groupName,
            returnValue: true,
        };
        this._owner.get().notify(args);
    }; // todo: uncomment , the bug with null view is fixed // public dataFormViewForHeaderInGroup(dataForm: TKDataForm, groupIndex: number): any { //TKEntityPropertyGroupTitleView //     console.log("dataFormViewForHeaderInGroup")
    /**
     * The header for the corresponding group.
     */ // }
    // todo: add height property to editor class in order to be set in xml.
    /**
     * The height for the editor at specified indices.
     */
    // public dataFormHeightForEditorInGroupAtIndex(dataForm: TKDataForm, groupIndex: number, editorIndex: number): number {
    //     console.log("DELEGATE: dataFormHeightForEditorInGroupAtIndex")
    //     var args: commonModule.DataFormEventData = { eventName: commonModule.RadDataForm.editorHeightEvent,
    //         object: this._owner,
    //         editor: editorIndex,
    //         group: groupIndex,
    //         returnValue: 20 };
    //     this._owner.notify(args);
    //     return args.returnValue;
    // }
    // todo: add height property to group in order to be set in xml.
    /**
     * The height of the group header.
     */
    // public dataFormHeightForHeaderInGroup(dataForm: TKDataForm, groupIndex: number): number {
    //     console.log("DELEGATE: dataFormHeightForHeaderInGroup")
    //     return 0;
    // }
    // todo: consider is it is required at all. Android doesn't support such kind of view
    /**
     *  Return input accessory view for text field editors.
     */
    // public inputAccessoryViewForDataForm(dataForm: TKDataForm): any {//TKDataFormAccessoryView
    //     console.log("DELEGATE: inputAccessoryViewForDataForm")
    // }
    /**
     * Initializes a view controller specific for a given view controller editor.
     */
    TKDataFormDelegateImplementation.prototype.dataFormInitViewControllerForEditor = function (dataForm, viewController, editor) {
        // This delegate method is called before a new UIViewController for an editor
        // is pushed to the UINavigationController.
        // Notify the NS page about the new controller and let it treat the controller as a presented view controller.
        if (this._owner.get().page.hasOwnProperty('_presentedViewController')) {
            this._owner.get().page['_presentedViewController'] = viewController;
        }
    };
    TKDataFormDelegateImplementation.ObjCProtocols = [TKDataFormDelegate];
    return TKDataFormDelegateImplementation;
}(NSObject));
var TKDataFormConverterImplementation = /** @class */ (function (_super) {
    __extends(TKDataFormConverterImplementation, _super);
    function TKDataFormConverterImplementation() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TKDataFormConverterImplementation.new = function () {
        return _super.new.call(this);
    };
    TKDataFormConverterImplementation.prototype.initWithConverter = function (converter) {
        this._converter = converter;
        return this;
    };
    TKDataFormConverterImplementation.prototype.convertFrom = function (source) {
        return this._converter.convertFrom(source);
    };
    TKDataFormConverterImplementation.prototype.convertTo = function (source) {
        return this._converter.convertTo(source);
    };
    TKDataFormConverterImplementation.ObjCProtocols = [TKDataFormConverter];
    return TKDataFormConverterImplementation;
}(NSObject));
var TKDataFormCustomEditorDelegateImplementation = /** @class */ (function (_super) {
    __extends(TKDataFormCustomEditorDelegateImplementation, _super);
    function TKDataFormCustomEditorDelegateImplementation() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TKDataFormCustomEditorDelegateImplementation.new = function () {
        return _super.new.call(this);
    };
    TKDataFormCustomEditorDelegateImplementation.prototype.initWithOwner = function (owner) {
        this._owner = new WeakRef(owner);
        return this;
    };
    TKDataFormCustomEditorDelegateImplementation.prototype.editorWillCreateView = function (editor) {
        var args = {
            eventName: commonModule.CustomPropertyEditor.editorNeedsViewEvent,
            object: this._owner.get(),
            view: undefined,
            context: undefined,
            value: undefined,
        };
        this._owner.get().notify(args);
        return args.view;
    };
    TKDataFormCustomEditorDelegateImplementation.prototype.editorShouldApplyValueEditorView = function (editor, value, view) {
        var args = {
            eventName: commonModule.CustomPropertyEditor.editorHasToApplyValueEvent,
            object: this._owner.get(),
            view: view,
            context: undefined,
            value: value,
        };
        this._owner.get().notify(args);
    };
    TKDataFormCustomEditorDelegateImplementation.prototype.editorWillReturnValueEditorView = function (editor, view) {
        var args = {
            eventName: commonModule.CustomPropertyEditor.editorNeedsValueEvent,
            object: this._owner.get(),
            view: view,
            context: undefined,
            value: undefined,
        };
        this._owner.get().notify(args);
        return args.value;
    };
    TKDataFormCustomEditorDelegateImplementation.ObjCProtocols = [TKDataFormCustomEditorDelegate];
    return TKDataFormCustomEditorDelegateImplementation;
}(NSObject));
var TKDataFormValidationProviderDelegateImplementation = /** @class */ (function (_super) {
    __extends(TKDataFormValidationProviderDelegateImplementation, _super);
    function TKDataFormValidationProviderDelegateImplementation() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TKDataFormValidationProviderDelegateImplementation.new = function () {
        return _super.new.call(this);
    };
    TKDataFormValidationProviderDelegateImplementation.prototype.initWithOwner = function (owner) {
        this._owner = new WeakRef(owner);
        return this;
    };
    TKDataFormValidationProviderDelegateImplementation.prototype.validatorWillValidate = function (validator, property) {
        return this._owner.get().validate(property.valueCandidate, property.name);
    };
    TKDataFormValidationProviderDelegateImplementation.ObjCProtocols = [TKDataFormValidationProviderDelegate];
    return TKDataFormValidationProviderDelegateImplementation;
}(NSObject));
export class RadDataForm extends commonModule.RadDataForm {
    constructor() {
        super();
        this._initialized = false;
        this._ios = TKDataForm.new();
        this._nativeDelegate = TKDataFormDelegateImplementation.new().initWithOwner(this);
        let that = new WeakRef(this);
        this.entityPropertyChangedHandler = function (data) {
            that.get().onPropertyPropertyChanged(data);
        };
        this.groupPropertyChangedHandler = function (data) {
            that.get().onGroupPropertyChanged(data);
        };
        this.groupTitleStylePropertyChangedHandler = function (data) {
            that.get().onGroupTitleStylePropertyChanged(data);
        };
        this.groupLayoutPropertyChangedHandler = function (data) {
            that.get()._onGroupLayoutPropertyChanged(data.object);
        };
        this.on('isEnabledChange', this.isEnabledChanged, this);
    }
    [borderLeftWidthProperty.setNative](value) {
        let paddingLeft = isNaN(+this.style.paddingLeft) ? 0 : +this.style.paddingLeft;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: value + paddingLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [paddingLeftProperty.setNative](value) {
        let borderLeft = isNaN(+this.style.borderLeftWidth) ? 0 : +this.style.borderLeftWidth;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: value + borderLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [borderTopWidthProperty.setNative](value) {
        let paddingTop = isNaN(+this.style.paddingTop) ? 0 : +this.style.paddingTop;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + paddingTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [paddingTopProperty.setNative](value) {
        let borderTop = isNaN(+this.style.borderTopWidth) ? 0 : +this.style.borderTopWidth;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + borderTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [borderRightWidthProperty.setNative](value) {
        let paddingRight = isNaN(+this.style.paddingRight) ? 0 : +this.style.paddingRight;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + paddingRight,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [paddingRightProperty.setNative](value) {
        let borderRight = isNaN(+this.style.borderRightWidth) ? 0 : +this.style.borderRightWidth;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + borderRight,
            bottom: currentInsets.bottom,
        });
        this._ios.insets = insets;
    }
    [borderBottomWidthProperty.setNative](value) {
        let paddingBottom = isNaN(+this.style.paddingBottom) ? 0 : +this.style.paddingBottom;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + paddingBottom,
        });
        this._ios.insets = insets;
    }
    [paddingBottomProperty.setNative](value) {
        let borderBottom = isNaN(+this.style.borderBottomWidth) ? 0 : +this.style.borderBottomWidth;
        let currentInsets = this._ios.insets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + borderBottom,
        });
        this._ios.insets = insets;
    }
    createNativeView() {
        // The iOS DataForm needs to know about the UIViewController that contains it.
        // It may be used by some UIViewControllerEditors (like List editor) to
        // access the UINavigationController and navigate to other controllers.
        // However, this is only possible when the DataForm is added to a page.
        // It can also be displayed in a modal page, then this.page will be undefined
        // and the above-mentioned editors will not work.
        if (this.page) {
            this._ios.owner = this.page.ios;
        }
        this._ngKey = Object.keys(this).find((key) => key.startsWith('_ngcontent'));
        // fix possible race conditions that happens when parsing the markup
        // we insert PropertyEntity objects after the form was already init
        // see https://github.com/NativeScript/nsplugins-internal/issues/162
        this._initDataForm();
        return this._ios;
    }
    initNativeView() {
        this._ios.delegate = this._nativeDelegate;
    }
    disposeNativeView() {
        this._ios.owner = undefined;
        this._ios.delegate = undefined;
        this._nativeDelegate = undefined;
    }
    isEnabledChanged(data) {
        this._ios.readOnly = !data.value;
    }
    onUnloaded() {
        super.onUnloaded();
        this._ios.delegate = null;
    }
    notifyValidated(propertyName, result) {
        let property = this.getPropertyByName(propertyName);
        let editor = property.editor;
        if (!result) {
            property.ios.errorMessage = property.errorMessage;
        }
        this._ios.onValidationResultValuePropertyEditor(result, property.valueCandidate, property.ios, editor.ios);
    }
    get editedObject() {
        let result = this._ios.dataSource.writeJSONToString();
        let parsedResult = JSON.parse(result);
        let finalResult = JSON.stringify(parsedResult);
        return finalResult;
    }
    _reset() {
        this._dataSource.removeAllGroups();
        this._initDataForm();
    }
    _applyGroupTitleStyle(groupView, titleStyle) {
        if (titleStyle.fillColor) {
            groupView.titleView.style.fill = TKSolidFill.solidFillWithColor(titleStyle.fillColor.ios);
        }
        if (titleStyle.strokeColor || titleStyle.strokeWidth) {
            let stroke = TKStroke.new();
            if (titleStyle.strokeWidth) {
                stroke.width = titleStyle.strokeWidth;
            }
            if (titleStyle.strokeColor) {
                stroke.color = titleStyle.strokeColor.ios;
            }
            groupView.titleView.style.stroke = stroke;
        }
        if (titleStyle.separatorColor) {
            groupView.titleView.style.separatorColor = TKSolidFill.solidFillWithColor(titleStyle.separatorColor.ios);
        }
        if (titleStyle.labelTextColor) {
            groupView.titleView.titleLabel.textColor = titleStyle.labelTextColor.ios;
        }
        if (titleStyle.labelFontName || titleStyle.labelTextSize || titleStyle.labelFontStyle) {
            groupView.titleView.titleLabel.font = RadDataForm.getFontWithProperties(titleStyle.labelFontName, titleStyle.labelTextSize, titleStyle.labelFontStyle);
        }
    }
    _updateGroupLayout(propertyGroup, nativeGroup) {
        if (propertyGroup.layout instanceof commonModule.DataFormStackLayout) {
            let nativeLayout = TKStackLayout.alloc().init();
            if (propertyGroup.layout.orientation === Enums.Orientation.horizontal) {
                nativeLayout.orientation = 0 /* TKLayoutOrientation.Horizontal */;
            }
            else {
                nativeLayout.orientation = 1 /* TKLayoutOrientation.Vertical */;
            }
            nativeGroup.editorsContainer.layout = nativeLayout;
        }
        else if (propertyGroup.layout instanceof commonModule.DataFormGridLayout) {
            nativeGroup.editorsContainer.layout = TKGridLayout.alloc().init();
        }
    }
    onGroupPropertyChanged(data) {
        if (!this._ios || !this._initialized) {
            return;
        }
        let nativeGroup = null;
        switch (data.propertyName) {
            case 'collapsed':
                let propertyGroup = data.object;
                if (!propertyGroup.collapsible) {
                    // If the group is not collapsible, we don't want to collapse it.
                    if (data.value) {
                        console.log('WARNING: collapsible should be true before collapsing a group.');
                    }
                    return;
                }
                nativeGroup = this.getNativeGroup(propertyGroup.name);
                let groupView = this._ios.groupViewForGroup(nativeGroup);
                if (data.value === groupView.isCollapsed) {
                    // If the group already confronts to the newValue, don't do anything.
                    return;
                }
                if (data.value) {
                    groupView.collapse();
                }
                else {
                    groupView.expand();
                }
                break;
            case 'titleHidden':
                nativeGroup = this.getNativeGroup(data.object.name);
                let nativeGroupView = this._ios.groupViewForGroup(nativeGroup);
                if (nativeGroupView) {
                    nativeGroupView.titleView.hidden = data.value;
                    nativeGroupView.setNeedsLayout();
                }
                break;
            case 'hidden':
                nativeGroup = this.getNativeGroup(data.object.name);
                nativeGroup.hidden = data.value;
                this.reload();
                break;
            case 'collapsible':
            case 'titleStyle':
                this.reload();
                break;
            case 'layout':
                this._onLayoutPropertyChanged(data.object);
                break;
            case 'name':
                this._reset();
                break;
        }
    }
    _onLayoutPropertyChanged(group) {
        if (!this._ios || !this._initialized) {
            return;
        }
        this._updateLayout(group);
    }
    _updateLayout(group) {
        let nativeGroup = this.getNativeGroup(group.name);
        let nativeGroupView = this._ios.groupViewForGroup(nativeGroup);
        this._updateGroupLayout(group, nativeGroupView);
    }
    getNativeGroup(name) {
        let groupCount = this._dataSource.numberOfGroupsInDataForm(this._ios);
        for (let i = 0; i < groupCount; i++) {
            let group = this._dataSource.groupAtIndex(i);
            if (group.name === name) {
                return group;
            }
        }
        return null;
    }
    onGroupTitleStylePropertyChanged(data) {
        if (!this._ios || !this._initialized) {
            return;
        }
        this.reload();
    }
    _onGroupLayoutPropertyChanged(group) {
        if (!this._ios || !this._initialized) {
            return;
        }
        this._updateLayout(group);
    }
    onPropertyPropertyChanged(data) {
        if (!this._ios || !this._initialized) {
            return;
        }
        let property = data.object;
        if (!property || !property.ios) {
            this.reload();
            return;
        }
        let nativeProperty = property.ios;
        switch (data.propertyName) {
            case 'readOnly':
                this._ios.updateEditorForProperty(nativeProperty);
                break;
            case 'hintText':
            case 'hidden':
            case 'index':
            case 'displayName':
            case 'valuesProvider':
            case 'editor':
                this.reload();
                break;
        }
    }
    _initDataForm() {
        if (!this.source || !this._dataSource) {
            return;
        }
        // go through all groups / entity properties
        if (this.groups) {
            for (let i = 0; i < this.groups.length; ++i) {
                let group = this.groups[i];
                if (group.properties) {
                    let propertyNames = NSMutableArray.alloc().initWithCapacity(group.properties.length);
                    for (let j = 0; j < group.properties.length; ++j) {
                        let entityProperty = group.properties[j];
                        propertyNames.addObject(entityProperty.name);
                    }
                    this._dataSource.addGroupWithNamePropertyNames(group.name, propertyNames);
                }
                // When a group is added to the data source, each property gets a new
                // value for its layoutInfo.row. Since we want the index defined in NS,
                // to have a bigger priority, we make the update after the property is
                // added to the data source.
                if (group.properties) {
                    for (let j = 0; j < group.properties.length; ++j) {
                        let entityProperty = group.properties[j];
                        this._updateNativeProperty(entityProperty);
                    }
                }
                let nativeGroup = this.getNativeGroup(group.name);
                if (group.hidden) {
                    nativeGroup.hidden = true;
                }
                if (!group.titleStyle) {
                    group.titleStyle = new commonModule.GroupTitleStyle();
                }
                if (!group.layout) {
                    group.layout = new commonModule.DataFormStackLayout();
                }
                this._attachGroupChangeListener(group);
            }
        }
        if (this.properties) {
            for (let i = 0; i < this.properties.length; ++i) {
                let entityProperty = this.properties[i];
                this._updateNativeProperty(entityProperty);
            }
        }
        this._ios.dataSource = this._dataSource;
        this._initialized = true;
    }
    _createPropertyFromNative(nativeProperty) {
        let entityProperty = new EntityProperty();
        entityProperty.name = nativeProperty.name;
        entityProperty._linkPropertyWithNative(nativeProperty);
        return entityProperty;
    }
    _updateNativeProperty(entityProperty) {
        let nativeProperty = this._dataSource.propertyWithName(entityProperty.name);
        if (nativeProperty) {
            entityProperty._linkPropertyWithNative(nativeProperty);
        }
        else {
            console.log("Cannot create native TKEntityProperty for EntityProperty with 'name': " + entityProperty.name);
        }
    }
    _onSourcePropertyChanged(oldValue, newValue) {
        if (newValue) {
            let objJSON = JSON.stringify(newValue);
            this._dataSource = TKDataFormEntityDataSource.alloc().initWithJSONStringRootItemKeyPath(objJSON, null);
            this._initDataForm();
        }
    }
    _onMetadataPropertyChanged(oldValue, newValue) {
        if (newValue) {
            let objJSON = JSON.stringify(newValue);
            this._ios.setupWithJSONAnnotationsString(objJSON);
            this.reload();
        }
    }
    _onIsReadOnlyPropertyChanged(oldValue, newValue) {
        this._ios.readOnly = newValue;
    }
    _onCommitModePropertyChanged(oldValue, newValue) {
        switch (newValue) {
            case commonModule.DataFormCommitMode.Immediate:
                this._ios.commitMode = 0 /* TKDataFormCommitMode.Immediate */;
                break;
            case commonModule.DataFormCommitMode.Manual:
                this._ios.commitMode = 2 /* TKDataFormCommitMode.Manual */;
                break;
            case commonModule.DataFormCommitMode.OnLostFocus:
                this._ios.commitMode = 1 /* TKDataFormCommitMode.OnLostFocus */;
                break;
        }
    }
    _onValidationModePropertyChanged(oldValue, newValue) {
        switch (newValue) {
            case commonModule.DataFormValidationMode.Immediate:
                this._ios.validationMode = 0 /* TKDataFormValidationMode.Immediate */;
                break;
            case commonModule.DataFormValidationMode.Manual:
                this._ios.validationMode = 2 /* TKDataFormValidationMode.Manual */;
                break;
            case commonModule.DataFormValidationMode.OnLostFocus:
                this._ios.validationMode = 1 /* TKDataFormValidationMode.OnLostFocus */;
                break;
        }
    }
    _onGroupsPropertyChanged(oldValue, newValue) { }
    validateAll() {
        let that = new WeakRef(this);
        let promise = new Promise(function (resolve) {
            that.get()._validateResolve = resolve;
        });
        this._ios.validate();
        return promise;
    }
    validateAndCommitAll() {
        let that = new WeakRef(this);
        let promise = new Promise(function (resolve) {
            that.get()._commitResolve = resolve;
        });
        this._ios.commit();
        return promise;
    }
    commitAll() {
        this._ios.commitForced();
    }
    reload() {
        if (this._ios) {
            this._ios.reloadData();
        }
    }
    hasValidationErrors() {
        if (this._ios) {
            this._ios.validate();
            return this._ios.hasValidationErrors();
        }
        return false;
    }
    ////////////////////////////////////////////////////////////////////////////
    // Helpers
    static getFontWithProperties(fontName, size, style) {
        let font = null;
        let fontSize = !isNaN(+size) ? size : 17;
        if (fontName) {
            font = UIFont.fontWithNameSize(fontName, fontSize);
            if (!font) {
                console.log('WARNING: Cannot create font with given name: ' + fontSize);
                return null;
            }
        }
        if (!font && !isNaN(+size)) {
            font = UIFont.systemFontOfSize(fontSize);
        }
        if (style) {
            let traits = 0 /* UIFontDescriptorSymbolicTraits.ClassUnknown */;
            switch (style) {
                case commonModule.DataFormFontStyle.Bold:
                    traits = 2 /* UIFontDescriptorSymbolicTraits.TraitBold */;
                    break;
                case commonModule.DataFormFontStyle.Italic:
                    traits = 1 /* UIFontDescriptorSymbolicTraits.TraitItalic */;
                    break;
                case commonModule.DataFormFontStyle.BoldItalic:
                    traits = 2 /* UIFontDescriptorSymbolicTraits.TraitBold */ | 1 /* UIFontDescriptorSymbolicTraits.TraitItalic */;
                    break;
            }
            if (!font) {
                font = UIFont.systemFontOfSize(fontSize);
            }
            let newFont = UIFont.fontWithDescriptorSize(font.fontDescriptor.fontDescriptorWithSymbolicTraits(traits), fontSize);
            if (newFont) {
                font = newFont;
            }
        }
        return font;
    }
}
///////////////////////////////////////////////
export class PropertyGroup extends commonModule.PropertyGroup {
    constructor() {
        super();
    }
    // todo: consider if these properties need handles at all
    onNameChanged(oldValue, newValue) { }
    onHiddenChanged(oldValue, newValue) { }
    onCollapsibleChanged(oldValue, newValue) { }
    onTitleStyleChanged(oldValue, newValue) { }
    onPropertiesChanged(oldValue, newValue) { }
}
export class EntityProperty extends commonModule.EntityProperty {
    constructor() {
        super();
        this._shouldSkipEditorUpdate = false;
    }
    get ios() {
        return this._ios;
    }
    get isValid() {
        if (this.ios) {
            return this.ios.isValid;
        }
        return true;
    }
    get value() {
        if (this.ios) {
            return this.ios.originalValue;
        }
        return undefined;
    }
    get valueCandidate() {
        if (this.ios) {
            return this.ios.valueCandidate;
        }
        return undefined;
    }
    _linkPropertyWithNative(value) {
        this._ios = value;
        this._ios.pickersUseIndexValue = false;
        this._onNativeSet();
    }
    _updateNativeEditor(nativeEditor) {
        if (!this.editor) {
            this._createEditorFromNative(nativeEditor);
        }
        else {
            PropertyEditorHelper._linkEditorWithNative(this.editor, nativeEditor);
        }
    }
    _createEditorFromNative(nativeEditor) {
        let type = PropertyEditor._getNativeEditorType(nativeEditor);
        this._shouldSkipEditorUpdate = true;
        let propertyEditor = new PropertyEditor();
        propertyEditor.type = type;
        PropertyEditorHelper._linkEditorWithNative(propertyEditor, nativeEditor);
        this.editor = propertyEditor;
        this._shouldSkipEditorUpdate = false;
    }
    _onNativeSet() {
        this.updateNativeValidators(this.validators);
        this.updateNativeConverter(this.converter);
        this.updateNativeValuesProvider(this.valuesProviderArray);
        this.updateNativeAutoCompleteDisplayMode(this.autoCompleteDisplayMode);
        this.updateNativeDisplayName(this.displayName);
        this.updateNativeIndex(this.index);
        this.updateNativeColumnIndex(this.columnIndex);
        this.updateNativeHidden(this.hidden);
        this.updateNativeReadOnly(this.readOnly);
        this.updateNativeRequired(this.required);
        this.updateNativeHintText(this.hintText);
        this.updateNativeImageResource(this.imageResource);
        this.updateNativeEditorParams(this.editor);
        this.updateNativeEditor(this.editor);
    }
    onEditorTypeChanged() {
        let newEditor = new PropertyEditor();
        newEditor.type = this.editor.type;
        newEditor.propertyEditorStyle = this.editor.propertyEditorStyle;
        newEditor.params = this.editor.params;
        this.editor = newEditor;
    }
    updateNativeEditorParams(value) {
        if (!this._ios || !value || !value.params) {
            return;
        }
        let editorParams = value.params;
        if (editorParams.minimum && editorParams.maximum) {
            if (!isNaN(editorParams.minimum) && !isNaN(editorParams.maximum)) {
                this._ios.range = TKRange.rangeWithMinimumAndMaximum(editorParams.minimum, editorParams.maximum);
            }
        }
        if (editorParams.step && !isNaN(editorParams.step)) {
            this._ios.step = editorParams.step;
        }
    }
    updateNativeEditor(value) {
        if (!this._ios || !value) {
            return;
        }
        if (value instanceof CustomPropertyEditor) {
            this._ios.editorClass = TKDataFormCustomEditor.class();
            return;
        }
        this._ios.editorClass = value.editorClass;
    }
    updateNativeValidators(value) {
        if (!this._ios || !value) {
            return;
        }
        let validatorSet = NSMutableArray.new();
        for (let k = 0; k < value.length; k++) {
            let validatorBase = value[k];
            let aValidator = validatorBase.ios;
            validatorSet.addObject(aValidator);
        }
        this._ios.validators = validatorSet;
    }
    updateNativeValuesProvider(value) {
        if (!this._ios || !value) {
            return;
        }
        let nativeSource = NSMutableArray.new();
        for (let i = 0; i < value.length; i++) {
            let nativeValue = value[i];
            if (typeof nativeValue === 'string') {
                nativeValue = nativeValue.trim();
            }
            nativeSource.addObject(nativeValue);
        }
        this._ios.valuesProvider = nativeSource;
        if (this.editor && this.editor.ios) {
            this.editor.ios.update();
        }
    }
    updateNativeAutoCompleteDisplayMode(value) {
        if (!this._ios || !value) {
            return;
        }
        let nativeValue;
        switch (value) {
            case AutoCompleteDisplayMode.Plain:
                nativeValue = 0 /* TKAutoCompleteDisplayMode.Plain */;
                break;
            case AutoCompleteDisplayMode.Tokens:
                nativeValue = 1 /* TKAutoCompleteDisplayMode.Tokens */;
                break;
        }
        if (nativeValue !== undefined) {
            this._ios.autoCompleteDisplayMode = nativeValue;
        }
        else {
            console.log('autoCompleteDisplayMode cannot be set to: ' + value);
        }
    }
    updateNativeImageResource(value) {
        if (!this._ios || value === undefined) {
            return;
        }
        if (value != null) {
            let image = UIImage.imageNamed(value);
            this._ios.image = image;
        }
        else {
            this._ios.image = null;
        }
    }
    updateNativeDisplayName(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.displayName = value;
    }
    updateNativeIndex(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.index = value;
    }
    updateNativeConverter(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.converter = TKDataFormConverterImplementation.new().initWithConverter(value);
        if (this.editor && this.editor.ios) {
            this.editor.ios.loadPropertyValue();
        }
    }
    updateNativeColumnIndex(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.columnIndex = value;
    }
    updateNativeHidden(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.hidden = value;
    }
    updateNativeReadOnly(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.readOnly = value;
    }
    updateNativeRequired(value) {
        if (!this._ios || value == null) {
            return;
        }
        this._ios.required = value;
    }
    updateNativeHintText(value) {
        if (!this._ios || !value) {
            return;
        }
        this._ios.hintText = value;
    }
}
export class DataFormEditorLabel extends commonModule.DataFormEditorLabel {
    constructor(editor) {
        super();
        this._editor = editor;
        this._ios = editor.ios.textLabel;
    }
    get ios() {
        return this._ios;
    }
    createNativeView() {
        return this._ios;
    }
    disposeNativeView() {
        this._editor = null;
        this._ios = null;
    }
    [paddingLeftProperty.setNative](value) {
        let borderLeft = isNaN(+this.style.borderLeftWidth) ? 0 : +this.style.borderLeftWidth;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: value + borderLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [borderLeftWidthProperty.setNative](value) {
        let paddingLeft = isNaN(+this.style.paddingLeft) ? 0 : +this.style.paddingLeft;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: value + paddingLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [paddingTopProperty.setNative](value) {
        let borderTop = isNaN(+this.style.borderTopWidth) ? 0 : +this.style.borderTopWidth;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + borderTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [borderTopWidthProperty.setNative](value) {
        let paddingTop = isNaN(+this.style.paddingTop) ? 0 : +this.style.paddingTop;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + paddingTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [paddingRightProperty.setNative](value) {
        let borderRight = isNaN(+this.style.borderRightWidth) ? 0 : +this.style.borderRightWidth;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + borderRight,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [borderRightWidthProperty.setNative](value) {
        let paddingRight = isNaN(+this.style.paddingRight) ? 0 : +this.style.paddingRight;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + paddingRight,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [paddingBottomProperty.setNative](value) {
        let borderBottom = isNaN(+this.style.borderBottomWidth) ? 0 : +this.style.borderBottomWidth;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + borderBottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [borderBottomWidthProperty.setNative](value) {
        let paddingBottom = isNaN(+this.style.paddingBottom) ? 0 : +this.style.paddingBottom;
        let currentInsets = this._editor.ios.textLabel.textInsets;
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + paddingBottom,
        });
        this._editor.ios.textLabel.textInsets = insets;
    }
    [marginLeftProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: value,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginTopProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: value,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginRightProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: value,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginBottomProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: value,
        });
        this.nativeViewProtected.margins = margins;
    }
    [colorProperty.setNative](value) {
        const nativeColor = value instanceof Color ? value.ios : value;
        this._ios.textColor = nativeColor;
    }
    [visibilityProperty.setNative](value) {
        PropertyEditorHelper._updateLabelHidden(this._editor, value === 'hidden' || value === 'collapse');
    }
    [fontInternalProperty.setNative](value) {
        const nativeFont = value instanceof Font ? value.getUIFont(this._ios.font) : value;
        this._ios.font = nativeFont;
    }
    [widthProperty.setNative](value) {
        PropertyEditorHelper._updateLabelWidth(this._editor, value);
    }
    [commonModule.PropertyEditor.positionProperty.setNative](value) {
        if (!value) {
            return;
        }
        if (value.toLowerCase() === 'left') {
            PropertyEditorHelper._updateLabelPosition(this._editor, commonModule.DataFormLabelPosition.Left);
        }
        else if (value.toLowerCase() === 'top') {
            PropertyEditorHelper._updateLabelPosition(this._editor, commonModule.DataFormLabelPosition.Top);
        }
    }
}
export class DataFormEditorCore extends commonModule.DataFormEditorCore {
    constructor(editor) {
        super();
        this._editor = editor;
        this._ios = this._editor.ios.editorCore;
    }
    get ios() {
        return this._ios;
    }
    createNativeView() {
        return this._ios;
    }
    [paddingLeftProperty.setNative](value) {
        let borderLeft = isNaN(+this.style.borderLeftWidth) ? 0 : +this.style.borderLeftWidth;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: value + borderLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [borderLeftWidthProperty.setNative](value) {
        let paddingLeft = isNaN(+this.style.paddingLeft) ? 0 : +this.style.paddingLeft;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: value + paddingLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [paddingTopProperty.setNative](value) {
        let borderTop = isNaN(+this.style.borderTopWidth) ? 0 : +this.style.borderTopWidth;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + borderTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [borderTopWidthProperty.setNative](value) {
        let paddingTop = isNaN(+this.style.paddingTop) ? 0 : +this.style.paddingTop;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + paddingTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [paddingRightProperty.setNative](value) {
        let borderRight = isNaN(+this.style.borderRightWidth) ? 0 : +this.style.borderRightWidth;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + borderRight,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [borderRightWidthProperty.setNative](value) {
        let paddingRight = isNaN(+this.style.paddingRight) ? 0 : +this.style.paddingRight;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + paddingRight,
            bottom: currentInsets.bottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [paddingBottomProperty.setNative](value) {
        let borderBottom = isNaN(+this.style.borderBottomWidth) ? 0 : +this.style.borderBottomWidth;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + borderBottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [borderBottomWidthProperty.setNative](value) {
        let paddingBottom = isNaN(+this.style.paddingBottom) ? 0 : +this.style.paddingBottom;
        let currentInsets = this._editor.ios.editorCore.insets;
        if (!currentInsets) {
            return;
        }
        let insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + paddingBottom,
        });
        this._editor.ios.editorCore.insets = insets;
    }
    [marginLeftProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: value,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginTopProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: value,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginRightProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: value,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginBottomProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: value,
        });
        this.nativeViewProtected.margins = margins;
    }
    [colorProperty.setNative](value) {
        const nativeColor = value instanceof Color ? value.ios : value;
        this._editor.ios.editorColor = nativeColor;
        this._editor.ios.style.accessoryArrowStroke.color = nativeColor;
    }
    [fontInternalProperty.setNative](value) {
        const defaultFont = this._editor.ios.editorFont ? this._editor.ios.editorFont : this._editor.ios.textLabel.font;
        const nativeFont = value instanceof Font ? value.getUIFont(defaultFont) : value;
        this._editor.ios.editorFont = nativeFont;
    }
}
// NOTE: currently we don't have specific class for every one of the editors since they don't have specific properties, with small exceptions
export class PropertyEditor extends commonModule.PropertyEditor {
    get ios() {
        return this._ios;
    }
    set ios(value) {
        this._ios = value;
        this.setNativeView(value);
        if (this._label) {
            this._removeView(this._label);
        }
        if (this._editorCore) {
            this._removeView(this._editorCore);
        }
        if (this._ios) {
            this._label = new DataFormEditorLabel(this);
            this._editorCore = new DataFormEditorCore(this);
            this._addView(this._label);
            this._addView(this._editorCore);
        }
        else {
            this._label = null;
            this._editorCore = null;
        }
    }
    get label() {
        return this._label;
    }
    get editorCore() {
        return this._editorCore;
    }
    get editorClass() {
        return this._editorClass;
    }
    [paddingLeftProperty.setNative](value) {
        let borderLeft = isNaN(+this.style.borderLeftWidth) ? 0 : +this.style.borderLeftWidth;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: value + borderLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [borderLeftWidthProperty.setNative](value) {
        let paddingLeft = isNaN(+this.style.paddingLeft) ? 0 : +this.style.paddingLeft;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: value + paddingLeft,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [paddingTopProperty.setNative](value) {
        let borderTop = isNaN(+this.style.borderTopWidth) ? 0 : +this.style.borderTopWidth;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + borderTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [borderTopWidthProperty.setNative](value) {
        let paddingTop = isNaN(+this.style.paddingTop) ? 0 : +this.style.paddingTop;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: value + paddingTop,
            right: currentInsets.right,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [paddingRightProperty.setNative](value) {
        let borderRight = isNaN(+this.style.borderRightWidth) ? 0 : +this.style.borderRightWidth;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + borderRight,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [borderRightWidthProperty.setNative](value) {
        let paddingRight = isNaN(+this.style.paddingRight) ? 0 : +this.style.paddingRight;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: value + paddingRight,
            bottom: currentInsets.bottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [paddingBottomProperty.setNative](value) {
        let borderBottom = isNaN(+this.style.borderBottomWidth) ? 0 : +this.style.borderBottomWidth;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + borderBottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [borderBottomWidthProperty.setNative](value) {
        let paddingBottom = isNaN(+this.style.paddingBottom) ? 0 : +this.style.paddingBottom;
        let currentInsets = this.nativeViewProtected.style.insets;
        const insets = new UIEdgeInsets({
            left: currentInsets.left,
            top: currentInsets.top,
            right: currentInsets.right,
            bottom: value + paddingBottom,
        });
        this.nativeViewProtected.style.insets = insets;
    }
    [marginLeftProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: value,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginTopProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: value,
            right: currentMargins.right,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginRightProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: value,
            bottom: currentMargins.bottom,
        });
        this.nativeViewProtected.margins = margins;
    }
    [marginBottomProperty.setNative](value) {
        let currentMargins = this.nativeViewProtected.margins;
        let margins = new UIEdgeInsets({
            left: currentMargins.left,
            top: currentMargins.top,
            right: currentMargins.right,
            bottom: value,
        });
        this.nativeViewProtected.margins = margins;
    }
    [commonModule.PropertyEditor.separatorColorProperty.setNative](value) {
        PropertyEditorHelper._updateSeparatorColor(this, value);
    }
    createNativeView() {
        return this._ios ? this._ios : super.createNativeView();
    }
    onStylePropertyChanged(propertyName) {
        PropertyEditorHelper.applyStyleForProperty(this, propertyName);
    }
    onParamsChanged(oldValue, newValue) {
        PropertyEditorHelper._applyParams(this);
    }
    onParamsPropertyChanged(propertyName) {
        PropertyEditorHelper._applyParams(this);
    }
    onTypeChanged(oldValue, newValue) {
        this._updateEditorClass();
    }
    _updateEditorClass() {
        if (this.type == null) {
            return;
        }
        switch (this.type) {
            case commonModule.DataFormEditorType.Text:
                this._editorClass = TKDataFormTextFieldEditor.class();
                break;
            case commonModule.DataFormEditorType.MultilineText:
                this._editorClass = TKDataFormMultilineTextEditor.class();
                break;
            case commonModule.DataFormEditorType.Email:
                this._editorClass = TKDataFormEmailEditor.class();
                break;
            case commonModule.DataFormEditorType.Password:
                this._editorClass = TKDataFormPasswordEditor.class();
                break;
            case commonModule.DataFormEditorType.Phone:
                this._editorClass = TKDataFormPhoneEditor.class();
                break;
            case commonModule.DataFormEditorType.Decimal:
                this._editorClass = TKDataFormDecimalEditor.class();
                break;
            case commonModule.DataFormEditorType.Number:
                this._editorClass = TKDataFormNumberEditor.class();
                break;
            case commonModule.DataFormEditorType.Switch:
                this._editorClass = TKDataFormSwitchEditor.class();
                break;
            case commonModule.DataFormEditorType.Stepper:
                this._editorClass = TKDataFormStepperEditor.class();
                break;
            case commonModule.DataFormEditorType.Slider:
                this._editorClass = TKDataFormSliderEditor.class();
                break;
            case commonModule.DataFormEditorType.SegmentedEditor:
                this._editorClass = TKDataFormSegmentedEditor.class();
                break;
            case commonModule.DataFormEditorType.DatePicker:
                this._editorClass = TKDataFormDatePickerEditor.class();
                break;
            case commonModule.DataFormEditorType.TimePicker:
                this._editorClass = TKDataFormTimePickerEditor.class();
                break;
            case commonModule.DataFormEditorType.Picker:
                this._editorClass = TKDataFormPickerViewEditor.class();
                break;
            case commonModule.DataFormEditorType.List:
                this._editorClass = TKDataFormOptionsEditor.class();
                break;
            case commonModule.DataFormEditorType.AutoCompleteInline:
                this._editorClass = TKDataFormAutoCompleteInlineEditor.class();
                break;
            case commonModule.DataFormEditorType.Label:
                this._editorClass = TKDataFormLabelEditor.class();
                break;
            default:
                console.log('WARNING: Unsupported editor type: ' + this.type);
        }
    }
    static _getNativeEditorType(nativeEditor) {
        if (nativeEditor instanceof TKDataFormMultilineTextEditor) {
            return commonModule.DataFormEditorType.MultilineText;
        }
        if (nativeEditor instanceof TKDataFormEmailEditor) {
            return commonModule.DataFormEditorType.Email;
        }
        if (nativeEditor instanceof TKDataFormPasswordEditor) {
            return commonModule.DataFormEditorType.Password;
        }
        if (nativeEditor instanceof TKDataFormPhoneEditor) {
            return commonModule.DataFormEditorType.Phone;
        }
        if (nativeEditor instanceof TKDataFormDecimalEditor) {
            return commonModule.DataFormEditorType.Decimal;
        }
        if (nativeEditor instanceof TKDataFormNumberEditor) {
            return commonModule.DataFormEditorType.Number;
        }
        if (nativeEditor instanceof TKDataFormSwitchEditor) {
            return commonModule.DataFormEditorType.Switch;
        }
        if (nativeEditor instanceof TKDataFormStepperEditor) {
            return commonModule.DataFormEditorType.Stepper;
        }
        if (nativeEditor instanceof TKDataFormSliderEditor) {
            return commonModule.DataFormEditorType.Slider;
        }
        if (nativeEditor instanceof TKDataFormSegmentedEditor) {
            return commonModule.DataFormEditorType.SegmentedEditor;
        }
        if (nativeEditor instanceof TKDataFormTimePickerEditor) {
            return commonModule.DataFormEditorType.TimePicker;
        }
        if (nativeEditor instanceof TKDataFormDatePickerEditor) {
            return commonModule.DataFormEditorType.DatePicker;
        }
        if (nativeEditor instanceof TKDataFormPickerViewEditor) {
            return commonModule.DataFormEditorType.Picker;
        }
        if (nativeEditor instanceof TKDataFormOptionsEditor) {
            return commonModule.DataFormEditorType.List;
        }
        if (nativeEditor instanceof TKDataFormAutoCompleteInlineEditor) {
            return commonModule.DataFormEditorType.AutoCompleteInline;
        }
        if (nativeEditor instanceof TKDataFormLabelEditor) {
            return commonModule.DataFormEditorType.Label;
        }
        return commonModule.DataFormEditorType.Text;
    }
}
export class CustomPropertyEditor extends commonModule.CustomPropertyEditor {
    constructor() {
        super();
        this._nativeDelegate = TKDataFormCustomEditorDelegateImplementation.new().initWithOwner(this);
    }
    get ios() {
        return this._ios;
    }
    set ios(value) {
        this._ios = value;
        this.setNativeView(value);
        if (this._label) {
            this._removeView(this._label);
        }
        if (this._editorCore) {
            this._removeView(this._editorCore);
        }
        if (this._ios) {
            this._label = new DataFormEditorLabel(this);
            this._editorCore = new DataFormEditorCore(this);
            this._addView(this._label);
            this._addView(this._editorCore);
        }
        else {
            this._label = null;
            this._editorCore = null;
        }
    }
    get label() {
        return this._label;
    }
    get editorCore() {
        return this._editorCore;
    }
    get editorClass() {
        return this._editorClass;
    }
    onStylePropertyChanged(propertyName) {
        PropertyEditorHelper.applyStyleForProperty(this, propertyName);
    }
    onParamsChanged(oldValue, newValue) {
        PropertyEditorHelper._applyParams(this);
    }
    onParamsPropertyChanged(propertyName) {
        PropertyEditorHelper._applyParams(this);
    }
    onTypeChanged(oldValue, newValue) {
        console.log("WARNING: You can't change CustomPropertyEditor's type");
    }
    notifyValueChanged() {
        if (this.ios) {
            this.ios.notifyValueChange();
        }
    }
}
export class PropertyEditorHelper {
    static _linkEditorWithNative(editor, value) {
        if (editor instanceof CustomPropertyEditor) {
            editor.ios = value;
        }
        else {
            editor.ios = value;
        }
        if (!editor.propertyEditorStyle) {
            editor.propertyEditorStyle = new commonModule.PropertyEditorStyle();
        }
        if (!editor.params) {
            editor.params = new commonModule.PropertyEditorParams();
        }
        PropertyEditorHelper._onNativeSet(editor);
    }
    static _onNativeSet(editor) {
        if (!editor.ios) {
            return;
        }
        if (editor instanceof CustomPropertyEditor) {
            editor.ios.delegate = editor._nativeDelegate;
        }
        else {
            if (!editor.type) {
                editor.type = PropertyEditor._getNativeEditorType(editor.ios);
            }
        }
        PropertyEditorHelper._applyParams(editor);
    }
    static _updateLabelTextColor(editor, labelTextColor) {
        if (!editor.ios || labelTextColor === undefined) {
            return;
        }
        editor.ios.textLabel.textColor = labelTextColor.ios;
    }
    static _updateLabelFont(editor, labelFontName, labelTextSize, labelFontStyle) {
        if (!editor.ios || (labelFontName === undefined && labelFontStyle === undefined && labelTextSize === undefined)) {
            return;
        }
        editor.ios.textLabel.font = RadDataForm.getFontWithProperties(labelFontName, labelTextSize, labelFontStyle);
    }
    static _updateLabelOffset(editor, labelHorizontalOffset, labelVerticalOffset) {
        if (!editor.ios || (labelHorizontalOffset === undefined && labelVerticalOffset === undefined)) {
            return;
        }
        editor.ios.style.textLabelOffset = {
            horizontal: isNaN(labelHorizontalOffset) ? 0 : labelHorizontalOffset,
            vertical: isNaN(labelVerticalOffset) ? 0 : labelVerticalOffset,
        };
    }
    static _updateEditorOffset(editor, editorHorizontalOffset, editorVerticalOffset) {
        if (!editor.ios || (editorHorizontalOffset === undefined && editorVerticalOffset === undefined)) {
            return;
        }
        editor.ios.style.editorOffset = {
            horizontal: isNaN(editorHorizontalOffset) ? 0 : editorHorizontalOffset,
            vertical: isNaN(editorVerticalOffset) ? 0 : editorVerticalOffset,
        };
    }
    static _updateEditorFillColor(editor, editorFillColor) {
        if (!editor.ios || editorFillColor === undefined) {
            return;
        }
        editor.ios.style.fill = TKSolidFill.solidFillWithColor(editorFillColor.ios);
    }
    static _updateEditorStroke(editor, editorStrokeColor, editorStrokeWidth) {
        if (!editor.ios || (editorStrokeColor === undefined && editorStrokeWidth === undefined)) {
            return;
        }
        let stroke = TKStroke.new();
        if (editorStrokeWidth) {
            stroke.width = editorStrokeWidth;
        }
        if (editorStrokeColor) {
            stroke.color = editorStrokeColor.ios;
        }
        editor.ios.style.stroke = stroke;
    }
    static _updateLabelHidden(editor, labelHidden) {
        if (!editor.ios || labelHidden === undefined) {
            return;
        }
        editor.ios.style.textLabelDisplayMode = labelHidden ? 1 /* TKDataFormEditorTextLabelDisplayMode.Hidden */ : 0 /* TKDataFormEditorTextLabelDisplayMode.Show */;
    }
    static _updateLabelPosition(editor, labelPosition) {
        if (!editor.ios || labelPosition === undefined) {
            return;
        }
        if (labelPosition === commonModule.DataFormLabelPosition.Left) {
            editor.ios.labelPosition = 0 /* TKDataFormLabelPosition.TKDataFormLabelPositionLeft */;
            editor.ios.setNeedsLayout();
        }
        else if (labelPosition === commonModule.DataFormLabelPosition.Top) {
            editor.ios.labelPosition = 1 /* TKDataFormLabelPosition.TKDataFormLabelPositionTop */;
            editor.ios.setNeedsLayout();
        }
    }
    static _updateLabelWidth(editor, labelWidth) {
        if (!editor.ios || labelWidth === -1) {
            return;
        }
        editor.ios.style.textLabelWidth = labelWidth;
        editor.ios.setNeedsLayout();
    }
    static _updateSeparatorColor(editor, separatorColor) {
        if (!editor.ios || separatorColor === undefined) {
            return;
        }
        editor.ios.style.separatorColor = TKSolidFill.solidFillWithColor(separatorColor.ios);
        editor.ios.setNeedsDisplay();
    }
    static _applyParams(editor) {
        let editorParams = editor.params;
        if (!editorParams) {
            return;
        }
        if (editorParams.minimum && editorParams.maximum) {
            if (!isNaN(editorParams.minimum) && !isNaN(editorParams.maximum)) {
                PropertyEditorHelper._updateNativeRange(editor, TKRange.rangeWithMinimumAndMaximum(editorParams.minimum, editorParams.maximum));
            }
        }
        if (editorParams.step && !isNaN(editorParams.step)) {
            PropertyEditorHelper._updateNativeStep(editor, editorParams.step);
        }
    }
    static _updateNativeRange(editor, range) {
        if (!editor.ios) {
            return;
        }
        if (editor.ios.property.range === range) {
            return;
        }
        editor.ios.property.range = range;
        editor.ios.update();
    }
    static _updateNativeStep(editor, step) {
        if (!editor.ios) {
            return;
        }
        if (editor.ios.property.step === step) {
            return;
        }
        editor.ios.property.step = step;
        editor.ios.update();
    }
    static applyStyle(editor) {
        if (!editor.propertyEditorStyle || !editor.ios) {
            return;
        }
        PropertyEditorHelper._updateLabelTextColor(editor, editor.propertyEditorStyle.labelTextColor);
        PropertyEditorHelper._updateLabelFont(editor, editor.propertyEditorStyle.labelFontName, editor.propertyEditorStyle.labelTextSize, editor.propertyEditorStyle.labelFontStyle);
        PropertyEditorHelper._updateLabelOffset(editor, editor.propertyEditorStyle.labelHorizontalOffset, editor.propertyEditorStyle.labelVerticalOffset);
        PropertyEditorHelper._updateEditorOffset(editor, editor.propertyEditorStyle.editorHorizontalOffset, editor.propertyEditorStyle.editorVerticalOffset);
        PropertyEditorHelper._updateEditorFillColor(editor, editor.propertyEditorStyle.fillColor);
        PropertyEditorHelper._updateEditorStroke(editor, editor.propertyEditorStyle.strokeColor, editor.propertyEditorStyle.strokeWidth);
        PropertyEditorHelper._updateLabelHidden(editor, editor.propertyEditorStyle.labelHidden);
        PropertyEditorHelper._updateLabelPosition(editor, editor.propertyEditorStyle.labelPosition);
        PropertyEditorHelper._updateLabelWidth(editor, editor.propertyEditorStyle.labelWidth);
        PropertyEditorHelper._updateSeparatorColor(editor, editor.propertyEditorStyle.separatorColor);
        PropertyEditorHelper.setNeedsLayout(editor);
        PropertyEditorHelper.setNeedsDisplay(editor);
    }
    static setNeedsDisplay(editor) {
        if (editor.ios) {
            editor.ios.setNeedsDisplay();
        }
    }
    static setNeedsLayout(editor) {
        if (editor.ios) {
            editor.ios.setNeedsLayout();
        }
    }
    static applyStyleForProperty(editor, propertyName) {
        if (!editor.propertyEditorStyle || !editor.ios) {
            return;
        }
        switch (propertyName) {
            case 'labelTextColor':
                PropertyEditorHelper._updateLabelTextColor(editor, editor.propertyEditorStyle.labelTextColor);
                break;
            case 'labelFontName':
            case 'labelFontStyle':
            case 'labelTextSize':
                PropertyEditorHelper._updateLabelFont(editor, editor.propertyEditorStyle.labelFontName, editor.propertyEditorStyle.labelTextSize, editor.propertyEditorStyle.labelFontStyle);
                break;
            case 'labelHorizontalOffset':
            case 'labelVerticalOffset':
                PropertyEditorHelper._updateLabelOffset(editor, editor.propertyEditorStyle.labelHorizontalOffset, editor.propertyEditorStyle.labelVerticalOffset);
                PropertyEditorHelper.setNeedsLayout(editor);
                break;
            case 'editorHorizontalOffset':
            case 'editorVerticalOffset':
                PropertyEditorHelper._updateEditorOffset(editor, editor.propertyEditorStyle.editorHorizontalOffset, editor.propertyEditorStyle.editorVerticalOffset);
                PropertyEditorHelper.setNeedsLayout(editor);
                break;
            case 'fillColor':
                PropertyEditorHelper._updateEditorFillColor(editor, editor.propertyEditorStyle.fillColor);
                PropertyEditorHelper.setNeedsDisplay(editor);
                break;
            case 'strokeColor':
            case 'strokeWidth':
                PropertyEditorHelper._updateEditorStroke(editor, editor.propertyEditorStyle.strokeColor, editor.propertyEditorStyle.strokeWidth);
                PropertyEditorHelper.setNeedsDisplay(editor);
                break;
            case 'labelHidden':
                PropertyEditorHelper._updateLabelHidden(editor, editor.propertyEditorStyle.labelHidden);
                PropertyEditorHelper.setNeedsLayout(editor);
                break;
            case 'labelPosition':
                PropertyEditorHelper._updateLabelPosition(editor, editor.propertyEditorStyle.labelPosition);
                PropertyEditorHelper.setNeedsLayout(editor);
                break;
            case 'labelWidth':
                PropertyEditorHelper._updateLabelWidth(editor, editor.propertyEditorStyle.labelWidth);
                PropertyEditorHelper.setNeedsLayout(editor);
                break;
            case 'separatorColor':
                PropertyEditorHelper._updateSeparatorColor(editor, editor.propertyEditorStyle.separatorColor);
                PropertyEditorHelper.setNeedsDisplay(editor);
                break;
        }
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Validators
export class PropertyValidator extends commonModule.PropertyValidator {
    constructor() {
        super();
        this._ios = TKDataFormManualValidator.new();
        this._nativeDelegate = TKDataFormValidationProviderDelegateImplementation.new().initWithOwner(this);
        this._ios.delegate = this._nativeDelegate;
        if (this.errorMessage === undefined) {
            this.errorMessage = 'This is not valid.';
        }
    }
    get ios() {
        return this._ios;
    }
    validate(value, propertyName) {
        return true;
    }
}
export class MinimumLengthValidator extends commonModule.MinimumLengthValidator {
    constructor() {
        super();
        this._ios = TKDataFormMinimumLengthValidator.new();
    }
    get ios() {
        return this._ios;
    }
    onLengthChanged(oldValue, newValue) {
        if (!isNaN(+newValue)) {
            this.ios.minimumLength = newValue;
        }
    }
}
export class MaximumLengthValidator extends commonModule.MaximumLengthValidator {
    constructor() {
        super();
        this._ios = TKDataFormMaximumLengthValidator.new();
    }
    get ios() {
        return this._ios;
    }
    onLengthChanged(oldValue, newValue) {
        if (!isNaN(newValue)) {
            this.ios.maximumLegth = newValue;
        }
    }
}
export class EmailValidator extends commonModule.EmailValidator {
    constructor() {
        super();
        this._ios = TKDataFormEmailValidator.new();
    }
    get ios() {
        return this._ios;
    }
}
export class NonEmptyValidator extends commonModule.NonEmptyValidator {
    constructor() {
        super();
        this._ios = TKDataFormNonEmptyValidator.new();
    }
    get ios() {
        return this._ios;
    }
}
export class RangeValidator extends commonModule.RangeValidator {
    constructor() {
        super();
        this._ios = TKDataFormRangeValidator.new();
    }
    get ios() {
        return this._ios;
    }
    onMinimumChanged(oldValue, newValue) {
        if (!isNaN(+newValue)) {
            if (this.ios.range) {
                this.ios.range.minimum = newValue;
            }
            else {
                this.ios.range = TKRange.rangeWithMinimumAndMaximum(newValue, newValue * 2);
            }
        }
    }
    onMaximumChanged(oldValue, newValue) {
        if (!isNaN(+newValue)) {
            if (this.ios.range) {
                this.ios.range.maximum = newValue;
            }
            else {
                this.ios.range = TKRange.rangeWithMinimumAndMaximum(newValue / 2, newValue);
            }
        }
    }
}
export class PhoneValidator extends commonModule.PhoneValidator {
    constructor() {
        super();
        this._ios = TKDataFormPhoneValidator.new();
    }
    get ios() {
        return this._ios;
    }
}
export class RegExValidator extends commonModule.RegExValidator {
    constructor() {
        super();
        this._ios = TKDataFormRegExValidator.new();
    }
    get ios() {
        return this._ios;
    }
    onRegExChanged(oldValue, newValue) {
        this._ios.regEx = newValue;
    }
}
export class IsTrueValidator extends commonModule.IsTrueValidator {
    constructor() {
        super();
        this._ios = TKDataFormIsTrueValidator.new();
    }
    get ios() {
        return this._ios;
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Converters
export class StringToDateConverter extends commonModule.StringToDateConverter {
    constructor() {
        super();
        this._ios = TKDataFormStringToDateConverter.new();
    }
    get ios() {
        return this._ios;
    }
}
export class StringToTimeConverter extends commonModule.StringToTimeConverter {
    constructor() {
        super();
        this._ios = TKDataFormStringToTimeConverter.new();
    }
    get ios() {
        return this._ios;
    }
}
//# sourceMappingURL=index.ios.js.map