/* 
   ------------------------------------------------------------------------
   cdcontrol.c : accept orders from the CD player and send the appropriate
   commands to hardware control functions.
   ------------------------------------------------------------------------
   based on ascd < 0.6, revamped to use exclusively WorkMan style variables
*/
								   
#include "ascd.h"
#include "../lib/struct.h"

extern cd_status();
extern play_cd();
extern stop_cd();
extern eject_cd();
extern pause_cd();

extern load();
extern save();
extern split_workmandb();
extern WMstrdup(char *);

extern open();

extern newtext(char *);

extern int cur_track, cur_index, cur_lasttrack, cur_firsttrack, cur_pos_abs ;
extern int cur_frame, cur_pos_rel, cur_tracklen, cur_cdlen, cur_ntracks ;
extern int cur_nsections, cur_listno, cur_stopmode, exit_on_eject, cur_balance ;
extern enum cd_modes cur_cdmode;
extern char *cur_artist, *cur_cdname, *cur_trackname;
extern char cur_contd, cur_avoid;
extern char *cd_device;
extern struct cdinfo_wm thiscd, *cd;
extern int found_in_db;

extern int wanted_track;
extern unsigned int do_autorepeat;

extern int anomalie;

/* xfascd vars */

extern unsigned int wanna_play;

extern unsigned int update_xpm;
extern unsigned int loop_mode, intro_mode;
extern unsigned int datatrack, cue_time;
extern unsigned int loop_start_track, loop_end_track;
extern unsigned int loop_1;
extern unsigned int loop_2;
extern unsigned int direct_access, direct_track;

void cd_control(int order)
{
    static int pos_changed = FALSE;
    int currenttrack;

    anomalie = 0;

    wanna_play = FALSE;

    /*update_xpm = 1;*/

    if (cd_status() != 1) {
	if ((cur_cdmode != PLAYING) && (order == STOP)) {
	    eject_cd();
	}
	return;
    }
    
    if (cur_cdmode != EJECTED) {
	if (cd->trk[cur_track - 1].data) datatrack = 1;
	else datatrack = 0;
    }

    switch(order) {

    case PLAY:
	loop_mode = 0;
	intro_mode = 0;
	if (! pos_changed) {
	    cd_status();
	} else {
	    pos_changed = FALSE;
	}

	/* don't play data tracks: */
          
	if (! cd->trk[cur_track - 1].data) {
	    if (cur_cdmode != EJECTED) {
		if (cur_cdmode != PAUSED) {
		    if (do_autorepeat) {
			cur_track = 1;
			do_autorepeat = FALSE;
		    }
		    /* if it's a data track, skip it */
		    while ((cd->trk[cur_track - 1].data) && (cur_track <= cur_ntracks)) {
			cur_track++;
		    }
		    if (cur_track > cur_ntracks) cur_track--;
		    if (!(cd->trk[cur_track - 1].data)) {
			wanna_play = TRUE;
			play_cd(cur_track, 0, cur_ntracks + 1);
		    } else {
			newtext("DATA");
		    }
		}
	    }
	}
	break;

    case PAUSE:
	loop_mode = 0;
	intro_mode = 0;

	if (pos_changed) {
	    cur_track = wanted_track;
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	    cur_cdmode = PLAYING;
	} else {
	    pause_cd();
	}

	if (cur_cdmode == PLAYING) {
	    pos_changed = FALSE;
	}
	break;

    case STOP:
	loop_mode = 0;
	intro_mode = 0;
	if ((cur_cdmode == PLAYING) || (cur_cdmode == PAUSED)) {
	    cur_cdmode = PAUSED;
	    stop_cd();
	    cur_cdmode = STOPPED;
	} else {
	    currenttrack = 0;
	    eject_cd();
	}
	pos_changed = FALSE;
	break;

    case UPTRACK: /* next track */
	loop_mode = 0;
	intro_mode = 0;
	if (pos_changed) cur_track = wanted_track;

	if (cur_track + 1 > cur_ntracks ) {
	    cur_track = 1;
	} else {
	    cur_track ++;
	}
	if (cur_cdmode == PAUSED) {
	    pos_changed = TRUE;
	    wanted_track = cur_track;
	}
	if (cur_cdmode == PLAYING) {
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	}
	break;

    case DNTRACK: /* previous track */
	loop_mode = 0;
	intro_mode = 0;
	if (pos_changed) cur_track = wanted_track;

	if (cur_cdmode == PAUSED) {
	    if (cur_pos_rel < 2 || pos_changed) cur_track--;
	    cur_pos_rel = 0;
	    pos_changed = TRUE;
	} else if (cur_cdmode == PLAYING) {
	    if (cur_pos_rel < 2) cur_track--;
	    cur_pos_rel = 0;
	} else {
	    cur_track--;
	}
	if (cur_track < 1) cur_track = cur_ntracks;
	if (cur_cdmode == PAUSED) {
	    pos_changed = TRUE;
	    wanted_track = cur_track;
	}
	if (cur_cdmode == PLAYING) {
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	}
	break;

    case DIRECTTRACK:
	loop_mode = 0;
	intro_mode = 0;
	if (cur_cdmode == PAUSED) pos_changed = TRUE;
	cur_track = direct_track;
	if (cur_track >= cur_ntracks + 1) cur_track = 1;

	/* if it's a data track, skip it */
	while ((cd->trk[cur_track - 1].data) && (cur_track <= cur_ntracks)) cur_track++;
          
	if (cur_cdmode == PLAYING) {
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	}
	break;

    case CUE:
	loop_mode = 0;
	intro_mode = 0;
	if (cur_cdmode == PLAYING) play_cd(cur_track, cur_pos_rel + cue_time, cur_ntracks + 1);
	break;

    case REV:
	loop_mode = 0;
	intro_mode = 0;
	if ( (cur_cdmode == PLAYING) && ( (cur_pos_rel - cue_time) >= 0 ) ) {
	    wanna_play = TRUE;
	    play_cd(cur_track, cur_pos_rel - cue_time, cur_ntracks + 1);
	}
	break;

    case FIRST:
	loop_mode = 0;
	intro_mode = 0;
	cur_track = 1;
	if (cur_cdmode == PLAYING) {
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	}
	break;

    case LAST:
	loop_mode = 0;
	intro_mode = 0;
	cur_track = cur_ntracks;
	if (cur_cdmode == PLAYING) {
	    wanna_play = TRUE;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	}
	break;

    case LOOP:
	if ( (loop_2 > loop_1) ||
	     (loop_end_track > loop_start_track) ) {
               
	    if (loop_start_track == 0) loop_start_track = 1;
	    intro_mode = 0;
	    if ( ( loop_2 > loop_1 ) 
		 || ( loop_start_track != loop_end_track ) )
		currenttrack = loop_start_track;
	    else {
		loop_end_track = cur_ntracks;
		currenttrack = loop_start_track = 1;
		loop_1 = 0;
		loop_2 = 
		    thiscd.trk[ loop_end_track - 1 ].length - 1;
	    }
	    play_cd(loop_start_track, loop_1, cur_ntracks + 1);
	    wanna_play = TRUE;
	    loop_mode = 1;
	} else {
	    anomalie = 1;
	}
	break;

    case DIRECTACCESS:
	if (direct_access < 0) direct_access = 0;
	loop_mode = 0;
	intro_mode = 0;
	cd_status();
	play_cd(cur_track, direct_access, cur_ntracks + 1);
	wanna_play = TRUE;
	break;

    case GLOBALACCESS:
	if (direct_access < 0) direct_access = 0;
	loop_mode = 0;
	intro_mode = 0;
	cd_status();
	play_cd(1, direct_access, cur_ntracks + 1);
	wanna_play = TRUE;
	break;

    case INTROSCAN:
	if (! intro_mode) {
	    intro_mode = 1;
	    play_cd(cur_track, 0, cur_ntracks + 1);
	} else {
	    intro_mode = 0;
	}
	break;
          
    case INTRONEXT:
	pause_cd();
	currenttrack = cur_track;
	currenttrack++;
	if (cur_track +1 > cur_ntracks ) currenttrack = 1;
	else currenttrack = cur_track + 1;
	cur_pos_rel = 0;
	play_cd(currenttrack, 0, cur_ntracks + 1);
	break;
          
    case LOCACCESS:
	if ( (loop_1 > 0) && (loop_start_track > 0) ) {
	    intro_mode = 0;
	    loop_mode = 0;
	    currenttrack = loop_start_track;
	    stop_cd();
	    play_cd(loop_start_track, loop_1, cur_ntracks + 1);
	    wanna_play = TRUE;
	} else {
	    anomalie = 1;
	}
	break;
    }
}
