define(["backbone", "underscore", "gettext"], function(Backbone, _, gettext) {

var CourseGrader = Backbone.Model.extend({
    defaults: {
        "type" : "",    // must be unique w/in collection (ie. w/in course)
        "min_count" : 1,
        "drop_count" : 0,
        "short_label" : "", // what to use in place of type if space is an issue
        "weight" : 0 // int 0..100
    },
    parse : function(attrs) {
        // round off values while converting them to integer
        if (attrs['weight']) {
            attrs.weight = Math.round(attrs.weight);
        }
        if (attrs['min_count']) {
            attrs.min_count = Math.round(attrs.min_count);
        }
        if (attrs['drop_count']) {
            attrs.drop_count = Math.round(attrs.drop_count);
        }
        return attrs;
    },
    validate : function(attrs) {
        var errors = {};
        if (_.has(attrs, 'type')) {
            if (_.isEmpty(attrs['type'])) {
                errors.type = "The assignment type must have a name.";
            }
            else {
                // FIXME somehow this.collection is unbound sometimes. I can't track down when
                var existing = this.collection && this.collection.some(function(other) { return (other.cid != this.cid) && (other.get('type') == attrs['type']);}, this);
                if (existing) {
                    errors.type = gettext("There's already another assignment type with this name.");
                }
            }
        }
        if (_.has(attrs, 'weight')) {
            var intWeight = Math.round(attrs.weight); // see if this ensures value saved is int
            if (!isFinite(intWeight) || /\D+/.test(attrs.weight) || intWeight < 0 || intWeight > 100) {
                errors.weight = gettext("Please enter an integer between 0 and 100.");
            }
            else {
                attrs.weight = intWeight;
                if (this.collection && attrs.weight > 0) {
                    // FIXME b/c saves don't update the models if validation fails, we should
                    // either revert the field value to the one in the model and make them make room
                    // or figure out a holistic way to balance the vals across the whole
//                  if ((this.collection.sumWeights() + attrs.weight - this.get('weight')) > 100)
//                  errors.weight = "The weights cannot add to more than 100.";
                }
            }}
        if (_.has(attrs, 'min_count')) {
            var intMinCount = Math.round(attrs.min_count);
            if (!isFinite(intMinCount) || /\D+/.test(attrs.min_count) || intMinCount < 1) {
                errors.min_count = gettext("Please enter an integer greater than 0.");
            }
            else attrs.min_count = intMinCount;
        }
        if (_.has(attrs, 'drop_count')) {
            var dropCount = attrs.drop_count;
            var intDropCount = Math.round(dropCount);
            if (!isFinite(intDropCount) || /\D+/.test(dropCount) || (_.isString(dropCount) && _.isEmpty(dropCount.trim())) || intDropCount < 0) {
                errors.drop_count = gettext("Please enter non-negative integer.");
            }
            else attrs.drop_count = intDropCount;
        }
        if (_.has(attrs, 'min_count') && _.has(attrs, 'drop_count') && !_.has(errors, 'min_count') && !_.has(errors, 'drop_count') && attrs.drop_count > attrs.min_count) {
            var template = _.template(
                gettext("Cannot drop more <%= types %> assignments than are assigned.")
            );
            errors.drop_count = template({types: attrs.type});
        }
        if (!_.isEmpty(errors)) return errors;
    }
});

return CourseGrader;
}); // end define()
