function LoginViewModel(container, action) {
    var that = null;

    this.validator = null;
    this.credentials = $.extend(true, {}, LoginCredentials);

    this.touWindow = {};
    this.touWindowwModel = {};

    this.privacyNoticeWindow = {};
    this.privacyNoticeWindowMoel = {};

    this.passwordResetWindow = {};
    this.passwordResetWindowModel = {};

    this.clientRegistrationWindow = {};
    this.clientRegistrationWindowModel = {};

    this.setObservable = function (o) {
        that = o;
        that.validator = loginValidator(container);
    };

    this.loginHandler = function () {
        $("#login-username").trigger("change");
        $("#login-password").trigger("change");

        if (that.validator.validate()) {
            post({
                url: action,
                dataType: "json",
                data: JSON.stringify(that.credentials),
                beforesend: that.loginBeforesendHandler,
                callback: that.loginCallbackHandler,
                headers: {
                    RequestVerificationToken: antiforgeryToken
                },
                submitElement: "#login-submit",
                resubmittable: true
            });
        };
    };

    this.loginBeforesendHandler = function (x, o) {
        var c = JSON.parse(o.data);
        var n = c.Username.indexOf("\\");
        if (n > -1) {
            var uarray = c.Username.split("\\");
            c.Domain = uarray[0];
            c.Username = uarray[1];
        }
        o.data = JSON.stringify(c);
    };

    this.loginCallbackHandler = function (r) {
        var notification = $("#notification-login").data("kendoNotification");

        if (r.user != null) {
            notification.hide();
            sessionContext.refresh(r.user);

            //set redirect url
            var params = getUrlVars();
            if (params["ReturnUrl"] && !isExternalUrl(params["ReturnUrl"]))
                r.redirect = decodeURIComponent(params["ReturnUrl"]);

            if (r.user.IsExternal) {
                //reset password for first time sign-in / expired password
                if (!r.user.EmailConfirmed || r.user.PasswordExpired) {
                    that.resetPasswordHandler(r.user);
                }
                    //verify if Terms of Use is accepted/declined
                else if (!r.user.TOU) {
                    that.touAgreementHandler(r.user);
                }
                    // verify if Privacy Notice has been seen
                else if (!r.user.PrivacyNoticeFlag) {
                    that.privacyNoticeHandler(r.user);
                }
                else {
                    redirectViewHandler(r.redirect);
                }
            }
            else {
                redirectViewHandler(r.redirect);
            }
        }
        else {
            sessionStorage.clear();
            //show message            
            if (notification.getNotifications().length > 0) notification.getNotifications().remove();
            notification.error({ message: r.message });
        }
    };

    this.forgotPasswordHandler = function () {
        showMessage(localizedResource.InformationModalTitle, localizedResource.ForgotPasswordMessage);
    }

    this.resetPasswordHandler = function (p) {
        that.passwordResetWindow.data("Params", { profile: p, callback: resetPasswordCallbackHandler, window: that.passwordResetWindow });
        that.passwordResetWindow.show();
    };

    this.touAgreementHandler = function (p) {
        that.touWindow.data("Params", { profile: p, callback: touAgreementCallbackHandler, window: that.touWindow });
        that.touWindow.show();
    };

    this.privacyNoticeHandler = function (p) {
        that.privacyNoticeWindow.data("Params", { profile: p, callback: privacyNoticeCallbackHandler, window: that.privacyNoticeWindow });
        that.privacyNoticeWindow.show();
    };

    this.clientRegistrationHandler = function () {
        that.clientRegistrationWindow.data("Params", { window: that.clientRegistrationWindow });
        that.clientRegistrationWindow.show();
    };

    var resetPasswordCallbackHandler = function (e, p) {
        //update cridential password
        that.credentials.set("Password", p);
        if (!e.TOU) that.touAgreementHandler(e);
        else if (!e.PrivacyNoticeFlag) that.privacyNoticeHandler(e);
        else that.loginHandler();
    }

    var touAgreementCallbackHandler = function (e) {
        if (e.TOU) that.loginHandler();
    }

    var privacyNoticeCallbackHandler = function (e) {
        if (e.PrivacyNoticeFlag) that.loginHandler();
    }
};



/* Create login validator */
function loginValidator(container) {
    return container.kendoValidator({
        validateOnBlur: false,
        rules: {},
        messages: {
            date: localizedResource.InvalidDateMessage,
            required: localizedResource.FieldRequiredMessage,
            email: localizedResource.EmailFormatMessage
        }
    }).data("kendoValidator");
}

function employeeValidator(container) {
    return container.kendoValidator({
        validateOnBlur: false,
        rules: {},
        messages: {
            date: localizedResource.InvalidDateMessage,
            required: localizedResource.FieldRequiredMessage,
            email: localizedResource.EmailFormatMessage
        }
    }).data("kendoValidator");
}

function permissionSetValidator(container) {
    return container.kendoValidator({
        validateOnBlur: false,
        rules: {},
        messages: {
            required:localizedResource.FieldRequiredMessage
        }
    }).data("kendoValidator");
}

function permissionValidator(container) {
    return container.kendoValidator({
        validateOnBlur: false,
        rules: {},
        messages: {
            required: localizedResource.FieldRequiredMessage
        }
    }).data("kendoValidator");
}
function sosValidator(container) {
	return container.kendoValidator({
		validateOnBlur: false,
		rules: {},
		messages: {}
	}).data("kendoValidator");
}
function AboutViewModel(container, args) {
    var that = null;

    this.clientRegWindow = {};
    this.clientRegWindowModel = {};

    this.setObservable = function (o) {
        that = o;
    };
};
function FaqViewModel(container) {
    var that = null;
    var quoteSlider = kendo.fx($("#qq-slide-in")).slideIn("right");

    this.setParams = function (p) {
        that.window = p.window;
    };

    this.setObservable = function (o) {
        that = o;
    };
    this.closeWindowHandler = function () {
        that.window.close();
    }
    this.faqFeedbackHandler = function (e) {
        mainViewModel.currentIndex = $(e.currentTarget).data("index");
        mainViewModel.setQuoteSildeHandler({ url: $(e.currentTarget).data("url") });

        that.closeWindowHandler();
    };

    this.homePageHandler = function (e) {
        mainViewModel.currentIndex = $(e.currentTarget).data("index");
        mainViewModel.setQuoteSildeHandler({ url: $(e.currentTarget).data("url") });
        that.closeWindowHandler();
    };

    this.displayTOUHandler = function (e) {
        window.open($(e.currentTarget).data("url"));
    };
};
function IndexViewModel(container, args) {
    var that = null;

    this.clientRegistrationWindow = {};
    this.clientRegistrationWindowModel = {};

    this.setObservable = function (o) {
        that = o;
    };

    this.clientRegistrationHandler = function () {
        that.clientRegistrationWindow.data("Params", { window: that.clientRegistrationWindow });
        that.clientRegistrationWindow.show();
    };
};
function MainViewModel(container, args) {
    var that = null;    
    var toggleSlider = false;    
    var quoteSlider = kendo.fx($("#qq-slide-in")).slideIn("right");

    this.productServiceWindow = {};
    this.productServiceWindowModel = {};

    this.aboutWindow = {};
    this.aboutWindowModel = {};

    this.currentIndex = 0;

    this.setObservable = function (o) {
        that = o;      

        that.toggleQuoteSlideHandler(toggleSlider);
        that.setQuoteSildeHandler();

        $(window).resize(function () {
            that.setQuoteSildeHandler();
        });

        if (that.base_setObservable)
            that.base_setObservable(o);       
    };

    this.navigateMenuHandler = function (e) {
        that.currentIndex = e.sender.element.data("index");
        that.setQuoteSildeHandler({ url: e.sender.element.data("url") });
    };

    this.setQuoteSildeHandler = function (e) {
        if (that.currentIndex > 0 || $(window).width() < 868) {
            $("#qq-slide-handle").show();
            if (!toggleSlider) that.toggleQuoteSlideHandler(false);
            $("#main-content").removeClass("c-pullHorizontal").addClass("c-stretchHorizontal");
            $("#main-quickquote").removeClass("c-pushHorizontal").addClass("c-absolute-position");
            if (e && e.url) loadPartialViewHandler("#main-content", e.url);
        }
        else {
            $("#qq-slide-handle").hide();
            if (toggleSlider) that.toggleQuoteSlideHandler(true);
            window.setTimeout(function () {
                $("#main-content").removeClass("c-stretchHorizontal").addClass("c-pullHorizontal");
                $("#main-quickquote").removeClass("c-absolute-position").addClass("c-pushHorizontal");
                if (e && e.url) loadPartialViewHandler("#main-content", e.url);
            }, 200);   //add buffer (200 ms) 
        }
    };

    this.displayFileHandler = function (e) {
        var url = e.sender.element.data("url");
        var permissions = e.sender.element.data("permittedactions");
        if (permissions && !verifyPermissions(permissions, sessionContext.currentUser.Permissions)) {
            showMessage(localizedResource.ErrorModalTitle, localizedResource.UnauthorizedAccessMessage);
            return;
        }
        else window.open(url);
    };

    this.toggleQuoteSlideHandler = function (e) {
        if (typeof e == "boolean") toggleSlider = e;
        if (toggleSlider) {
            quoteSlider.reverse();
            $("#slide-handle-panel").hide();
            $("#qq-slide-handle").removeClass("c-a-width");
        }
        else {
            quoteSlider.play();
            $("#slide-handle-panel").show();
            $("#qq-slide-handle").addClass("c-a-width");
        }
        toggleSlider = !toggleSlider;
        if (e.preventDefault) e.preventDefault();
    };

    this.openProductServiceWindowHandler = function () {
        that.productServiceWindow.data("Params", { window: that.productServiceWindow });
        that.productServiceWindow.show();
    };

    this.openAboutWindowHandler = function () {
        that.aboutWindow.data("Params", { window: that.aboutWindow });
        that.aboutWindow.show();
    };

};
function MySOSViewModel(container, actions, args) {
    var that = null;
    this.enquiry = args.enquiry;
    this.validator = null;

    this.recaptchaReady = false;

    this.setObservable = function (o) {
        that = o;
        that.validator = args.validator;
        getRecaptchaHandler($("#mysos-recaptcha"));
    };

    this.sendEmailHandler = function () {
        that.enquiry.set("Response", grecaptcha.getResponse());

        if (that.validator.validate()) {
            post({
                url: actions.sendMySOSEmail,
                dataType: "json",
                data: JSON.stringify(that.enquiry),
                callback: function (data) {                    
                    if (data.success == "true") {
                        showDialog({
                            title: localizedResource.InformationModalTitle,
                            message: localizedResource.EnquirySentMessage,
                            IsYesOnly: true
                        });
                        that.set("enquiry", { Sender: null, SenderEmail: null, Message: null, EnquiryType: "" });                        
                    } else {
                        showDialog({
                            title: localizedResource.InformationModalTitle,
                            message: localizedResource.RecaptchaFailedMessage,
                            IsYesOnly: true
                        });                        
                    }
                    grecaptcha.reset();
                },
                headers: {
                    RequestVerificationToken: antiforgeryToken
                }
            });
        }
    }

    var getRecaptchaHandler = function (e) {
        removeElements($(document), 'span[id^="recaptcha-"]');
        post({
            url: actions.getRecaptcha,
            dataType: "json",
            callback: function (data) {
                e.html(data);
                that.set("recaptchaReady", true);
            },
            headers: {
                RequestVerificationToken: antiforgeryToken
            },
            hideLoading: true
        });
    };
};
function ProductServiceViewModel(container) {
    var that = null;

    this.setParams = function (p) {
        that.window = p.window;
    };

    this.setObservable = function (o) {
        that = o;
    };
    this.closeWindowHandler = function()
    {
        that.window.close();
    }
};
function QuickQuoteViewModel(container, actions, args) {
    var that = null;

    this.quote = {};
    this.propertyTypes = args.propertyTypes;
    this.countries = args.countries;

    this.product = [];
    this.products = new kendo.data.DataSource({ data: [] });

    this.quoteValidator = null;
    this.criteria = $.extend(true, {}, QuoteCriteria);

    this.totalPremium = 0;
    this.headerVisible = true;

    this.setObservable = function (o) {
        that = o;

        that.quote = args.quote;
        that.quoteValidator = args.quoteValidator;

        extendEntity(that, "quote", "Quote");

        if (that.quote.Property.CountryID.ID == 0) {
            that.quote.Property.set("CountryID", { ID: 1, Value: "England" });
            that.quote.Property.set("PropertyTypeID", { ID: 1, Value: "Residential" });
            that.getProductsHandler(null);
        }
        that.quote.setupHandlers();
        that.set("headerVisible", !sessionContext.currentUser);

        that.loadQuoteFirmHandler();
    };

    this.productChangeHandler = function (e) {
        that.quote.RiskCollection.Items.removeAll();
        that.quote.RiskCollection.Items.addRange(e.sender.dataItems());
        Enumerable.From(that.products._data).ForEach(function (x) {
            x.set("IsSelected", Enumerable.From(e.sender.dataItems()).Any(function (r) { return r.RiskID == x.RiskID }));
        });
    };

    this.getQuoteHandler = function (e) {
        if (that.quoteValidator.validate()) {
            that.quote.PolicyCollection.Items.removeAll();
            that.quote.Invoice.InvoiceItemCollection.Items.removeAll(function (x) {
                return x.PolicyUniqueId != null
            });
            post({
                url: actions.getQuote,
                dataType: "json",
                data: kendo.stringify(that.quote),
                callback: function (data) {
                    that.quote.Update(data);
                    that.set("totalPremium", data.Invoice.TotalNetPremium);
                    that.trigger("change", { field: "resultVisiblityHandler" });
                },
                headers: {
                    RequestVerificationToken: antiforgeryToken
                },
                hideLoading: true
            });
        }
    };

    this.resultVisiblityHandler = function () {
        return that.totalPremium > 0;
    };

    this.getProductsHandler = function (e) {
        if (that.quote.Property) {
            if (that.quote.Property.PropertyTypeID == null) that.quote.Property.set("PropertyTypeID", { ID: 0 });
            if (that.quote.Property.CountryID == null) that.quote.Property.set("CountryID", { ID: 0 });
        }
        if (that.quote.Property.PropertyTypeID.ID > 0 && that.quote.Property.CountryID.ID > 0) {
            that.criteria.IsOnline = true;
            that.criteria.PolicyTypeID.ID = PolicyTypesEnum.Standard;
            that.criteria.PropertyTypeID.ID = that.quote.Property.PropertyTypeID.ID;
            that.criteria.CountryID.ID = that.quote.Property.CountryID.ID;

            post({
                url: actions.getProducts,
                dataType: "json",
                data: kendo.stringify(that.criteria),
                callback: function (data) {
                    that.set("products", new kendo.data.DataSource({ data: data.Risks }));

                },
                headers: {
                    RequestVerificationToken: antiforgeryToken
                }
            });
        }
    };

    this.loadQuoteFirmHandler = function () {
        if (that.quote.ProfileUniqueId == null) return;
        post({
            url: actions.getQuoteFirm,
            dataType: "json",
            data: JSON.stringify(that.quote),
            callback: function (data) {
                that.quote.set("Firm", data);
            },
            headers: {
                RequestVerificationToken: antiforgeryToken
            }
        });
    }

    this.refreshQuoteHandler = function () {
        that.set("totalPremium", 0);
        that.trigger("change", { field: "resultVisiblityHandler" });
    };
}
