

function getSelectedRadio(radioGroup) {
    var radio = $("INPUT[name='" + radioGroup + "']:checked");
    return radio.size() > 0 ? $(radio[0]) : false;
}

var Validations = {
    required : function (value, arg)
    {
        //alert("checking for required value: " + value + ", args: " + arg);
        return (value && value != "");
    },
    min : function(value, arg)
    {
        return  parseInt(value, 10) >= parseInt(arg, 10);
    },
    max : function(value, arg)
    {
        return  parseInt(value, 10) <= parseInt(arg, 10);
    },
    number : function(value, arg)
    {
        return (/^(\d)*(,(\d)+)?$/).test(value);
    },
    fixed_length : function(value, arg)
    {
        return value.length == parseInt(arg, 10);
    },
    exact_match : function(value, arg)
    {
        return value == arg;
    },
    pnr_se : function(value, arg) //validates swedish personal identification numbers on the form "YYMMDDNNNN"
    {
        var pnr = value;
        var numbers = pnr.match(/^(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)$/);
        if (numbers == null) {
            return false;
        }
        var checkSum = 0;

        var n;
        for (var i = 1; i <= 10; i++)
        {
            n = parseInt(numbers[i], 10);
            if (i % 2 == 0)
                checkSum += n;
            else
                checkSum += (n * 2) % 9 + Math.floor(n / 9) * 9
        }
        return checkSum % 10 == 0;
    },
    year_month : function(value, arg)
    {
        var numbers = value.match(/^(\d{2})(\d{2})$/);
        if (numbers == null) return false;
        var month = parseInt(numbers[2], 10); //numbers = {YYMM,YY,MM}
        return month <= 12 && month >= 1;
    },
    same_as : function(value, arg)
    {
        var otherInputElement = $("#" + arg); //find other input element by id specified in argument
        return value == otherInputElement.val();
    },
    email : function(value, arg)
    {
        return Validations.regexp(value, /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/);
    },
    regexp : function(value, arg)
    {
        return (value.search(arg) != -1);
    },
    yymm : function(value, arg)
    {
        //alert(value.search(/^~d$/));
        if(value && value.length != 4)
        {
            return false;
        }
        //var year = parseInt(value.substr(0, 2));
        var month = parseInt(value.substr(2, 2));

        return month > 0 && month < 13;
    }
};

var Resurs = {
    initMenu: function() {
        $(document).ready(function() {
            var menuDiv = $("#menu");

            menuDiv.find("DIV.menu-clickable-area").each(function(idx, element) {
                var $menuNodeDiv = $(element);
                var menuLinkA = $menuNodeDiv.find("A.menu-link");
                var linkURL = menuLinkA.attr("href");

                menuLinkA.click(function(e) {
                    e.preventDefault();
                });

                $menuNodeDiv.click(function(e) {
                    window.location = linkURL;
                });
            });
        });
    }
}

var ResursSteps = {
    currentStep : 1,

    doValidation : function(inputElement, validation)
    {
        var validationNameArgumentPair = jQuery.trim(validation).split('=');
        var validationName = jQuery.trim(validationNameArgumentPair[0]);

        var validationFunction = Validations[validationName];

        if (validationFunction)   //found a matching validation function, calculate validation value and validation argument to pass to validation function
        {
            var value;
            var validationArgument = validationNameArgumentPair.length == 2 ? jQuery.trim(validationNameArgumentPair[1]) : null;
            var inputType = inputElement.attr("type");
            if (inputType == "radio")
            {
                var radio = getSelectedRadio(inputElement.attr("name"));
                value = radio ? radio.val() : "";
            }
            else if(inputType == "checkbox")
            {
                value = inputElement.attr("checked");
            }
            else
            {
                value = inputElement.val();
            }
            
            return {inError : !validationFunction(value, validationArgument)};
        }
        else
            return false;  //ignore invalid validation
    },
    validateStepDiv : function(stepDiv)
    {
        var stepHasError = false;

        var inputElementsInStep = stepDiv.find("INPUT,SELECT"); //find all input elements and selects in this step
        //alert("inputElementsInStep: " + inputElementsInStep + ", " + inputElementsInStep.size());

        var validationResults = [];
        inputElementsInStep.each(function(idx, inputElement) {

            var validationsString = $(inputElement).attr("validations");
            //alert("validationsString " + validationsString);
            var validations = $(validationsString ? validationsString.split(",") : []);
            var inputElementHasError = false

            validations.each(function(idx, validation) //for each validation on this input element
            {
                var validationResult = ResursSteps.doValidation($(inputElement), validation);
                if (validationResult && validationResult.inError)
                    stepHasError = inputElementHasError = true;

            });
            validationResults.push({inputElement : $(inputElement), inError : inputElementHasError});

        });
        var validationResult = {hasError : stepHasError, validationResults : $(validationResults)};

        ResursSteps.displayValidationErrors(validationResult);


        var stepTitle = $($("#steps").find("[titleForStep='" + stepDiv.attr("step") + "']")[0]);
        if (stepTitle)  //if there is a title, set title image depending on error or not.
        {
            if(!stepTitle.attr("defaultImageSrc"))
                stepTitle.attr("defaultImageSrc", stepTitle.attr("src")); //save the default image

            var newImageSrc = "";
            if (validationResult.hasError)
                newImageSrc = stepTitle.attr("inErrorImgSrc");
            else
                newImageSrc = stepTitle.attr("validImgSrc");
            if (newImageSrc) stepTitle.attr("src", newImageSrc);
        }

        return validationResult;

    },
    displayValidationErrors : function(validationResult)
    {
        validationResult.validationResults.each(function(idx, validationInputResult) {

            var inputElement = validationInputResult.inputElement;
            var errorContainer = $(inputElement).parent();

            if (validationInputResult.inError)
            {
                if (!errorContainer.hasClass("error-container")) //is it not contained in an error container?
                {
                    errorContainer = $("<SPAN />").addClass('error-container').addClass("in-error");
                    inputElement.wrap(errorContainer);            //if not wrap it in an error container
                }
                else
                    errorContainer.addClass("in-error");
            } else
                errorContainer.removeClass("in-error");
        });
    },

    createInputContentBlurredFunction : function(input, caption)
    {
        return function()
        {
            if(input.val() == "")
            {
                input.val(caption).addClass("blurred");
            }
            input.removeClass("focus");
        };
    },

    createInputContentFocusFunction : function(input)
    {
        return function()
        {
            if(input.hasClass("blurred"))
            {
                input.removeClass("blurred");
                input.val("");
            }
            input.addClass("focus");
        }
    },
    /**
     * initializes the resurs form validation.
     * @param messages messages for errors
     * @param validationFailCallback a callback-function takes as parameter the errors as a string and should return true if the form should post, false otherwise
     */
    initSteps : function(messages, validationFailCallback)
    {
        var stepsDivs = $('.steps'); //div with all steps in it

        stepsDivs.each(function(idx, stepsDiv)
        {
            //alert("steps: " + stepsDiv);
            stepsDiv = $(stepsDiv);
            stepsDiv.find("FORM").each(function(idx2, formElement) {
                formElement = $(formElement);
                formElement.submit(function(event) {
                    var anyStepHasError = false;
                    //alert("Form submitted!");

                    //for each form, find all input elements that are blurred and reset their value to ""
                    //because we dont want to send the caption as value for the field.
                    var allBlurredInputs = formElement.find('INPUT[type="text"].blurred, INPUT[type="password"].blurred');
                    allBlurredInputs.each(function(idx, inputElement)
                    {
                        inputElement = $(inputElement);
                        inputElement.val("");
                    });

                    var errorMessage = "";

                    var validationNoAlert = formElement.attr("validationNoAlert");
                    if(validationNoAlert)
                        if (validationNoAlert != "true")
                            validationNoAlert = "false";

                    var allValidationResultsInError = [];

                    stepsDiv.find("DIV.step").each(function(idx, stepDiv) {
                        var validationResult = ResursSteps.validateStepDiv($(stepDiv));


                        if (validationResult.hasError) {


                            validationResult.validationResults.each(function(idx, validationResult) {
                                if(validationResult.inError) {
                                    allValidationResultsInError.push(validationResult);
                                    var validationMessage = validationResult.inputElement.attr("validationMessage");

                                    if(validationMessage)
                                        errorMessage += "* " + validationMessage + "\n";
                                }
                            });

                            anyStepHasError = true;
                        }
                    });

                    if (anyStepHasError)
                    {
                        //the form was in error, reset all blurred fields to their caption value
                        allBlurredInputs.each(function(idx, inputElement)
                        {
                            inputElement = $(inputElement);

                            inputElement.val(inputElement.attr("caption"));
                        });
                        if(!validationFailCallback($(allValidationResultsInError))) {
                            event.preventDefault();
                        }
                    }
                    else
                    {
                        //$(stepsDiv.find("input[type='submit'")).attr("disabled", "disabled"); //disable submit
                    }
                });
            });

            stepsDiv.find(".step").each(function(idx, stepDiv)
            {
                stepDiv = $(stepDiv);
                stepDiv.find('INPUT[type="text"], INPUT[type="password"]').each(function(idx, inputElement) {

                    inputElement = $(inputElement);
                    var caption = inputElement.attr("caption");
                    //alert("input: " + inputElement + " caption: " + caption);
                    if(caption)
                    {
                        var contentBlurredFunction = ResursSteps.createInputContentBlurredFunction(inputElement, caption);
                        var contentFocusFunction = ResursSteps.createInputContentFocusFunction(inputElement);

                        if(inputElement.val() == caption) //When you reload the page the old value is cached in the browser making the caption not-blurred and thus a value for the field.
                        {                                 //This fix checks if the value (most probably the cached one) is the same as the caption, if so, we assume that it is cached and make it blurred.
                            inputElement.val("");
                        }

                        contentBlurredFunction();
                        inputElement.blur(contentBlurredFunction);
                        inputElement.focus(contentFocusFunction);
                    }
                });

                var step = stepDiv.attr("step");

                var stepTitle = $($("#steps").find("[titleForStep='" + stepDiv.attr("step") + "']")[0]);
                stepDiv.attr("stepTitle", stepTitle);
                stepTitle.click(function()
                {
                    ResursSteps.activateStep(step);
                });

                stepDiv.find("A.gotoStep").each(function(gotoStepLink) {
                    gotoStepLink.click(function(e)
                    {
                        if (gotoStepLink.getAttribute("ignoreValidation") != "true")
                        {
                            var validationResult = ResursSteps.validateStepDiv(stepDiv);
                            if (validationResult.hasError)
                            {
                                //TODO details about the error??
                                alert(messages.formInError);
                                return;
                            }
                        }
                        var clickedElement = e.element();
                        var step = clickedElement.getAttribute("step");
                        ResursSteps.activateStep(step);
                    });
                });
            });
        });
    },

    activateStep : function(step)
    {
        if (step != ResursSteps.currentStep)
        {
            var stepsDiv = $('#steps'); //div with all steps in it
            var currentStepDiv = stepsDiv.find("DIV.step[step='" + ResursSteps.currentStep + "']");
            var activatingStepDiv = stepsDiv.find("DIV.step[step='" + step + "']");
            ResursSteps.currentStep = step;
            currentStepDiv.hide(); //hide this step
            activatingStepDiv.show(); //show next step
        }
    }

};