(function($){
    
    $.fn.createCFCountdown = function(options) {
        
        options = $.extend({
            
            seconds: 60,
            showCentiseconds: true,
            complete: function() {}
            
        }, options);
        
        var container = this;

        var now = function() { return +new Date(); };
        
        var secondsToMilliseconds = 1000;
        var millisecondsRemaining = options.seconds * secondsToMilliseconds;
        var tickCounter = 0;
        
        
        var timerElement = $('<div class="cf-timer"><p><span class="number">00</span><span class="colon">:</span><span class="number">00</span><span class="colon">:</span><span class="number">00</span></p></div>');
        var minutes = timerElement.find('span.number').eq(0);
        var seconds = timerElement.find('span.number').eq(1);
        var centiseconds = timerElement.find('span.number').eq(2);

        var startTime = now();

        var intervalDelay = options.showCentiseconds ? 85 : 850;
        
        
        
        var interval = setInterval(function() {
            
            var minutesRemaining = Math.floor(millisecondsRemaining / (60 * secondsToMilliseconds)) % 60;
            var secondsRemaining = Math.floor((millisecondsRemaining / secondsToMilliseconds)) % 60;
            var centisecondsRemaining = Math.floor((options.showCentiseconds && millisecondsRemaining > 3 ? millisecondsRemaining / 10 : 0) % 100);
            
            var minuteString = (minutesRemaining < 10 ? "0" : "") + minutesRemaining;
            var secondString = (secondsRemaining < 10 ? "0" : "") + secondsRemaining;
            var centisecondString = (centisecondsRemaining < 10 ? "0" : "") + centisecondsRemaining;
            
            minutes.text(minuteString);
            seconds.text(secondString);
            centiseconds.text(centisecondString);
            
            // occasionally sync to actual time passed in case tab lost focus during load,
            // which now causes time dilation in chrome and ff
            // also, don't sync if displayed time is fast or close enough
            if (++tickCounter % (options.showCentiseconds ? 10 : 1)) {

                millisecondsRemaining -= intervalDelay;
            } else {

                // compute real value of millisecondsRemaining
                var adjustedTime = (options.seconds * secondsToMilliseconds) - (now() - startTime);

                // abort if displayed time is within 40ms of real time, or if displayed time is fast
                if (adjustedTime + 40 < (millisecondsRemaining - intervalDelay)) {

                    millisecondsRemaining = adjustedTime;
                } else {

                    millisecondsRemaining -= intervalDelay;
                }
            }
            
            if(millisecondsRemaining <= 0) {
                
                clearInterval(interval);
                options.complete();
                
            }
            
        }, intervalDelay);
        
        
        container.empty();
        container.append(timerElement);
        
        
        var dimensions = {width: 1, height: 0};
        
        timerElement.find('span').each(function(i, e) {
            
            var element = $(e);
            var marginLeft = parseInt(element.css('marginLeft').substr(0, element.css('marginLeft').length - 2));
            var marginRight = parseInt(element.css('marginRight').substr(0, element.css('marginRight').length - 2));
            
            dimensions.width += (element.width() + marginLeft + marginRight);
            dimensions.height = Math.max($(e).height(), dimensions.height);
            
        });
    
        container.css({width: dimensions.width + 'px', height: dimensions.height + 'px'});
        
        
        
        
        
    }
    
    
})(jQuery);

