/***************************************************************************
 *   Copyright (C) 2005 by Roland Weigert   *
 *   roweigert@t-online.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "cdidgenerator.h"

cdrominfo::cdrominfo()
{
  //initialize cdtoc-strcuture
  for (int i=0;i<100;i++)
    {
      cdtoc[i].min=0;
      cdtoc[i].sec=0;
      cdtoc[i].frame=0;
      cdtoc[i].mode=0;
      cdtoc[i].frameoffset=0;
    }
  trackcount=0;
  int cdrom=0;
  cdrom=open(CDROM,O_RDONLY);
  if (cdrom==-1)
    {
      if(errno==ENOMEDIUM)
        cout<<"No Disc in CDROM"<<endl;
      else
        {
          cerr<<"Could not open /dev/cdrom"<<endl;
          discreadok=0;
        }
    }
  else
    {
      struct cdrom_tochdr cdindexes;
      struct cdrom_tocentry tocentry;
      //initialize values, to stop valgrind from complaining
      cdindexes.cdth_trk0=0;
      cdindexes.cdth_trk1=0;
      tocentry.cdte_addr.msf.minute=0;
      tocentry.cdte_addr.msf.second=0;
      tocentry.cdte_addr.msf.frame=0;
      tocentry.cdte_track=0;
      tocentry.cdte_format=0;
      int track=0;
      if (ioctl(cdrom,CDROMREADTOCHDR,&cdindexes)==-1)
        {
          cerr<<"Could not fetch header from CD"<<endl;
          discreadok=0;
        }
      else
        {
          trackcount=cdindexes.cdth_trk1;
          track=cdindexes.cdth_trk0;
          while(track<=trackcount)
            {
              tocentry.cdte_track=track;
              tocentry.cdte_format=CDROM_MSF;
              if (ioctl(cdrom,CDROMREADTOCENTRY,&tocentry)==-1)
                {
                  cerr<<"Could not fetch tracks from CD"<<endl;
                  discreadok=0;
                  track=trackcount;
                }
              else
                //read in toc into struct cdtoc
                discreadok=1;
              cdtoc[track-1].min=(int) tocentry.cdte_addr.msf.minute;
              cdtoc[track-1].sec=(int) tocentry.cdte_addr.msf.second;
              cdtoc[track-1].frame=(int) tocentry.cdte_addr.msf.frame;
              cdtoc[track-1].mode=(int) tocentry.cdte_ctrl;//mode 0=audio,mode 4=data
              cdtoc[track-1].frameoffset=(cdtoc[track-1].min*60+cdtoc[track-1].sec)*75+cdtoc[track-1].frame-150;
              track++;
            }
        }
      if(discreadok)
        {
          //enter leadout in the last tracknumber
          tocentry.cdte_track=CDROM_LEADOUT;
          ioctl(cdrom,CDROMREADTOCENTRY,&tocentry);
          cdtoc[trackcount].min=(int) tocentry.cdte_addr.msf.minute;
          cdtoc[trackcount].sec=(int) tocentry.cdte_addr.msf.second;
          cdtoc[trackcount].frame=(int) tocentry.cdte_addr.msf.frame;
          cdtoc[trackcount].mode=(int) tocentry.cdte_ctrl;//mode 0=audio,mode 4=data
          cdtoc[trackcount].frameoffset=(cdtoc[trackcount].min*60+cdtoc[trackcount].sec)*75+cdtoc[trackcount].frame-150;
        }
    }
  if(discreadok)
    {
      discid=QString::number(calcdiscid(trackcount),16);
    }
  //If we where able to read cdrom, give it back to system
  if (cdrom)
    close(cdrom);
  //only take the 8 right digits
  discid=discid.right(8);
  cddbquery=QString("cddb query %1 %2").arg(discid,QString::number(trackcount));
  int counter=0;
  while (counter<=trackcount-1)
    {
      cddbquery=QString("%1 %2")
                .arg(cddbquery,QString::number(cdtoc[counter].frameoffset));
      counter++;
    }
  int discseconds=(cdtoc[trackcount].frameoffset-cdtoc[0].frameoffset)/75;
  cddbquery=QString("%1 %2").arg(cddbquery,QString::number(discseconds));
}

unsigned long cdrominfo::calcdiscid(int tracks)
{
  int t=0,n=0;
  for (int i=0;i<tracks;i++)
    {
      int temp=0;
      temp=(cdtoc[i].min*60)+cdtoc[i].sec;
      int calc=0;
      while (temp>0)
        {
          calc+=(temp%10);
          temp=temp/10;
        }
      n=n+calc;
    }
  t=((cdtoc[tracks].min*60)+cdtoc[tracks].sec)-((cdtoc[0].min*60)+cdtoc[0].sec);
  return ((n%0xff) << 24|t << 8|tracks);
}
