/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef _SOURCE_INTERNAL_H
#define _SOURCE_INTERNAL_H

#include "playlist.h"

#define HALF_UINT32_MAX 2147483647U
#define MAS_STREAM_END -64


enum stream_state
{
    STOP_STATE = 0,
    PAUSE_STATE = 1,
    PLAY_STATE = 2,
    START_STATE = 3
};

struct track_info
{
    FILE* file;     /* used if it's a file stream */
    char* filename;

    uint32 period;       /* polling period, if used, otherwise zero */
    int32  period_clkid;

    int32 length;       /* stream length, if known, otherwise zero */
    double length_sec;

    int   invalid; /* if set, the track is unplayable. */
    void* fdti; /* points to format-dependent track info structure */

    struct track_info* prev;
    struct track_info* next;
};

struct source_state
{
    int32 device_instance;
    int32 reaction;
    int32 sink;
    int32 source;

    int sink_configured;
    int source_configured;
    int polling_scheduled;

    uint32 seq; /* next sequence # */
    int    mark; /* mark the next packet that goes out */
    int32 use_clkid; /* use this clock id */
    enum stream_state strst; /* the current state of the stream */
    int set_clkid; /* boolean: set clock id? */
    int newformat; /* boolean: has the format changed? */
    int preferred_clkid; /* i.e., an anx estimate based clock; -1 will mean no preferred clock */
    
    struct track_info* ti; /* current track - points to entry in
                            * playlist */

    struct plist* pl;

    void* fdstate; /* format-dependent state pointer */
};

extern char* repeat_mode[];

/*
 * FORMAT DEPENDENT ACTIONS
 *
 * These must be implemented for any new format.
 *
 */

extern int32 sourcex_init_instance( struct source_state* state );
extern int32 sourcex_exit_instance( struct source_state* state );
extern int32 sourcex_configure_port( struct source_state* state, int32 portnum );
extern int32 sourcex_disconnect_port( struct source_state* state, int32 portnum );
extern int32 sourcex_show_state( struct source_state* state );
extern int32 sourcex_stop( struct source_state* state );
extern int32 sourcex_play( struct source_state* state );
extern int32 sourcex_pause( struct source_state* state );
extern int32 sourcex_next_track( struct source_state* state );
extern int32 sourcex_prev_track( struct source_state* state );
extern int32 sourcex_cue_track( struct source_state* state, struct track_info* ti );
extern int32 sourcex_get_data( struct source_state* state, struct track_info* ti, uint32 seq, struct mas_data** data_ptr );
extern int32 sourcex_fill_out_track_info( struct source_state* state, struct track_info* ti );
extern int sourcex_format_diff( struct source_state* state, struct track_info* ti, struct track_info* prev_ti );
extern struct mas_data_characteristic* sourcex_get_track_dc( struct source_state* state, struct track_info* ti );

#endif /* _SOURCE_INTERNAL_H */
