'use strict';

var ko = require('knockout');
require('knockout.validation');
var $ = require('jquery');

var $osf = require('./osfHelpers');


var ViewModel = function(submitUrl, campaign) {

    var self = this;

    self.fullName = ko.observable('').extend({
        required: true,
        minLength: 3
    });
    self.email1 = ko.observable('').extend({
        required: true,
        email: true
    });
    self.email2 = ko.observable('').extend({
        required: true,
        email: true,
        validation: {
            validator: function(val, other) {
                return String(val).toLowerCase() === String(other).toLowerCase();
            },
            'message': 'Email addresses must match.',
            params: self.email1
        }
    });
    self.password = ko.observable('').extend({
        required: true,
        minLength: 6,
        maxLength: 256
    });
    self.campaign = ko.observable(campaign);

    // Preserve object of validated fields for use in `submit`
    var validatedFields = {
        fullName: self.fullName,
        email1: self.email1,
        email2: self.email2,
        password: self.password
    };
    // Collect validated fields
    self.validatedFields = ko.validatedObservable($.extend({}, validatedFields));

    self.submitted = ko.observable(false);

    self.flashMessage = ko.observable('');
    self.flashMessageClass = ko.observable('');
    self.flashTimeout = null;

    self.trim = function(observable) {
        observable($.trim(observable()));
    };

    /** Change the flashed message. */
    self.changeMessage = function(message, messageClass, text, css, timeout, timeoutClock) {
        message(text);
        var cssClass = css || 'text-info';
        messageClass(cssClass);
        if (timeout) {
            // Reset message after timeout period
            if (timeoutClock) {
                clearTimeout(timeoutClock);
            }
            self.timeout = setTimeout(
                function() {
                    message('');
                    messageClass('');
                },
                timeout
            );
        }
    };

    self.isValid = ko.computed(function() {
        return self.validatedFields.isValid();
    });

    self.submitSuccess = function(response) {
        self.changeMessage(
            self.flashMessage,
            self.flashMessageClass,
            response.message,
            'text-info p-xs'
        );
        self.submitted(true);
    };

    self.submitError = function(xhr) {
        self.changeMessage(
            self.flashMessage,
            self.flashMessageClass,
            xhr.responseJSON.message_long,
            'text-danger p-xs',
            5000,
            self.flashTimeout
        );
    };

    self.submit = function() {
        if (self.submitted()) {
            self.changeMessage(self.flashMessage, self.flashMessageClass, 'You have already submitted. You cannot sign up more than once.', 'text-danger p-xs');
            return false;
        }
        // Show errors if invalid
        if (!self.isValid()) {
            // Ensure validation errors are displayed
            $.each(validatedFields, function(key, value) {
                value.notifySubscribers();
            });
            return false;
        }
        // Else submit, and send Google Analytics event
        window.ga('send', 'event', 'signupSubmit', 'click', 'new_user_submit');
        $osf.postJSON(
            submitUrl,
            ko.toJS(self)
        ).done(
            self.submitSuccess
        ).fail(
            self.submitError
        );
    };

    self.errors = ko.validation.group(self);

};

var SignUp = function(selector, submitUrl, campaign) {
    this.viewModel = new ViewModel(submitUrl, campaign);
    $osf.applyBindings(this.viewModel, selector);
};

module.exports = SignUp;

@@ -138,78 +138,1686 @@
 ');%0A
-%0A%0Avar ViewModel = function(submitUrl, campaign) %7B%0A%0A    var self = this
+var zxcvbn = require('zxcvbn');%0A%0A%0Ako.validation.rules%5B'trial'%5D = %7B%0A    validator: function (val, otherVal) %7B%0A        return val === otherVal;%0A    %7D,%0A    message: 'The field must equal %7B0%7D'%0A%7D;%0Ako.validation.registerExtenders();%0A%0A%0Avar ViewModel = function(submitUrl, campaign) %7B%0A%0A    var self = this;%0A%0A    self.typedPassword = ko.observable('').extend(%7B notify: 'always' %7D);%0A%0A    self.passwordFeedback = ko.observable('');%0A%0A    self.passwordComplexity = ko.pureComputed(function() %7B%0A        var current = zxcvbn(self.typedPassword());%0A        self.passwordFeedback(current.feedback.warning);%0A        return current.score;%0A    %7D);%0A%0A    self.passwordComplexityBar = ko.computed(function() %7B%0A        if (self.passwordComplexity() == 0) %7B%0A            return %7B%0A                class: 'progress-bar progress-bar-danger',%0A                style: 'width: 0%25'%0A            %7D;%0A        %7D%0A        if (self.passwordComplexity() == 1) %7B%0A            return %7B%0A                class: 'progress-bar progress-bar-danger',%0A                style: 'width: 25%25'%0A            %7D;%0A        %7D else if (self.passwordComplexity() == 2) %7B%0A            return %7B%0A                class: 'progress-bar progress-bar-warning progress-bar-striped active',%0A                style: 'width: 50%25'%0A            %7D;%0A        %7D else if (self.passwordComplexity() == 3) %7B%0A            return %7B%0A                class: 'progress-bar progress-bar-warning progress-bar-striped active',%0A                style: 'width: 75%25'%0A            %7D;%0A        %7D else if (self.passwordComplexity() == 4) %7B%0A            return %7B%0A                class: 'progress-bar progress-bar-success',%0A                style: 'width: 100%25'%0A            %7D;%0A        %7D%0A    %7D)
 ;%0A%0A 

Add password checkers to KO properties