=head1 NAME

Time::Timecode - Video timecode class

=head1 SYNOPSIS

 use Time::Timecode;

 my $tc1 = Time::Timecode->new(2, 0, 0, 12); # hh, mm, ss, ff
 print $tc1->fps;			     # $DEFAULT_FPS
 print $tc1;				     # 02:00:00:12
 print $tc1->hours;			     # 2
 print $tc1->hh;			     # shorthanded version

 my $tc2 = Time::Timecode->new('00:10:30:00', { fps => 25 } );
 print $tc2->total_frames;		     # 15750
 print $tc2->fps;			     # 25

 $tc2 = Time::Timecode->new(1800); 	     # Total frames
 print $tc1 + $tc2; 			     # 02:01:00:12

 $tc1 = Time::Timecode->new('00:01:00;04');  # Dropframe ( see the ";" )
 print $tc1->is_dropframe;		     # 1

 my $diff = $tc1 - 1800;		     # Subtract 1800 frames
 print $tc1->is_dropframe;		     # Maintains LHS' opts
 print $diff;				     # 00:00:02;00

 my $opts = { delimiter => ',', frame_delimiter => '+' };
 $Time::Timecode::DEFAULT_FPS = 23.976;      
 $tc2 = Time::Timecode->new('00,10,30+00', $opts); 
 print $tc2->fps			     # 23.976
 print $tc2->minutes;			     # 10
 print $tc2->seconds;			     # 30

 # Conversions
 my $pal  = $tc->convert(25);
 my $ntsc = $pal->convert(30), { dropframe => 1 });
 my $ndf  = $ntsc->to_non_dropframe;
 
=head1 DESCRIPTION

C<Time::Timecode> supports any frame rate, drop/non-drop frame counts, basic arithmetic, 
and conversion between frame rates and drop/non-drop frame counts. The only 
requirements are that the timecode be between 00:00:00:00 and 99:99:99:99, 
inclusive, and frames per second (fps) are greater than zero. This means that 
you can create nonstandard timecodes (feature or bug? :^). Dropframe rules will still 
apply.

C<Time::Timecode> instances can be created from a a variety of representations, 
see L</CONSTRUCTOR>. 

C<Time::Timecode> instances are immutable.

=head1 CONSTRUCTOR

=over 2

=item C<new( TIMECODE [, OPTIONS ] )>

Creates an immutable instance for C<TIMECODE> with the given set of C<OPTIONS>. 
If no C<OPTIONS> are given the L<"package defaults"|/DEFAULTS> are used.

=back

=head2 TIMECODE 

C<TIMECODE> can be one of the following:

=over 4

=item * A list denoting hours, minutes, seconds, and/or frames:

 $tc1 = Time::Timecode->new(1, 2, 3)
 $tc1 = Time::Timecode->new(1, 2, 3, 0)   #same as above

=item * Frame count:

 $tc1 = Time::Timecode->new(1800)   # 00:01:00:00 @ 30 fps

=item * Timecode string:

 $tc1 = Time::Timecode->new('00:02:00:25')

B<Timecode strings with dropframe frame delimiters>
 
In the video encoding world timecodes with a frame delimiter of '.' or ';' are 
dropframe. If either of these characters are used in the timecode string passed to C<new()>
the resulting instance will dropframe.

This can be overridden by setting the L<"dropframe argument"|/OPTIONS> to false. 

=back

=head2 OPTIONS

C<OPTIONS> must be a hash reference containg any of the following:

=over 4

B<fps>: Frames per second, must be greater than 0. Decimal values 
are rounded 0 places when performing calculations: 29.976 becomes 30.
Defaults to C<$Time::Timecode::DEFAULT_FPS>

B<dropframe>: A boolean value denoting wheather or not the timecode 
is dropframe. Defaults to C<$Time::Timecode::DEFAULT_DROPFRAME>.

B<delimiter>: The character used to delimit the timecode's hours, minutes, 
and seconds. Use the B<frame_delimiter> option for delimiting the frames.
Defaults to C<$Time::Timecode::DEFAULT_DELIMITER>.

B<frame_delimiter>: The character used to delimit the timecode's frames. 
Use the B<delimiter> option for delimiting the rest of the timecode.
Defaults to C<$Time::Timecode::DEFAULT_FRAME_DELIMITER>.

=back

=head1 METHODS

All time part accessors return an integer.

=over 2

=item C<hours()>

=item C<hrs()>

=item C<hh()>

Returns the hour part of the timecode 

=item C<minutes()>

=item C<mins()>

=item C<mm()>

Returns the mintue part of the timecode

=item C<seconds()>

=item C<secs()>

=item C<ss()>

Returns the second part of the timecode

=item C<frames()>

=item C<ff()>

Returns the frame part of the timecode

=item C<fps()>

Returns the frames per second

=item C<to_string()>

Returns the timecode as string in a HH:MM:SS:FF format.

The delimiter used to separate each portion of the timecode can vary.
If the C<delimiter> or C<frame_delimiter> options were provided they 
will be used here. If the timecode was created from a timecode string
that representation will be reconstructed.

This method is overloaded. Using a C<Time::Timecode> instance in a scalar
context results in a call to C<to_string()>.

=item C<is_dropframe()>

Returns a boolean value denoting whether or not the timecode is dropframe.

=item C<to_non_dropframe()>

Converts the timecode to non-dropframe and returns a new C<Time::Timecode> instance.
The framerate is not changed.

If the current timecode is non-dropframe C<$self> is returned.

=item C<to_dropframe()>

Converts the timecode to dropframe and returns a new C<Time::Timecode> instance.
The framerate is not changed.

If the current timecode is dropframe C<$self> is returned.

=item C<convert( FPS [, OPTIONS ] )>

Converts the timecode to C<FPS> and returns a new instance.

C<OPTIONS> are the same as L<those allowed by the CONSTRUCTOR|/OPTIONS>. Any unspecified options 
are taken from the calling instance.

The converted timecode will be non-dropframe.

=back

=head1 ARITHMATIC

=over 2

=item Addition

=item Subtraction

=item Multiplacation

=item Division

All results get their options from the left hand side (LHS) of the expression. If LHS 
is a literal, options will be taken from RHS.

=back

=head1 DEFAULTS

These can be overridden L<when creating a new instance|/CONSTRUCTOR>.

C<$DEFAULT_FPS = 29.97>

C<$DEFAULT_DROPFRAME = 0>

C<$DEFAULT_DELIMITER = ':'>

C<$DEFAULT_FRAME_DELIMITER = ':'>

=head1 AUTHOR

Skye Shaw (sshaw AT lucas.cis.temple.edu)

=head1 REFERENCES

For information about dropframe timecodes see:
L<http://dropframetimecode.org/>, L<http://en.wikipedia.org/wiki/SMPTE_time_code#Drop_frame_timecode>

=head1 COPYRIGHT

Copyright (c) 2009-2010 Skye Shaw. All rights reserved. This program
is free software; you can redistribute it and/or modify it under the
same terms as Perl itself.
