class TimeWidget(forms.MultiWidget):
    """Input accurate timing. IntegerFields for hours, minutes, seconds, milliseconds."""
    
    NUM_FIELDS = 4 # Hours, Minutes, Seconds, Milliseconds
    
    def __init__(self, attrs=None):
        widgets = [forms.TextInput()] * self.NUM_FIELDS
        super(TimeWidget, self).__init__(widgets, attrs)
        
    def format_output(self, widgets):
        widgets.insert(1, ' : ')
        widgets.insert(3, ' : ')
        widgets.insert(5, ' . ')
        return mark_safe(''.join(widgets))
        
    def decompress(self, value):
        if value:
            return ('%d' % (value/3600), '%02d' % (value%3600/60), 
                    '%02d' % (value%3600%60), '%03d' % (value%1*1000))
        return [None] * self.NUM_FIELDS


class TimeField(forms.MultiValueField):
    """Input accurate timing. Interface with models.DecimalField for great success."""
    
    LABELS  = ['Hours', 'Minutes', 'Seconds', 'Milliseconds'] 
    SECONDS = [ 60*60,   60,        1,         0.001]
    widget = TimeWidget()
    
    def __init__(self, *args, **kwargs):
        fields = [forms.CharField(label=label) for label in self.LABELS]
        super(TimeField, self).__init__(fields, *args, **kwargs)
    
    def compress(self, value):
        if value:
            from operator import add, mul
            return str(reduce(add, 
                        map(lambda x: mul(*x), 
                            zip(map(float, value), self.SECONDS))))
        return None