V4.WizardFlow = function() {

    var wizardFlowInitializer = this;

    var getElementFor = function(elementName) {
        return $(elementName.type + '[name="' + elementName.name + '"]');
    };

    var enableFormRowOfElement = function(inputElementName) {
        var inputElement = getElementFor(inputElementName);
        inputElement.parents(".formRow").show();
        inputElement.removeAttr('disabled');
    };

    var showFormRowWith = function(elementClass) {
        $('div.formRow.' + elementClass).show();
    };

     var hideFormRowWith = function(elementClass) {
        $('div.formRow.' + elementClass).hide();
    };

    var enableFormRowOfElements = function(inputElementNames) {
        $.each(inputElementNames, function(index, inputElement) {
            enableFormRowOfElement(inputElement);
        });
        getElementFor(inputElementNames[0]).focus();
    };

    var disableFormRowOfElement = function(inputElementName) {
        var inputElementSelector = getElementFor(inputElementName);
        inputElementSelector.parents(".formRow").hide();
        inputElementSelector.attr('disabled', "disabled");
    };

    var disableFormRowOfElements = function(inputElementNames) {
        $.each(inputElementNames, function(index, inputElement) {
            disableFormRowOfElement(inputElement);
        });
    };

    var disableAllInputElementsForStep = function(stepNumber) {
        $('.jsWizardStep' + stepNumber + ' :input').parents(".formRow").hide();
        $('.jsWizardStep' + stepNumber + ' :input').attr('disabled', 'disabled');
    };

    var ProgrammesFlow = function() {
        var programmesFlow = this;
        var typeOfFeedbackElement = getElementFor(V4.fields.programmeFlow.typeOfFeedback);
        var programmeTitleElement = getElementFor(V4.fields.programmeFlow.programmeTitles);

        var initDefaultProgrammesFlow = function() {
            enableFormRowOfElements([V4.fields.programmeFlow.tvChannels,
                V4.fields.programmeFlow.programmeTitles]);
            programmesFlow.programmeTitleChanged();

            enableFormRowOfElement(V4.fields.programmeFlow.transmissionDate);
        };

        var initProgrammesTechnicalFaultFlow = function() {
            enableFormRowOfElements([V4.fields.programmeFlow.tvChannels,
                V4.fields.programmeFlow.signal,
                V4.fields.programmeFlow.detailProblem]);
        };


        var changeElementsToBeShown = function() {
            if (typeOfFeedbackElement.val() == '') {
                return;
            }
            if (typeOfFeedbackElement.val() == V4.fields.programmeFlow.typeOfFeedback.options.technicalFaultOption) {
                initProgrammesTechnicalFaultFlow();
            }
            else {
                initDefaultProgrammesFlow();
            }
        };

        this.refreshStepTwoFlow = function() {
            disableAllInputElementsForStep(2);
            enableFormRowOfElement(V4.fields.programmeFlow.typeOfFeedback);
            changeElementsToBeShown();
        };

        this.refreshStepThreeFlow = function() {
            disableAllInputElementsForStep(3);
            if (typeOfFeedbackElement.val() == V4.fields.programmeFlow.typeOfFeedback.options.technicalFaultOption) {
                enableFormRowOfElement(V4.fields.step3.caseNumber);
                hideFormRowWith(V4.fields.step3.termsAndConditions.className);
            }
            else {
                enableFormRowOfElement(V4.fields.step3.feedback);
                enableFormRowOfElement(V4.fields.step3.makePublic);
                showFormRowWith(V4.fields.step3.termsAndConditions.className);
            }
        };

        this.programmeTitleChanged = function() {
            var otherProgramme = V4.fields.programmeFlow.otherProgramme;
            if (programmeTitleElement.val() == V4.fields.programmeFlow.programmeTitles.options.other) {
                enableFormRowOfElement(otherProgramme);
            }
            else {
                disableFormRowOfElement(otherProgramme);
            }
        };

        this.bindEvents = function() {
            typeOfFeedbackElement.change(programmesFlow.refreshStepTwoFlow);
            programmeTitleElement.change(programmesFlow.programmeTitleChanged);
        };
    };

    var OnlineFlow = function() {
        var onlineFlow = this;
        var selectWebsiteElement = getElementFor(V4.fields.onlineFlow.website);
        var typeOfFeedback = getElementFor(V4.fields.onlineFlow.typeOfFeedback);
        var registrationElement = getElementFor(V4.fields.onlineFlow.registration);

        var changeElements = function() {
            if (selectWebsiteElement.val() == V4.fields.onlineFlow.website.options.apps) {
                enableFormRowOfElements([V4.fields.onlineFlow.operatingSystem,
                    V4.fields.onlineFlow.platform,
                    V4.fields.onlineFlow.typeOfDevice]);
            }
            else if (selectWebsiteElement.val() == "") {
                return true;
            }
            else {
                enableFormRowOfElement(V4.fields.onlineFlow.typeOfFeedback);
                onlineFlow.typeOfFeedbackChanged();
            }

        };

        this.refreshStepTwoFlow = function() {
            disableAllInputElementsForStep(2);
            enableFormRowOfElement(V4.fields.onlineFlow.website);
            changeElements();
        };

        this.refreshStepThreeFlow = function() {
            disableAllInputElementsForStep(3);
            enableFormRowOfElement(V4.fields.step3.feedback);
            hideFormRowWith(V4.fields.step3.termsAndConditions.className);
        };

        this.registrationChanged = function() {
            if (registrationElement.val() == V4.fields.onlineFlow.registration.options.other) {
                enableFormRowOfElement(V4.fields.onlineFlow.registrationOther);
            }
            else {
                disableFormRowOfElement(V4.fields.onlineFlow.registrationOther);
            }

        };

        this.typeOfFeedbackChanged = function() {
            disableFormRowOfElements([V4.fields.onlineFlow.onlineLink,
                V4.fields.onlineFlow.registration,
                V4.fields.onlineFlow.registrationOther]);

            if (typeOfFeedback.val() == V4.fields.onlineFlow.typeOfFeedback.options.accessibility) {
                enableFormRowOfElement(V4.fields.onlineFlow.onlineLink);
            }
            else if (typeOfFeedback.val() == V4.fields.onlineFlow.typeOfFeedback.options.registration) {
                enableFormRowOfElements([V4.fields.onlineFlow.onlineLink,
                    V4.fields.onlineFlow.registration]);
                onlineFlow.registrationChanged();
            }
        };

        this.bindEvents = function() {
            selectWebsiteElement.change(onlineFlow.refreshStepTwoFlow);
            typeOfFeedback.change(onlineFlow.typeOfFeedbackChanged);
            registrationElement.change(onlineFlow.registrationChanged);
        };

    };

    var FourODFlow = function() {
        var fourODFlow = this;

        var fourODViewingOptionsElement = getElementFor(V4.fields.fourODFlow.fourODViewingOptions);
        var typeOfFeedbackElement = getElementFor(V4.fields.fourODFlow.typeOfFeedback);

        this.typeOfFeedbackChanged = function() {
            disableFormRowOfElements([V4.fields.fourODFlow.errorCode,
                V4.fields.fourODFlow.approximateTime,
                V4.fields.fourODFlow.webPageAddress,
                V4.fields.fourODFlow.otherInfo]);

            if (typeOfFeedbackElement.val() == V4.fields.fourODFlow.typeOfFeedback.options.technicalQuery) {
                enableFormRowOfElement(V4.fields.fourODFlow.errorCode);
                enableFormRowOfElement(V4.fields.fourODFlow.approximateTime);
                if (fourODViewingOptionsElement.val() == V4.fields.fourODFlow.fourODViewingOptions.options.computer) {
                    enableFormRowOfElement(V4.fields.fourODFlow.webPageAddress);
                }
                enableFormRowOfElement(V4.fields.fourODFlow.otherInfo);
            }
        };
        var changeElements = function() {
            if (fourODViewingOptionsElement.val() == V4.fields.fourODFlow.fourODViewingOptions.options.computer) {
                enableFormRowOfElements([V4.fields.fourODFlow.operatingSystem,
                    V4.fields.fourODFlow.browser,
                    V4.fields.fourODFlow.typeOfFeedback]);
                fourODFlow.typeOfFeedbackChanged();
            }
            else if (fourODViewingOptionsElement.val() == V4.fields.fourODFlow.fourODViewingOptions.options.tv) {
                enableFormRowOfElement(V4.fields.fourODFlow.typeOfFeedback);
                fourODFlow.typeOfFeedbackChanged();
            }
        };

        this.refreshStepTwoFlow = function() {
            disableAllInputElementsForStep(2);
            enableFormRowOfElement(V4.fields.fourODFlow.fourODViewingOptions);
            changeElements();
        };

        this.refreshStepThreeFlow = function() {
            disableAllInputElementsForStep(3);
            enableFormRowOfElement(V4.fields.step3.feedback);
            hideFormRowWith(V4.fields.step3.termsAndConditions.className);
        };

        this.bindEvents = function() {
            fourODViewingOptionsElement.change(fourODFlow.refreshStepTwoFlow);
            typeOfFeedbackElement.change(fourODFlow.typeOfFeedbackChanged);
        };

    };

    this.programmesFlow = new ProgrammesFlow();
    this.onlineFlow = new OnlineFlow();
    this.fourODFlow = new FourODFlow();

    var getFlowType = function() {
        var areaOfFeedbackElement = getElementFor(V4.fields.fromStep1.areaOfFeedback);

        if (areaOfFeedbackElement.val() == V4.fields.programmeFlow.name) {
            return wizardFlowInitializer.programmesFlow;
        }
        else if (areaOfFeedbackElement.val() == V4.fields.onlineFlow.name) {
            return wizardFlowInitializer.onlineFlow;
        }
        else if (areaOfFeedbackElement.val() == V4.fields.fourODFlow.name) {
            return wizardFlowInitializer.fourODFlow;
        }
    };

    this.nextButtonHandler = function(stepNumber) {
        var flow = getFlowType();
        if (stepNumber == 2) {
            flow.refreshStepTwoFlow();
        }
        else if (stepNumber == 3) {
            flow.refreshStepThreeFlow();
        }
    };

    this.init = function() {
        this.programmesFlow.bindEvents();
        this.onlineFlow.bindEvents();
        this.fourODFlow.bindEvents();
    };

};

