define(["backbone", "js/models/location", "js/collections/course_grader"],
    function(Backbone, Location, CourseGraderCollection) {

var CourseGradingPolicy = Backbone.Model.extend({
    defaults : {
        graders : null,  // CourseGraderCollection
        grade_cutoffs : null,  // CourseGradeCutoff model
        grace_period : null, // either null or { hours: n, minutes: m, ...}
        minimum_grade_credit : null // either null or percentage
    },
    parse: function(attributes) {
        if (attributes['graders']) {
            var graderCollection;
            // interesting race condition: if {parse:true} when newing, then parse called before .attributes created
            if (this.attributes && this.has('graders')) {
                graderCollection = this.get('graders');
                graderCollection.reset(attributes.graders, {parse:true});
            }
            else {
                graderCollection = new CourseGraderCollection(attributes.graders, {parse:true});
            }
            attributes.graders = graderCollection;
        }
        // If grace period is unset or equal to 00:00 on the server,
        // it's received as null
        if (attributes['grace_period'] === null) {
            attributes.grace_period = {
                hours: 0,
                minutes: 0
            }
        }
        // If minimum_grade_credit is unset or equal to 0 on the server,
        // it's received as 0
        if (attributes.minimum_grade_credit === null) {
            attributes.minimum_grade_credit = 0;
        }
        return attributes;
    },
    gracePeriodToDate : function() {
        var newDate = new Date();
        if (this.has('grace_period') && this.get('grace_period')['hours'])
            newDate.setHours(this.get('grace_period')['hours']);
        else newDate.setHours(0);
        if (this.has('grace_period') && this.get('grace_period')['minutes'])
            newDate.setMinutes(this.get('grace_period')['minutes']);
        else newDate.setMinutes(0);
        if (this.has('grace_period') && this.get('grace_period')['seconds'])
            newDate.setSeconds(this.get('grace_period')['seconds']);
        else newDate.setSeconds(0);

        return newDate;
    },
    parseGracePeriod : function(grace_period) {
        // Enforce hours:minutes format
        if(!/^\d{2,3}:\d{2}$/.test(grace_period)) {
            return null;
        }
        var pieces = grace_period.split(/:/);
        return {
            hours: parseInt(pieces[0], 10),
            minutes: parseInt(pieces[1], 10)
        }
    },
    parseMinimumGradeCredit : function(minimum_grade_credit) {
        // get the value of minimum grade credit value in percentage
        if (isNaN(minimum_grade_credit)) {
            return 0;
        }
        return parseInt(minimum_grade_credit);
    },
    validate : function(attrs) {
        if(_.has(attrs, 'grace_period')) {
            if(attrs['grace_period'] === null) {
                return {
                    'grace_period': gettext('Grace period must be specified in HH:MM format.')
                }
            }
        }
        if(this.get('is_credit_course') && _.has(attrs, 'minimum_grade_credit')) {
            var minimum_grade_cutoff = _.values(attrs.grade_cutoffs).pop();
            if(isNaN(attrs.minimum_grade_credit) || attrs.minimum_grade_credit === null || attrs.minimum_grade_credit < minimum_grade_cutoff) {
                return {
                    'minimum_grade_credit': interpolate(
                        gettext('Not able to set passing grade to less than %(minimum_grade_cutoff)s%.'),
                        {minimum_grade_cutoff: minimum_grade_cutoff * 100},
                        true
                    )
                };
            }
        }
    }
});

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