/***************************************************************************
 *   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 "freedbinterface.h"

extern rcdatei settingsfile;

freedbconnect::freedbconnect()
{
    lastquery=new QStringList;
    tracklist=new QStringList;
    userabort=FALSE;
    userchoice=NULL;
    url=new QHttp();
    url->setHost(settingsfile.freedbservername,80);
}

freedbconnect::~freedbconnect()
{
    delete lastquery;
    delete url;
    delete tracklist;
}

void freedbconnect::getservers()
{
    url->setHost("freedb.freedb.org",80);
    QString cddbquery=QString("/~cddb/cddb.cgi/?cmd=sites&hello=%1+localhost+kyamo+%3&proto=6").arg(settingsfile.freedbloginname)
                      .arg(KYAMOVERSION);
    transactionid=url->get
                  (cddbquery);
    connect(url,SIGNAL(done(bool)),SLOT(fetchservers(bool)));
}

void freedbconnect::fetchservers(bool err)
{
    if (!err)
    {
        parselastquery();
        //Sort out all needed stuff, and make a new list with them
        QStringList servers;
        QStringList::Iterator index=lastquery->begin();
        int foundservers=0;
        while(index!=lastquery->end())
        {
            QString buffer=*index;
            if (buffer.contains("http"))
            {
                buffer=buffer.left(buffer.find(" http"));
                foundservers++;
                servers.append(buffer);
            }
            index++;
        }
        if (foundservers)
        {
            userchoice=new choicebox2(&servers,i18n("<center><h3>Select a server, that is close to you.</h3></center>"),"internet.png");
            connect (userchoice,SIGNAL(stringselected(QString)),this,SLOT(serverselected(QString)));
            connect (userchoice,SIGNAL(dialogcancelled()),this,SLOT(freedbcancelled()));
        }
    }
    else
        emit error(i18n("Can't connect to freedb-server"));
}

void freedbconnect::serverselected(QString servername)
{
    if (userchoice)
    {
        delete userchoice;
        userchoice=NULL;
    }
    emit selected(servername);
}

void freedbconnect::freedbcancelled()
{
    emit cancelled();
    if (userchoice)
    {
        delete userchoice;
        userchoice=NULL;
    }
}

void freedbconnect::getcdinfo(QString cddbquery,QString discid)
{
    //first get the right style for our cd,so we get the right results later
    lookupdiscid=discid;
    QString querystring=QString("/~cddb/cddb.cgi/?cmd=%1&hello=%2+localhost+kyamo+%3&proto=6").arg(cddbquery)
                        .arg(settingsfile.freedbloginname)
                        .arg(KYAMOVERSION);
    querystring.replace(' ','+');
    queryOk=FALSE;
    while(!queryOk)
    {
        transactionid=url->get
                      (querystring);
        connect(url,SIGNAL(requestFinished (int, bool)),SLOT(getfinished(int,bool)));
        notfinished=TRUE;
        while (notfinished)
        {
            kapp->processEvents();
        }
        //Answer should start with 200 ,followed by th right style
        parselastquery();
        QString answer=lastquery->first();
        //check if one cd was found (answer starts with 200)
        if (answer.compare("Connection refused"))
        {
            if (answer.startsWith("200"))
            {
                answer.remove("200");
                int position=answer.find(discid);
                answer=answer.left(position);
                //remove all spaces from the answerstring
                answer.remove(" ");
            }
            //check if more cds where found (answer starts with 210)
            else if (answer.startsWith("210"))
            {
                //more results, let user choose wich one he wants
                //use the next Strings in list to make a user choice
                QStringList::Iterator index=lastquery->begin();
                index++;
                bool last=FALSE;
                QStringList choices;
                while(!last&&index!=lastquery->end())
                {
                    QString buffer=*index;
                    if(buffer.startsWith("."))
                    {
                        //we already have every good entry, and need to make dialog now
                        last=TRUE;
                    }
                    else
                        choices.append(buffer);
                    index++;
                }
                //Ask User for the right disc
                userchoice=new choicebox2(&choices,i18n("Available discs"),"cdaudio_unmount.png");
                choicebox *userchoice=new choicebox(&choices,i18n("Available discs"),"cdaudio_unmount.png");
                while(userchoice->selected==QString::null&&!userchoice->abort)
                {
                    kapp->processEvents();
                }
                if (userchoice->abort)
                {
                    queryOk=FALSE;
                    userabort=TRUE;
                    return;
                }
                answer=userchoice->selected;
                answer=answer.left(answer.find(discid)-1);
                delete userchoice;
            }
            else
            {
                queryOk=FALSE;
                return;
            }
            querystring=QString("/~cddb/cddb.cgi/?cmd=cddb+read+%1+%2&hello=%3+localhost+kyamo+"KYAMOVERSION"&proto=6").arg(answer,discid,settingsfile.freedbloginname);
            transactionid=url->get
                          (querystring);
            connect(url,SIGNAL(requestFinished (int, bool)),SLOT(getfinished(int,bool)));
            notfinished=TRUE;
            while (notfinished)
            {
                kapp->processEvents();
            }
            if (queryOk)
            {
                //Got response from freedb,parse the result
                parselastquery();
            }
        }
    }
}

void freedbconnect::discselected(QString discid)
{
    QString querystring;
    querystring=QString("/~cddb/cddb.cgi/?cmd=cddb+read+%1+%2&hello=%3+localhost+kyamo+"KYAMOVERSION"&proto=6").arg(discid,lookupdiscid,settingsfile.freedbloginname);
    transactionid=url->get
                  (querystring);
    connect(url,SIGNAL(done(bool)),SLOT(fetchcd(bool)));
}

void freedbconnect::fetchcd(bool err)
{
    if (!err)
    {
        parselastquery();
    }
    else
        emit error(i18n("Could not fetch the cd-contents from freedb"));
}

void freedbconnect::fetchcdlist(bool err)
{
    if (!err)
    {
        parselastquery();
        QString answer=lastquery->first();
        //check if one cd was found (answer starts with 200)
        if (answer.compare("Connection refused"))
        {
            if (answer.startsWith("200"))
            {
                answer.remove("200");
                int position=answer.find(lookupdiscid);
                answer=answer.left(position);
                //remove all spaces from the answerstring
                answer.remove(" ");
            }
            //check if more cds where found (answer starts with 210)
            else if (answer.startsWith("210"))
            {
                //more results, let user choose wich one he wants
                //use the next Strings in list to make a user choice
                QStringList::Iterator index=lastquery->begin();
                index++;
                bool last=FALSE;
                QStringList choices;
                while(!last&&index!=lastquery->end())
                {
                    QString buffer=*index;
                    if(buffer.startsWith("."))
                    {
                        //we already have every good entry, and need to make dialog now
                        last=TRUE;
                    }
                    else
                        choices.append(buffer);
                    index++;
                }
                //Ask User for the right disc
                choicebox *userchoice=new choicebox(&choices,i18n("Available discs"),"cdaudio_unmount.png");
                while(userchoice->selected==QString::null&&!userchoice->abort)
                {
                    kapp->processEvents();
                }
                if (userchoice->abort)
                {
                    queryOk=FALSE;
                    userabort=TRUE;
                    return;
                }
                answer=userchoice->selected;
                answer=answer.left(answer.find(lookupdiscid)-1);
                delete userchoice;
            }
            else
            {
                queryOk=FALSE;
                return;
            }
            //now get the right disc from freedb
            QString querystring;
            querystring=QString("/~cddb/cddb.cgi/?cmd=cddb+read+%1+%2&hello=%3+localhost+kyamo+"KYAMOVERSION"&proto=6").arg(answer,lookupdiscid,settingsfile.freedbloginname);
            transactionid=url->get
                          (querystring);
            connect(url,SIGNAL(requestFinished (int, bool)),SLOT(getfinished(int,bool)));
            notfinished=TRUE;
            while (notfinished)
            {
                kapp->processEvents();
            }
            if (queryOk)
            {
                //Got response from freedb,parse the result
                parselastquery();
            }
        }
        else
            emit error(i18n("Not allowed to connect to freedb"));
    }
    else
        emit error(i18n("Could not connect ro freedb"));
}

void freedbconnect::getfinished(int id, bool error )
{
    queryOk=FALSE;
    if (transactionid==id)
    {
        if (!error)
        {
            queryOk=TRUE;
        }
        else
            cerr<<url->errorString()<<endl;
        notfinished=FALSE;
    }
}

void freedbconnect::parselastquery()
{
    lastquery->clear();
    QByteArray receiveddata=url->readAll();
    QString buffer;
    for ( uint i = 0; i < receiveddata.count(); i++ )
    {
        char character=receiveddata[(int)i];
        if (character!='\n')
        {
            buffer.append(character);
        }
        else
        {
            if (!buffer.startsWith("#"))//throw away everything starting with #
                buffer=QString::fromUtf8(buffer);
            lastquery->append(buffer);
            buffer="";
        }
    }
    QStringList::Iterator index=lastquery->begin();
    if (QString(*index).startsWith("2"))
    {
        tracklist->clear();
        //got a result from freedb
        while(index!=lastquery->end())
        {
            QString line=QString(*index);
            //search for keywords
            if (line.contains("DTITLE="))
            {
                //get artist and albumname out of line
                line=line.remove("DTITLE=");
                int position=line.find('/');
                artist=QString::fromLocal8Bit(line.left(position));
                album=line.right(line.length()-(position+2));
                //cut off last space
                album=album.left(album.length()-1);
            }
            else if(line.contains("TITLE"))
            {
                int position=line.find("=");
                QString trackname=line.right(line.length()-(position+1));
                //cut off last space
                trackname=trackname.left(trackname.length()-1);
                tracklist->append(trackname);
            }
            else if(line.contains("DYEAR="))
            {
                line=line.remove("DYEAR=");
                bool ok;
                releaseyear=line.toLong(&ok,10);
            }
            else if(line.contains("DGENRE="))
            {
                line=line.remove("DGENRE=");
                genre=line.left(line.length()-1);
            }
            index++;
        }
    }
    else
    {
        queryOk=FALSE;
        //nothing found by freedb
    }
}
