﻿var FormBuilderVisibility = Class.create({
    initialize: function(linkedItems, invisibleElementsHiddenField) {
        this.linkedItems = linkedItems;
        this.invisibleElementsHiddenField = $(invisibleElementsHiddenField);
        this.wireLinkedItems();
        this.setValidators();
        this.updateValidatorHidden();
    },

    wireLinkedItems: function() {
        this._linkedHash = new Hash();
        for (var i = 0; i < this.linkedItems.length; i++) {
            var item = this.linkedItems[i];
            this._linkedHash.set(item.id, item);
            var trigger = $(item.id);

            if (trigger != null) {
                if (trigger.nodeName.toLowerCase() == "input" || trigger.nodeName.toLowerCase() == "textarea" || trigger.nodeName.toLowerCase() == "select") {
                    this.setLinkedEvents(trigger);
                }
                else {
                    // Handle Radio Button List. to do need to handle checkbox list.
                    var radios = trigger.select('input');
                    var radiosDislpay = false;
                    for (var j = 0; j < radios.length; j++) {
                        radios[j].observe('click', this.linkedItemChanged.bind(this));
                        if (radios[j].type == "radio") {
                            if (Form.Element.getValue(radios[j]) != null) {
                                this.updateLinkedVisibility(radios[j]);
                                radiosDislpay = true;
                            }
                        }
                        else if (radios[j].type == "checkbox")
                            this.updateLinkedVisibility(radios[j]);
                    }

                    if (radiosDislpay == false && radios.length > 0) {
                        if (radios[0].type == "radio")
                            this.setLinkedRadio(radios[0]);
                    }
                }
            }
            else {
                var linked = this._linkedHash.get(item.id);
                if (linked != null) {
                    for (var j = 0; j < linked.linkedControls.length; j++) {
                        var linkedElement = $(linked.linkedControls[j].id);

                        var linkedElementWrapper;
                        if (linkedElement != null) {
                            if (linkedElement.hasClassName('FormContainer')) {
                                linkedElementWrapper = linkedElement;
                            }
                            else {
                                var ancestors = linkedElement.ancestors();
                                for (var i = 0; i < ancestors.length; i++) {
                                    if (ancestors[i].hasClassName('EnquiryLabelGroup')) {
                                        linkedElementWrapper = ancestors[i];
                                        break;
                                    }
                                }
                            }
                        }
                        if (linkedElementWrapper != null) {
                            var value = linked.linkedControls[j].value;
                            this.setVisibilityHiddenFieldValues(linkedElementWrapper, 'hidden');
                            linkedElementWrapper.hide();
                            this.AddKeyToInvisiableElementsHiddenField(linkedElement);
                            var validators = linkedElementWrapper.select('.EnquiryError');
                            for (var a = 0; a < validators.length; a++)
                                this.setValidatorEnabled(validators[a]);
                        }
                    }
                }
            }
        }
    },

    linkedItemChanged: function(e) {
        var element = Event.element(e)
        if (this.isRadNumericInputText(element)) {
            var elementInput = $(element.identify().replace('_text', ''));
            this.updateLinkedVisibility(elementInput);
        }
        else {
            this.updateLinkedVisibility(element);
        }
        this.updateValidatorHidden();
    },

    updateLinkedVisibility: function(element) {
        switch (element.type) {
            case "checkbox":
                this.setLinkedCheckBox(element);
                break;
            case "radio":
                this.setLinkedRadio(element);
                break;
            default:
                this.setLinkedControl(element);
                break;
        }
    },

    setLinkedEvents: function(element) {
        switch (element.type) {
            case "checkbox":
                element.observe('click', this.linkedItemChanged.bind(this));
                this.updateLinkedVisibility(element);
                break;
            case "radio":
                element.observe('click', this.linkedItemChanged.bind(this));
                this.updateLinkedVisibility(element);
                break;
            case "text":
            case "textarea":
                if (this.isRadNumericInputId(element)) {
                    var wrapperElement = $(element.identify() + "_text");
                    if (wrapperElement != null) {
                        wrapperElement.observe('keyup', this.linkedItemChanged.bind(this));
                        this.updateLinkedVisibility(element);
                    }
                }
                else {
                    element.observe('keyup', this.linkedItemChanged.bind(this));
                    this.updateLinkedVisibility(element);
                }
                break;
            default:
                element.observe('change', this.linkedItemChanged.bind(this));
                this.updateLinkedVisibility(element);
                break;
        }
    },

    isRadNumericInputId: function(element) {
        var radInputId = element.identify();
        return this.isRadNumericInput($(radInputId));
    },

    isRadNumericInputText: function(element) {
        var radInputId = element.identify().replace('_text', '');
        return this.isRadNumericInput($(radInputId));
    },

    isRadNumericInput: function(element) {
        var radNumeric = false;
        var radInputId = element.identify();
        var upElement = element.up('span');
        if (upElement != null) {
            var radInputs = upElement.select('input');
            if (radInputs.length > 1) {
                var containsNumberic = true;
                for (var i = 0; i < radInputs.length; i++) {
                    if (radInputs[i].identify() != radInputId) {
                        if (radInputs[i].identify().startsWith(radInputId) == false && (radInputs[i].identify().endWith('_text') || radInputs[i].identify().endWith('_value')))
                            containsNumberic = false;

                    }
                }
                radNumeric = true;
            }
        }
        return radNumeric;
    },

    isDisplay: function(element, expression) {
        var display = false;
        var exp = expression.toArray();
        var symbol = exp[0] + exp[1];
        var value = "";
        symbol = symbol.strip();
        for (var index = 2; index < exp.length; ++index)
            value += exp[index];

        var elementValue;
        var isMultiValuesList = false;

        switch (symbol) {
            case "=":
                symbol = "==";
                break;
            case "<>":
                symbol = "!=";
                break;
        }
        if (element.getValue() != null) {

            switch (element.type) {
                case "checkbox":
                    isMultiValuesList = (element.up('td') != null);
                    if (isMultiValuesList)
                        display = this.getCheckboxListDisplay(element, symbol, value);
                    else
                        elementValue = element.checked;
                    break;
                case "select-one":
                    elementValue = this.getSelectOneLabel(element);
                    break;
                case "select-multiple":
                    isMultiValuesList = true;
                    display = this.getSelectMultipleDisplay(element, symbol, value);
                    break;
                case "radio":
                    elementValue = this.getRadioLabel(element);

                    break;
                case "text":
                    if (this.isRadNumericInputId(element)) {
                        var wrapperElement = $(element.identify() + "_text");
                        if (wrapperElement != null)
                            elementValue = wrapperElement.getValue();
                    }
                    else {
                        elementValue = element.getValue();
                    }
                    break;
                default:
                    elementValue = element.getValue();
                    break;
            }

            if (isMultiValuesList == false) {
                if (element.type == "checkbox") {
                    element.checked;
                    var boolValue;
                    if (value.toLowerCase() == "yes" || value.toLowerCase() == "true")
                        boolValue = true;
                    else
                        boolValue = false;

                    display = element.checked == boolValue;
                }
                else {
                    if (isNaN(Math.abs(value)) || isNaN(Math.abs(elementValue))) // to check the numeric value
                        eval("display = '" + elementValue + "' " + symbol + " '" + value + "'");
                    else {
                        if (elementValue.length > 0)
                            eval("display = " + elementValue + " " + symbol + " " + value);
                    }
                }
            }
        }
        else {
            if (element.type == "checkbox") {
                isMultiValuesList = (element.up('td') != null);
                if (isMultiValuesList) {
                    display = this.getCheckboxListDisplay(element, symbol, value);
                }
                else {
                    element.checked;
                    var boolValue;
                    if (value.toLowerCase() == "yes" || value.toLowerCase() == "true")
                        boolValue = true;
                    else
                        boolValue = false;
                    display = element.checked == boolValue;
                }
            }
        }

        return display;
    },

    getRadioLabel: function(element) {
        var item = element.up('td').select('label');
        return item[0].innerHTML;
    },

    getSelectOneLabel: function(element) {
        var option = element.options[element.selectedIndex];
        return option.text;
    },

    getSelectMultipleDisplay: function(element, symbol, value) {
        var display = false;
        var checkedValues = new Array();
        var i = 0;
        for (var index = 0; index < element.options.length; ++index) {
            var item = element[index];
            if (item.selected) {
                checkedValues[i] = item.text;
                i++;
            }
        }

        if (symbol == "==") //Remeber we only handle equal and not equal ingore the rest of them.
        {
            for (var index = 0; index < checkedValues.length; ++index) {
                if (checkedValues[index] == value) {
                    display = true;
                    break;
                }
            }
        }
        else if (symbol == "!=") {
            display = true;
            for (var index = 0; index < checkedValues.length; ++index) {
                if (checkedValues[index] == value) {
                    display = false;
                    break;
                }
            }
        }
        return display;
    },

    getCheckboxListDisplay: function(element, symbol, value) {

        var display = false;
        var checkboxList = element.up('table');
        var list = checkboxList.select('input');
        var checkedValues = new Array();
        var i = 0;
        for (var index = 0; index < list.length; ++index) {
            var item = list[index];
            if (item.checked) {
                var valueItem = item.up('td').select('label');
                checkedValues[i] = valueItem[0].innerHTML;
                i++;
            }
        }

        if (symbol == "==") //Remeber we only handle equal and not equal ingore the rest of them.
        {
            for (var index = 0; index < checkedValues.length; ++index) {
                if (checkedValues[index] == value) {
                    display = true;
                    break;
                }
            }
        }
        else if (symbol == "!=") {
            display = true;
            for (var index = 0; index < checkedValues.length; ++index) {
                if (checkedValues[index] == value) {
                    display = false;
                    break;
                }
            }
        }

        return display;
    },

    setLinkedControl: function(control) {
        var linked = this._linkedHash.get(control.id);

        for (var j = 0; j < linked.linkedControls.length; j++) {
            var linkedElement = $(linked.linkedControls[j].id);

            var linkedElementWrapper;
            if (linkedElement != null) {
                if (linkedElement.hasClassName('FormContainer')) {
                    linkedElementWrapper = linkedElement;
                }
                else {
                    var ancestors = linkedElement.ancestors();
                    for (var i = 0; i < ancestors.length; i++) {
                        if (ancestors[i].hasClassName('EnquiryLabelGroup')) {
                            linkedElementWrapper = ancestors[i];
                            break;
                        }
                    }
                }
            }
            if (linkedElementWrapper != null) {
                var value = linked.linkedControls[j].value;
                if (this.isDisplay(control, value)) {
                    this.setVisibilityHiddenFieldValues(linkedElementWrapper, '');
                    linkedElementWrapper.show();
                    this.RemoveKeyFromInvisiableElementsHiddenField(linkedElement);
                }
                else {
                    this.setVisibilityHiddenFieldValues(linkedElementWrapper, 'hidden');
                    linkedElementWrapper.hide();
                    this.AddKeyToInvisiableElementsHiddenField(linkedElement);
                }

                var validators = linkedElementWrapper.select('.EnquiryError');

                for (var a = 0; a < validators.length; a++)
                    this.setValidatorEnabled(validators[a]);
            }
        }
    },

    setLinkedRadio: function(radio) {
        var ancestors = radio.ancestors();
        for (var i = 0; i < ancestors.length; i++) {
            if (ancestors[i].tagName.toLowerCase() == 'table') {
                var linked = this._linkedHash.get(ancestors[i].id);
                for (var j = 0; j < linked.linkedControls.length; j++) {
                    var linkedElement = $(linked.linkedControls[j].id);
                    var linkedElementWrapper;
                    if (linkedElement.hasClassName('FormContainer')) {
                        linkedElementWrapper = linkedElement;
                    }
                    else {
                        var ancestors = linkedElement.ancestors();
                        for (var i = 0; i < ancestors.length; i++) {
                            if (ancestors[i].hasClassName('EnquiryLabelGroup')) {
                                linkedElementWrapper = ancestors[i];
                                break;
                            }
                        }
                    }
                    if (linkedElementWrapper != null) {
                        if (this.isDisplay(radio, linked.linkedControls[j].value)) {
                            this.setVisibilityHiddenFieldValues(linkedElementWrapper, '');
                            linkedElementWrapper.show();
                            this.RemoveKeyFromInvisiableElementsHiddenField(linkedElementWrapper);
                        }
                        else {
                            this.setVisibilityHiddenFieldValues(linkedElementWrapper, 'hidden');
                            linkedElementWrapper.hide();
                            this.AddKeyToInvisiableElementsHiddenField(linkedElementWrapper);
                        }
                        var validators = linkedElementWrapper.select('.EnquiryError');
                        for (var a = 0; a < validators.length; a++)
                            this.setValidatorEnabled(validators[a]);
                    }
                }
                break;
            }
        }
    },

    setLinkedCheckBox: function(checkbox) {
        var ancestors = checkbox.ancestors();
        var linkedElementWrapper;
        for (var i = 0; i < ancestors.length; i++) {
            if (ancestors[i].tagName.toLowerCase() == 'table') {
                var linked = this._linkedHash.get(ancestors[i].id);
                for (var j = 0; j < linked.linkedControls.length; j++) {
                    var linkedElement = $(linked.linkedControls[j].id);
                    if (linkedElement.hasClassName('FormContainer')) {
                        linkedElementWrapper = linkedElement;
                    }
                    else {
                        var ancestors = linkedElement.ancestors();
                        for (var i = 0; i < ancestors.length; i++) {
                            if (ancestors[i].hasClassName('EnquiryLabelGroup')) {
                                linkedElementWrapper = ancestors[i];
                                break;
                            }
                        }
                    }
                    if (linkedElementWrapper != null) {
                        if (this.isDisplay(checkbox, linked.linkedControls[j].value)) {
                            this.setVisibilityHiddenFieldValues(linkedElementWrapper, '');
                            linkedElementWrapper.show();
                            this.RemoveKeyFromInvisiableElementsHiddenField(linkedElementWrapper);
                        }
                        else {
                            this.setVisibilityHiddenFieldValues(linkedElementWrapper, 'hidden');
                            linkedElementWrapper.hide();
                            this.AddKeyToInvisiableElementsHiddenField(linkedElementWrapper);
                        }

                        var validators = linkedElementWrapper.select('.EnquiryError');
                        for (var a = 0; a < validators.length; a++)
                            this.setValidatorEnabled(validators[a]);
                    }
                }
                break;
            }
        }
        if (linkedElementWrapper == null) // single checkbox
        {
            var linked = this._linkedHash.get(checkbox.id);
            for (var j = 0; j < linked.linkedControls.length; j++) {
                var linkedElement = $(linked.linkedControls[j].id);
                if (linkedElement.hasClassName('FormContainer')) {
                    linkedElementWrapper = linkedElement;
                }
                else {
                    var ancestors = linkedElement.ancestors();
                    for (var i = 0; i < ancestors.length; i++) {
                        if (ancestors[i].hasClassName('EnquiryLabelGroup')) {
                            linkedElementWrapper = ancestors[i];
                            break;
                        }
                    }
                }
                if (linkedElementWrapper != null) {
                    if (this.isDisplay(checkbox, linked.linkedControls[j].value)) {
                        this.setVisibilityHiddenFieldValues(linkedElementWrapper, '');
                        linkedElementWrapper.show();
                        this.RemoveKeyFromInvisiableElementsHiddenField(linkedElementWrapper);
                    }
                    else {
                        this.setVisibilityHiddenFieldValues(linkedElementWrapper, 'hidden');
                        linkedElementWrapper.hide();
                        this.AddKeyToInvisiableElementsHiddenField(linkedElementWrapper);
                    }
                    var validators = linkedElementWrapper.select('.EnquiryError');
                    for (var a = 0; a < validators.length; a++)
                        this.setValidatorEnabled(validators[a]);
                }
            }
        }
    },

    setValidatorEnabled: function(validator) {
        validator.enabled = this.isVisible(validator);

        if (!validator.enabled)
            validator.isvalid = true;

        ValidatorUpdateDisplay(validator);
    },

    setValidators: function() {
        if (typeof ValidatorUpdateDisplay != 'undefined') {
            var validators = $(document.body).select('.EnquiryError');
            for (var i = 0; i < validators.length; i++)
                this.setValidatorEnabled(validators[i]);
        }
    },

    updateValidatorHidden: function() {
        var value = '';
        var validators = $(document.body).select('.EnquiryError');
        for (var i = 0; i < validators.length; i++)
            value += validators[i].id + ':' + validators[i].enabled + ',';
    },

    isVisible: function(element) {
        var ancestors = element.ancestors();
        for (var i = 0; i < ancestors.length; i++)
            if (ancestors[i].visible() == false)
            return false;

        return true;
    },

    setVisibilityHiddenFieldValues: function(linkedElementWrapper, value) {
        var inputFields = linkedElementWrapper.select('input');
        var visibilityHiddenField;
        for (var k = 0; k < inputFields.length; k++) {
            if (inputFields[k].type == 'hidden') {
                var stringId = inputFields[k].id.endsWith('VisibilityHiddenField');
                if (stringId) {
                    visibilityHiddenField = inputFields[k];
                    visibilityHiddenField.value = value;
                }
            }
        }
    },

    AddKeyToInvisiableElementsHiddenField: function(linkedElement) {
        if (linkedElement.hasClassName('FormContainer') || linkedElement.hasClassName('EnquiryLabelGroup')) {
            var inputFields = linkedElement.select('input');
            for (var i = 0; i < inputFields.length; i++) {
                this.AddInvisibleElementKey(inputFields[i]);
            }
            var textareaFields = linkedElement.select('textarea');
            for (var i = 0; i < textareaFields.length; i++) {
                this.AddInvisibleElementKey(textareaFields[i]);
            }
        }
        else {
            this.AddInvisibleElementKey(linkedElement);
        }
    },

    AddInvisibleElementKey: function(linkedElement) {
        var keyArray = linkedElement.identify().split('_');
        var key = keyArray[keyArray.length - 1];
        if (this.invisibleElementsHiddenField.value.length > 0) {
            var exists = false;
            var keyArray = this.invisibleElementsHiddenField.value.split(',');
            for (var i = 0; i < keyArray.length; i++) {
                var value = keyArray[i];
                if (value == key) {
                    exists = true;
                    break;
                }
            }

            if (exists == false && key != '' && key != 'VisibilityHiddenField') {
                this.invisibleElementsHiddenField.value = this.invisibleElementsHiddenField.value + ',' + key;
            }
        }
        else {
            this.invisibleElementsHiddenField.value = key;
        }
    },

    RemoveKeyFromInvisiableElementsHiddenField: function(linkedElement) {
        if (linkedElement.hasClassName('FormContainer') || linkedElement.hasClassName('EnquiryLabelGroup')) {
            var inputFields = linkedElement.select('input');
            for (var i = 0; i < inputFields.length; i++) {
                this.RemoveInvisibleElementKey(inputFields[i]);
            }
            var textareaFields = linkedElement.select('textarea');
            for (var i = 0; i < textareaFields.length; i++) {
                this.RemoveInvisibleElementKey(textareaFields[i]);
            }
        }
        else {
            this.RemoveInvisibleElementKey(linkedElement);
        }
    },

    RemoveInvisibleElementKey: function(linkedElement) {
        var keyArray = linkedElement.identify().split('_');
        var key = keyArray[keyArray.length - 1];
        if (this.invisibleElementsHiddenField.value.length > 0) {
            var keyArray = this.invisibleElementsHiddenField.value.split(',');
            var removedKeyValue = '';
            for (var i = 0; i < keyArray.length; i++) {
                var value = keyArray[i];
                if (value != key) {
                    removedKeyValue = removedKeyValue + value + ',';
                }
            }
            this.invisibleElementsHiddenField.value = removedKeyValue;
        }
    }
});
