/*
   Interface to the CDROM drive.

   -- Roy Keene [021119991200] cdplay@rkeene.org
*/

#include <stdlib.h>
#include <err.h>
#include <errno.h>
#include <asm/errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include <linux/cdrom.h>
#include "cdrom.h"


int open_cdrom(char *cdromfile) {
   int cdrom_fd;
   cdrom_fd=open(cdromfile, O_RDONLY|O_NONBLOCK);
#ifdef DEBUG
   printf("cdrom.c: open_cdrom(\"%s\")=%i\n",cdromfile,cdrom_fd);
   if (cdrom_fd<0) { printf("cdrom.c: open_cdrom: Couldn't open %s\n",cdromfile); }
#endif
   return cdrom_fd;
}

void cd_eject(int cdrom_fd) {
#ifdef DEBUG
   printf("cdrom.c: cd_eject(cdrom_fd)\n");
#endif
   cd_stop(cdrom_fd);
#ifdef DEBUG
   printf("cdrom.c: cd_eject: ioctl(cdrom,CDROMEJECT)=%i\n",ioctl(cdrom_fd, CDROMEJECT));
#else
   ioctl(cdrom_fd, CDROMEJECT);
#endif
}

void cd_playtrack(int cdrom_fd, int track) {
   static struct cdrom_ti trackindex;
   trackindex.cdti_trk0=track;
   trackindex.cdti_trk1=track;
   trackindex.cdti_ind0=0;
   trackindex.cdti_ind1=0;
#ifdef DEBUG
   printf("cdrom.c: cd_playtrack(cdrom_fd, %i)\n",track);
   printf("cdrom.c: cd_playtrack: ioctl(cdrom_fd,CDROMSTART)=%i\n",ioctl(cdrom_fd,CDROMSTART));
   printf("cdrom.c: cd_playtrack: ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex)=%i\n",ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex));
#else
   ioctl(cdrom_fd,CDROMSTART);
   ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex);
#endif
}

void cd_play(int cdrom_fd, int starttrack) {
   static struct cdrom_ti trackindex;
   trackindex.cdti_trk0=starttrack;
   trackindex.cdti_ind0=0;
   trackindex.cdti_ind1=0;
#ifdef DEBUG
   printf("cdrom.c: cd_play(cdrom_fd, %i)\n",starttrack);
   trackindex.cdti_trk1=cd_num_tracks(cdrom_fd, 0);
   printf("cdrom.c: cd_play: ioctl(cdrom_fd,CDROMSTART)=%i\n",ioctl(cdrom_fd,CDROMSTART));
   perror("cdrom.c: cd_play: perror");
   printf("cdrom.c: cd_play: ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex)=%i\n",ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex));
   perror("cdrom.c: cd_play: perror");
#else
   trackindex.cdti_trk1=cd_num_tracks(cdrom_fd, 0);
   ioctl(cdrom_fd,CDROMSTART);
   ioctl(cdrom_fd,CDROMPLAYTRKIND,&trackindex);
#endif
}


void cd_stop(int cdrom_fd) {
#ifdef DEBUG
   printf("cdrom.c: cd_stop(cdrom_fd)\n");
   printf("cdrom.c: cd_stop: ioctl(cdrom_fd,CDROMSTOP)=%i\n",ioctl(cdrom_fd,CDROMSTOP));
#else
   ioctl(cdrom_fd,CDROMSTOP);
#endif
}


int cd_num_tracks(int cdrom_fd, int start) {
   struct cdrom_tochdr toc;
#ifdef DEBUG
   printf("cdrom.c: cd_num_tracks(cdrom_fd, %i)\n", start);
   printf("cdrom.c: cd_num_tracks: ioctl(cdrom_fd, CDROMREADTOCHDR, &toc)=%i\n",   ioctl(cdrom_fd, CDROMREADTOCHDR, &toc));
   printf("cdrom.c: cd_num_tracks: toc.cdth_trk0=%i\n",toc.cdth_trk0);
   printf("cdrom.c: cd_num_tracks: toc.cdth_trk1=%i\n",toc.cdth_trk1);
#else
   ioctl(cdrom_fd, CDROMREADTOCHDR, &toc);
#endif
   if (start==1) return(toc.cdth_trk0);
   return(toc.cdth_trk1-toc.cdth_trk0+1);
}


int cd_isplaying(int cdrom_fd) {
  struct cdrom_subchnl status;
  status.cdsc_format=CDROM_MSF;
#ifdef DEBUG
  int ioctl_retval, retval=0;
  ioctl_retval=ioctl(cdrom_fd,CDROMSUBCHNL,&status);
  if (status.cdsc_audiostatus==17) retval=1;
  printf("cdrom.c: cd_isplaying(cdrom_fd)=%i\n",retval);
  printf("cdrom.c: cd_isplaying: ioctl(cdrom_fd, CDROMSUBCHNL, &status)=%i\n",ioctl_retval);
  printf("cdrom.c: cd_isplaying: status.cdsc_audiostatus=%i\n",status.cdsc_audiostatus);
  printf("cdrom.c: cd_isplaying: status.cdsc_ctrl=%i\n",status.cdsc_ctrl);
  printf("cdrom.c: cd_isplaying: status.cdsc_format=%i\n",status.cdsc_format);
  printf("cdrom.c: cd_isplaying: status.cdsc_adr=%i\n",status.cdsc_adr);
  printf("cdrom.c: cd_isplaying: status.cdsc_trk=%i\n",status.cdsc_trk);
  printf("cdrom.c: cd_isplaying: status.cdsc_ind=%i\n",status.cdsc_ind);
  printf("cdrom.c: cd_isplaying: status.cdsc_absaddr.msf.minute=%lu\n",(long) status.cdsc_absaddr.msf.minute);
  printf("cdrom.c: cd_isplaying: status.cdsc_absaddr.msf.second=%lu\n",(long) status.cdsc_absaddr.msf.second);
  return(retval);
#else
  ioctl(cdrom_fd,CDROMSUBCHNL,&status);
  if (status.cdsc_audiostatus==17) return(1);
  return(0);
#endif
}

int cd_currenttrack(int cdrom_fd) {
  struct cdrom_subchnl status;
  status.cdsc_format=CDROM_MSF;
#ifdef DEBUG
  int retval=0;
  retval=ioctl(cdrom_fd,CDROMSUBCHNL,&status);
  printf("cdrom.c: cd_currenttrack(cdrom_fd)=%i\n",status.cdsc_trk);
  printf("cdrom.c: cd_currenttrack: ioctl(cdrom_fd, CDROMSUBCHNL, &status)=%i\n",retval);
  printf("cdrom.c: cd_currenttrack: status.cdsc_audiostatus=%i\n",status.cdsc_audiostatus);
  printf("cdrom.c: cd_currenttrack: status.cdsc_ctrl=%i\n",status.cdsc_ctrl);
  printf("cdrom.c: cd_currenttrack: status.cdsc_format=%i\n",status.cdsc_format);
  printf("cdrom.c: cd_currenttrack: status.cdsc_adr=%i\n",status.cdsc_adr);
  printf("cdrom.c: cd_currenttrack: status.cdsc_trk=%i\n",status.cdsc_trk);
  printf("cdrom.c: cd_currenttrack: status.cdsc_ind=%i\n",status.cdsc_ind);
  printf("cdrom.c: cd_currenttrack: status.cdsc_absaddr.msf.minute=%lu\n",(long) status.cdsc_absaddr.msf.minute);
  printf("cdrom.c: cd_currenttrack: status.cdsc_absaddr.msf.second=%lu\n",(long) status.cdsc_absaddr.msf.second);
#else
  ioctl(cdrom_fd,CDROMSUBCHNL,&status);  
#endif
  return(status.cdsc_trk);
}

void cd_setvolume(int cdrom_fd, unsigned char volume) {
  struct cdrom_volctrl cdvolume;
  cdvolume.channel0=volume;
  cdvolume.channel1=volume;
  cdvolume.channel2=volume;
  cdvolume.channel3=volume;
#ifdef DEBUG
  printf("cdrom.c: cd_setvolume(cdrom_fd, %i)\n",volume);
  printf("cdrom.c: cd_setvolume: ioctl(cdrom_fd, CDROMVOLCTRL, &cdvolume)=%i\n",  ioctl(cdrom_fd, CDROMVOLCTRL, &cdvolume));
#else
  ioctl(cdrom_fd, CDROMVOLCTRL, &cdvolume);
#endif
}

int cd_getvolume(int cdrom_fd) {
  struct cdrom_volctrl cdvolume;
#ifdef DEBUG
  int ioctl_retval;
  ioctl_retval=ioctl(cdrom_fd, CDROMVOLREAD, &cdvolume);
  printf("cdrom.c: cd_getvolume(cdrom_fd)=%i\n",cdvolume.channel0);
  printf("cdrom.c: cd_getvolume: ioctl(cdrom_fd, CDROMVOLREAD, &cdvolume)=%i\n",ioctl_retval);
  printf("cdrom.c: cd_getvolume: cdvolume.channel0=%i\n",cdvolume.channel0);
  printf("cdrom.c: cd_getvolume: cdvolume.channel1=%i\n",cdvolume.channel1);
  printf("cdrom.c: cd_getvolume: cdvolume.channel2=%i\n",cdvolume.channel2);
  printf("cdrom.c: cd_getvolume: cdvolume.channel3=%i\n",cdvolume.channel3);
#else
  ioctl(cdrom_fd, CDROMVOLREAD, &cdvolume);
#endif
  return(cdvolume.channel0);
}
