/**
 * call-seq:
 *  tracks() -> array
 *  tracks() {|offset, length| block }
 * 
 * Returns an array of <tt>[offset, length]</tt> tuples for each track.
 * 
 * Offset and length are both integer values representing sectors.
 * If a block is given this method returns +nil+ and instead iterates over the
 * block calling the block with two arguments <tt>|offset, length|</tt>.
 *
 * Returns always +nil+ if no ID was yet read. The block won't be called in
 * this case.
 *
 * You may want to use the method track_details instead of this method to
 * retrieve more detailed information about the tracks.
 */
static VALUE mb_discid_tracks(VALUE self)
{
        if (rb_iv_get(self, "@read") == Qfalse)
                return Qnil;
        else
        {
                DiscId *disc; /* Pointer to the disc struct */
                VALUE result = rb_ary_new(); /* Array of all [offset, length] tuples */
                VALUE tuple; /* Array to store one [offset, length] tuple. */
                int track;   /* Counter for the track number to process. */
                
                Data_Get_Struct(self, DiscId, disc);
                
                track = discid_get_first_track_num(disc); /* First track number */
                while (track <= discid_get_last_track_num(disc))
                {
                        tuple = rb_ary_new3(2,
                                INT2FIX(discid_get_track_offset(disc, track)),
                                INT2FIX(discid_get_track_length(disc, track)) );
                        
                        if (rb_block_given_p())
                                rb_yield(tuple);
                        else
                                rb_ary_push(result, tuple);
                                
                        track++;
                }
                
                if (rb_block_given_p())
                        return Qnil;
                else
                        return result;
        }
}