(function ($) {

/*
Change Log
==========

2 May 2010: timecode_tosecs returns null (not undefined) on no match
*/

// hours optional
timecode_tosecs_pat = /^(?:(\d\d):)?(\d\d):(\d\d)(,(\d{1,3}))?$/;

function zeropad (n, toplaces) {
    var ret = ""+n;
    var foo = toplaces - ret.length;
    for (var i=0; i<foo; i++) {
        ret = "0"+ret;
    }
    return ret;
}

function zeropostpad (n, toplaces) {
    var ret = ""+n;
    var foo = toplaces - ret.length;
    for (var i=0; i<foo; i++) {
        ret = ret+"0";
    }
    return ret;
}

function timecode_tosecs (tcstr) {
    // seeks and returns first timecode pattern and returns it in secs
    // nb: timecode can appear anywhere in string, will only convert first match
    // note that the parseInt(f, 10), the 10 is necessary to avoid "09" parsing as octal (incorrectly returns 0 then since 9 is an invalid octal digit)
    r = tcstr.match(timecode_tosecs_pat);
    if (r) {
        ret = 0;
        if (r[1]) {
            ret += 3600 * parseInt(r[1], 10);
        }
        ret += 60 * parseInt(r[2], 10);
        ret += parseInt(r[3], 10);
        if (r[5]) {
            ret = parseFloat(ret+"."+r[5]);
        }
        return ret;
    } else {
        return null;
    }
}

function timecode_fromsecs (rawsecs, fract, alwaysfract) {
    if (fract === undefined) { fract = false; }
    if (alwaysfract === undefined) { alwaysfract = false; }
    // returns a string in HH:MM:SS[.xxx] notation
    // if fract is True, uses .xxx if either necessary (non-zero) OR alwaysfract is True
    // var hours = Math.floor(rawsecs / 3600);
    // rawsecs -= hours*3600;
    var mins = Math.floor(rawsecs / 60);
    rawsecs -= mins*60;
    var secs;
    if (fract) {
        secs = Math.floor(rawsecs);
        rawsecs -= secs;
        if ((rawsecs > 0) || alwaysfract) {
            fract = zeropostpad((""+rawsecs).substr(2, 3), 3);
            // return zeropad(hours, 2)+":"+zeropad(mins, 2)+":"+zeropad(secs, 2)+","+fract;
            return zeropad(mins, 2)+":"+zeropad(secs, 2)+","+fract;
        } else {
            // return zeropad(hours, 2)+":"+zeropad(mins, 2)+":"+zeropad(secs, 2);
            return zeropad(mins, 2)+":"+zeropad(secs, 2);
        }
    } else {
        secs = Math.floor(rawsecs);
        // return zeropad(hours, 2)+":"+zeropad(mins, 2)+":"+zeropad(secs, 2);
        return zeropad(mins, 2)+":"+zeropad(secs, 2);
    }
}

function timecode_tosecs_attr(val) {
    if (val) {
        if (typeof(val) == "string") {
            var tc = timecode_tosecs(val);
            if (tc !== null) { return tc; }
        }
        return parseFloat(val);
    }
    return val;
}                        

// export
$.timecode_fromsecs = timecode_fromsecs;
$.timecode_tosecs = timecode_tosecs;
$.timecode_tosecs_attr = timecode_tosecs_attr;
// alternate names
$.timecode_parse = timecode_tosecs_attr;
$.timecode_unparse = timecode_fromsecs;

})(jQuery);


