/* ============================================================
 *
 * This file is a part of kipi-plugins project
 * http://www.kipi-plugins.org
 *
 * Date        : 2007-16-07
 * Description : a kipi plugin to export images to Picasa web service
 *
 * Copyright (C) 2007-2008 by Vardhman Jain <vardhman at gmail dot com>
 * Copyright (C) 2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * 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, 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.
 *
 * ============================================================ */

// C++ includes.

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <string>

// TQt includes.

#include <tqcstring.h>
#include <tqtextstream.h>
#include <tqfile.h>
#include <tqfileinfo.h>
#include <tqimage.h>
#include <tqstringlist.h>
#include <tqurl.h>
#include <tqlineedit.h>
#include <tqmessagebox.h>
#include <tqdom.h>

// KDE includes.

#include <tdelocale.h>
#include <tdeio/job.h>
#include <kdebug.h>
#include <kmimetype.h>
#include <kstandarddirs.h>
#include <kmdcodec.h>
#include <tdeapplication.h>
#include <tdemessagebox.h>
#include <tdeio/jobclasses.h>
#include <kurl.h>

// LibKExiv2 includes.

#include <libkexiv2/kexiv2.h>

// LibKDcraw includes.

#include <libkdcraw/version.h>
#include <libkdcraw/kdcraw.h>

#if KDCRAW_VERSION < 0x000106
#include <libkdcraw/dcrawbinary.h>
#endif

// Local includes.

#include "pluginsversion.h"
#include "mpform.h"
#include "picasawebitem.h"
#include "picasawebtalker.h"
#include "picasawebwindow.h"
#include "picasaweblogin.h"
#include "picasawebtalker.moc"

class PicasawebLogin;

namespace KIPIPicasawebExportPlugin
{

PicasawebTalker::PicasawebTalker( TQWidget* parent )
               : m_parent( parent ),  m_job( 0 )
    {
        m_apikey="49d585bafa0758cb5c58ab67198bf632";
        m_secret="34b39925e6273ffd";

        connect(this, TQ_SIGNAL(signalError(const TQString&)),
                this, TQ_SLOT(slotError(const TQString&)));

        authProgressDlg=new TQProgressDialog();
    }

PicasawebTalker::~PicasawebTalker()
{
    if (m_job)
        m_job->kill();
}

TQString PicasawebTalker::getApiSig(TQString secret, TQStringList headers)
{
    TQStringList compressed ;//= new List<string>(headers.Length);

    for ( TQStringList::Iterator it = headers.begin(); it != headers.end(); ++it ) {
        TQStringList str=TQStringList::split("=",(*it));
        compressed.append(str[0].stripWhiteSpace()+str[1].stripWhiteSpace());
    }

    compressed.sort();
    TQString merged=compressed.join("");
    TQString final = secret + merged;
    const char *test=final.ascii();
    KMD5 context (test);
    //kdDebug()<< "Test Hex Digest output: " << context.hexDigest().data() << endl;
    return context.hexDigest().data();
}

void PicasawebTalker::getToken(const TQString& username, const TQString& password )
{
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    TQString url = "https://www.google.com/accounts/ClientLogin";

    PicasawebLogin *loginDialog = new PicasawebLogin(kapp->activeWindow(), TQString("LoginWindow"), username, password);
    /*if (username!=NULL && username.length() > 0){
        //  kdDebug()<<"Showing stored username"<< username << endl;
        loginDialog->setUsername(username);
        if (password != NULL && password.length() > 0){
        //    kdDebug()<<"Showing stored password"<< password << endl;
            loginDialog->setPassword(password);
            //  kdDebug()<<"Showing stored password"<< password << endl;
        }
    }
    */

    TQString username_edit, password_edit;

    if (!loginDialog)
    {
        kdDebug()<<" Out of memory error "<< endl;
    }

    if (loginDialog->exec() == TQDialog::Accepted)
    {
        username_edit = loginDialog->username();
        password_edit = loginDialog->password();
    }
    else 
    {
        //Return something which say authentication needed.
        return ;
    }

    m_username    = username_edit;
    username_edit = username;
    TQString accountType = "GOOGLE";

    if (!(username_edit.endsWith("@gmail.com")))
        username_edit += "@gmail.com";

    TQByteArray buffer;
    TQStringList qsl;
    qsl.append("Email="+username_edit);
    qsl.append("Passwd="+password_edit);
    qsl.append("accountType="+accountType);
    qsl.append("service=lh2");
    qsl.append("source=kipi-picasaweb-client");
    TQString dataParameters = qsl.join("&");

    TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
    ts.setEncoding(TQTextStream::UnicodeUTF8);
    ts << dataParameters;

    TDEIO::TransferJob* job = TDEIO::http_post(url, buffer, false);
    job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );	
    m_state = FE_GETTOKEN;
    authProgressDlg->setLabelText(i18n("Getting the token"));

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy( true );
}

void PicasawebTalker::authenticate(const TQString& token, const TQString& username, const TQString& password)
{
    if (!token || token.length() < 1)
    {
        checkToken(token);
        m_username = username;
        m_password = password; //this would be needed if the checktoken failed
                                //we would need to reauthenticate using auth
    }
    else 
    {
        getToken(username, password);
    }
}

void PicasawebTalker::checkToken(const TQString& /*token*/) 
{
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    TQString    url         = "https://www.google.com/accounts/ClientLogin";
    TQString    auth_string = "GoogleLogin auth=" + m_token;
    TQByteArray tmp;
    TDEIO::TransferJob* job  = TDEIO::http_post(url, tmp, false);
    job->addMetaData("customHTTPHeader", "Authorization: " + auth_string);

    job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded");

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_CHECKTOKEN;
    authProgressDlg->setLabelText(i18n("Checking if previous token is still valid"));
    authProgressDlg->setProgress(1,4);
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy( true );
}

/** PicasaWeb's Album listing request/response
  * First a request is sent to the url below and then we might(?) get a redirect URL
  * WE then need to send the GET request to the Redirect url (this however gets taken care off by the 
  * TDEIO libraries.
  * This uses the authenticated album list fetching to get all the albums included the unlisted-albums
  * which is not returned for an unauthorised request as done without the Authorization header.
*/
void PicasawebTalker::listAllAlbums() {
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    TQString    url = "http://picasaweb.google.com/data/feed/api/user/" + m_username + "?kind=album";
    TQByteArray tmp;	
    TQString auth_string = "GoogleLogin auth=" + m_token;
    TDEIO::TransferJob* job = TDEIO::get(url, !tmp.isNull(), false);
    job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );	
    job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)), 
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_LISTALBUMS;
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy( true );

}

void PicasawebTalker::getPhotoProperty(const TQString& method,const TQString& argList)
{
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    TQString     url="http://www.picasaweb.com/services/rest/?";
    TQStringList headers;
    headers.append("api_key="+ m_apikey);
    headers.append("method="+method);
    headers.append("frob="+ m_frob);
    headers.append(argList);
    TQString md5=getApiSig(m_secret,headers);
    headers.append("api_sig="+ md5);
    TQString queryStr=headers.join("&");
    TQString postUrl=url+queryStr;
    TQByteArray tmp;	
    TDEIO::TransferJob* job = TDEIO::http_post(postUrl, tmp, false);
    job->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded" );	

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)), 
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_GETPHOTOPROPERTY;
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy( true );
    //authProgressDlg->setLabelText("Getting the Token from the server");
    //authProgressDlg->setProgress(3,4);
}

void PicasawebTalker::addPhotoTag(const TQString& photoURI, const TQString& tag)
{ 
    //if (m_job && m_state != FE_ADDTAG){ //we shouldn't kill the old tag request
    //	m_job->kill();
    //	m_job = 0;
    //}

    TQString addTagXML = TQString("<entry xmlns='http://www.w3.org/2005/Atom'> "
                                "<title>%1</title> "
                                "<category scheme='http://schemas.google.com/g/2005#kind' "
                                "term='http://schemas.google.com/photos/2007#tag'/> "
                                "</entry>").arg(tag);
    TQString postUrl = TQString("%1").arg(photoURI);
    TQByteArray buffer;
    TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
    ts.setEncoding(TQTextStream::UnicodeUTF8);
    ts << addTagXML;

    TQString auth_string = "GoogleLogin auth=" + m_token;
    TDEIO::TransferJob* job = TDEIO::http_post(postUrl, buffer, false);
    job->addMetaData("content-type", "Content-Type: application/atom+xml");
    job->addMetaData("content-length", TQString("Content-Length: %1").arg(addTagXML.length()));
    job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );

    //connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
    //        this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_ADDTAG;
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy(true);
}

void PicasawebTalker::listPhotos(const TQString& /*albumName*/)
{
    // TODO
}

void PicasawebTalker::createAlbum(const TQString& albumTitle, const TQString& albumDesc,
                                  const TQString& location, uint  timestamp, const TQString& access,
                                  const TQString& media_keywords, bool isCommentsEnabled)
{
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    TQString newAlbumXML = TQString("<entry xmlns='http://www.w3.org/2005/Atom' "
                                "xmlns:media='http://search.yahoo.com/mrss/' "
                                "xmlns:gphoto='http://schemas.google.com/photos/2007'> "
                                "<title type='text'>%1</title> "
                                "<summary type='text'>%2</summary> "
                                "<gphoto:location>%3</gphoto:location> "
                                "<gphoto:access>%4</gphoto:access> "
                "<gphoto:commentingEnabled>%5</gphoto:commentingEnabled> "
                "<gphoto:timestamp>%6</gphoto:timestamp> "
                "<media:group> "
                "<media:keywords>%7</media:keywords> "
                "</media:group> "
                "<category scheme='http://schemas.google.com/g/2005#kind' "
                        "term='http://schemas.google.com/photos/2007#album'></category> "
                        "</entry> ").arg(albumTitle)
                                    .arg(albumDesc)
                                    .arg(location)
                                    .arg(access)
                                    .arg(isCommentsEnabled==true?"true":"false")
                                    .arg(timestamp)
                                    .arg(media_keywords);

    TQByteArray buffer;
    TQTextStream ts(buffer, IO_Append|IO_WriteOnly);
    ts.setEncoding(TQTextStream::UnicodeUTF8);
    ts << newAlbumXML;

    MPForm form;
    TQString postUrl = "http://www.picasaweb.google.com/data/feed/api/user/" + m_username ;
    TQString auth_string = "GoogleLogin auth=" + m_token;
    TDEIO::TransferJob* job = TDEIO::http_post(postUrl, buffer, false);
    job->addMetaData("content-type", "Content-Type: application/atom+xml");
    job->addMetaData("content-length", TQString("Content-Length: %1").arg(newAlbumXML.length()));
    job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_CREATEALBUM;
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy(true);
}

bool PicasawebTalker::addPhoto(const TQString& photoPath, FPhotoInfo& info,
                               const TQString& albumId, bool rescale,
                               int maxDim, int imageQuality)
{
    // Disabling this totally may be checking the m_state and doing selecting 
    // disabling is a better idea
    /*if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }*/

    TQString album_id = albumId;

    if (album_id.length() == 0)
        album_id = "test";

    TQString     postUrl = "http://www.picasaweb.google.com/data/feed/api/user/" + KURL::encode_string(m_username) + "/albumid/" + album_id;
    TQString     path = postUrl;
    TQStringList headers;
    MPForm      form;
    TQString     auth_string = "GoogleLogin auth=" + m_token;

    //form.addPair("Authorization", auth_string);

    //Create the Body in atom-xml
    TQStringList body_xml;
    body_xml.append("<entry xmlns=\'http://www.w3.org/2005/Atom\'>");
    body_xml.append("<title>"+ info.title +"</title>");
    body_xml.append("<summary>"+ info.description +"</summary>");
    body_xml.append("<category scheme=\"http://schemas.google.com/g/2005#kind\" "
                    "term=\"http://schemas.google.com/photos/2007#photo\" />");
    body_xml.append("</entry>");

    TQString body = body_xml.join("");

    form.addPair("test", body, "application/atom+xml");

    // save the tags for this photo in to the tags hashmap
    tags_map.insert(info.title, info.tags); 
    TQImage image;

    // Check if RAW file.
#if KDCRAW_VERSION < 0x000106
    TQString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles());
#else
    TQString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
#endif
    TQFileInfo fileInfo(photoPath);
    if (rawFilesExt.upper().contains(fileInfo.extension(false).upper()))
        KDcrawIface::KDcraw::loadDcrawPreview(image, photoPath);
    else
        image.load(photoPath);

    if (!image.isNull())
    {
        path = locateLocal("tmp", TQFileInfo(photoPath).baseName().stripWhiteSpace() + ".jpg");

        if (rescale && (image.width() > maxDim || image.height() > maxDim))
            image = image.smoothScale(maxDim, maxDim, TQImage::ScaleMin);

        image.save(path, "JPEG", imageQuality);

        // Restore all metadata.

        KExiv2Iface::KExiv2 exiv2Iface;

        if (exiv2Iface.load(photoPath))
        {
            exiv2Iface.setImageProgramId(TQString("Kipi-plugins"), TQString(kipiplugins_version));
            exiv2Iface.setImageDimensions(image.size());
            exiv2Iface.save(path);
        }
        else
        {
            kdWarning(51000) << "(picasawebExport::Image doesn't have exif data)" << endl;
        }

        kdDebug() << "Resizing and saving to temp file: " << path << endl;
    }

    if (!form.addFile("photo", path))
        return false;

    form.finish();

    TDEIO::TransferJob* job = TDEIO::http_post(postUrl, form.formData(), false);
    job->addMetaData("content-type", form.contentType());	
    job->addMetaData("customHTTPHeader", "Authorization: " + auth_string );

    connect(job, TQ_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
            this, TQ_SLOT(data(TDEIO::Job*, const TQByteArray&)));

    connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
            this, TQ_SLOT(slotResult(TDEIO::Job *)));

    m_state = FE_ADDPHOTO;
    m_job   = job;
    m_buffer.resize(0);
    emit signalBusy(true);
    return true;
}

TQString PicasawebTalker::getUserName()
{
    return m_username;
}

TQString PicasawebTalker::getUserId()
{
    return m_userId;
}

void PicasawebTalker::cancel()
{
    if (m_job)
    {
        m_job->kill();
        m_job = 0;
    }

    if (authProgressDlg && !authProgressDlg->isHidden()) 
        authProgressDlg->hide();
}

void PicasawebTalker::info(TDEIO::Job* /*job*/, const TQString& /*str*/)
{
}

void PicasawebTalker::data(TDEIO::Job*, const TQByteArray& data)
{
    if (data.isEmpty())
        return;

    int oldSize = m_buffer.size();
    m_buffer.resize(m_buffer.size() + data.size());
    TQString output_data = TQString(data);
    memcpy(m_buffer.data()+oldSize, data.data(), data.size());
}

void PicasawebTalker::slotError(const TQString & error)
{
    TQString transError;
    int     errorNo = 0;

    if (!error.isEmpty())
        errorNo = atoi(error.latin1());

    switch (errorNo)
    {
        case 2: 
            transError=i18n("No photo specified");break;
        case 3: 
            transError=i18n("General upload failure");break;
        case 4: 
            transError=i18n("Filesize was zero");break;
        case 5: 
            transError=i18n("Filetype was not recognised");break;
        case 6:
            transError=i18n("User exceeded upload limit");break;
        case 96:
            transError=i18n("Invalid signature"); break;
        case 97:
            transError=i18n("Missing signature"); break;
        case 98:
            transError=i18n("Login Failed / Invalid auth token"); break;
        case 100: 
            transError=i18n("Invalid API Key"); break;
        case 105:
            transError=i18n("Service currently unavailable");break;
        case 108:
            transError=i18n("Invalid Frob");break;
        case 111: 
            transError=i18n("Format \"xxx\" not found"); break;
        case 112: 
            transError=i18n("Method \"xxx\" not found"); break;
        case 114: 
            transError=i18n("Invalid SOAP envelope");break;
        case 115: 
            transError=i18n("Invalid XML-RPC Method Call");break;
        case 116: 
            transError=i18n("The POST method is now required for all setters"); break;
        default:
            transError=i18n("Unknown error");
    };

    KMessageBox::error(kapp->activeWindow(), i18n("Error Occured: %1\n We can not proceed further").arg(transError));
    //kdDebug()<<"Not handling the error now will see it later"<<endl;
}

void PicasawebTalker::slotResult(TDEIO::Job *job)
{
    m_job = 0;
    emit signalBusy(false);

    if (job->error())
    {
        if (m_state == FE_ADDPHOTO)
        {
            emit signalAddPhotoFailed(job->errorString());
        }
        else 
        {
            job->showErrorDialog(m_parent);
        }

        return;
    }

    switch(m_state)
    {
        case(FE_LOGIN):
            //parseResponseLogin(m_buffer);
            break;
        case(FE_CREATEALBUM):
            parseResponseCreateAlbum(m_buffer);
            break;
        case(FE_LISTALBUMS):
            parseResponseListAlbums(m_buffer);
            break;
        case(FE_GETFROB):
            break;
        case(FE_GETTOKEN):
            parseResponseGetToken(m_buffer);
            break;
        case(FE_CHECKTOKEN):
            parseResponseCheckToken(m_buffer);
            break;
        case(FE_GETAUTHORIZED):
            break;
        case(FE_LISTPHOTOS):
            parseResponseListPhotos(m_buffer);
            break;
        case(FE_GETPHOTOPROPERTY):
            parseResponsePhotoProperty(m_buffer);
            break;
        case(FE_ADDPHOTO):
            parseResponseAddPhoto(m_buffer);
            break;
        case(FE_ADDTAG):
            parseResponseAddTag(m_buffer);
            break;
    }
}

void PicasawebTalker::parseResponseCheckToken(const TQByteArray &data)
{
    bool success = false;
    TQString errorString;
    TQString username;
    TQString transReturn(data);
    // If checktoken failed.
    // getToken ...

    if(transReturn.startsWith("Error="))
        success = false;
    else
        success = true;

    if(!success)
        getToken(m_username, m_password);
    //emit signalError(errorString);
}

void PicasawebTalker::parseResponseGetToken(const TQByteArray &data)
{
    bool success = false;
    TQString errorString;
    TQString str(data);
    //Check the response code should it be 200, proceed
    //if it is 403 handle the error mesg
    //figure out the auth string from this response

    if (str.find("Auth="))
    {
        TQStringList strList = TQStringList::split("Auth=", str);
        m_token = strList[1];
        success = 1;
    }

    if(success)
    {
        authProgressDlg->hide();
        emit signalTokenObtained(m_token);
    }
    else
    {
        emit signalError(errorString);
    }

    emit signalBusy(false);
}

void PicasawebTalker::getHTMLResponseCode(const TQString& /*str*/)
{
}

void PicasawebTalker::parseResponseListAlbums(const TQByteArray &data)
{
    bool success = false;
    TQString str(data);
    TQDomDocument doc( "feed" );
    if ( !doc.setContent( data ) ) 
    {
        return;
    }

    TQDomElement docElem = doc.documentElement();
    TQDomNode node = docElem.firstChild();
    TQDomElement e;
    TQString feed_id, feed_updated, feed_title, feed_subtitle;
    TQString feed_icon_url, feed_link_url;
    TQString feed_username, feed_user_uri;

    TQString album_id, album_title, album_description;
    m_albumsList = new TQValueList <PicasaWebAlbum>();

    while(!node.isNull())
    {
        if (node.isElement() && node.nodeName() == "entry")
        {
            success = true;
            e = node.toElement(); 
            TQDomNode details=e.firstChild();
            PicasaWebAlbum fps;
            TQDomNode detailsNode = details;

            while(!detailsNode.isNull())
            {
                if(detailsNode.isElement())
                {
                    if(detailsNode.nodeName() == "id")
                    {
			// The node data is a URL of which album id is the string following the last /
			// like <id>http://www.picasaweb.google.com/.../AlbumID<id>
			TQString albumIdUrl = detailsNode.toElement().text();
                        int index = albumIdUrl.findRev("/");
                        int length = albumIdUrl.length();
                        TQString album_id = albumIdUrl.right(length - index - 1);
                        fps.id = album_id;
                    }

                    if(detailsNode.nodeName() == "title")
                    {
                        album_title = "Not fetched";

                        if(detailsNode.toElement().attribute("type")=="text")
                            album_title = detailsNode.toElement().text();

                        //this is what is obtained from data.
                        fps.title = album_title;
                    }

                    if(detailsNode.nodeName()=="gphoto:name")
                    {
                        TQString name = detailsNode.toElement().text();
                    }
                }

                detailsNode = detailsNode.nextSibling();
            }

            m_albumsList->append(fps);
        }

    node = node.nextSibling();
    }

    if (!success)
    {
        emit signalGetAlbumsListFailed(i18n("Failed to fetch photoSets List"));
        m_albumsList = NULL;
    }
    else
    {
        emit signalGetAlbumsListSucceeded();
    }
}

void PicasawebTalker::parseResponseListPhotos(const TQByteArray &data)
{
    TQDomDocument doc( "getPhotosList" );
    if ( !doc.setContent( data ) ) 
    {
        return;
    }

    TQDomElement docElem = doc.documentElement();
    TQDomNode node = docElem.firstChild();
    //TQDomElement e;
    // TODO
}

void PicasawebTalker::parseResponseCreateAlbum(const TQByteArray &data)
{
    bool success = false;
    TQString errorString;
    TQString response(data);
    TQDomDocument doc( "AddPhoto Response" );
    // parse the new album name
    TQDomElement docElem = doc.documentElement();
    TQString title, photo_id, album_id, photoURI; 
    TQDomNode node = docElem.firstChild(); //this should mean <entry>
    TQDomElement e;

    while( !node.isNull() ) 
    {
        if ( node.isElement()) 
        {
            TQString node_name = node.nodeName();
            TQString node_value = node.toElement().text();
            if(node_name == "title")
            {
                success = true;
                title = node_value;
            }
            else if (node_name == "id")
                photoURI = node_value;
            else if(node_name == "gphoto:id")
                photo_id = node_value;
            else if(node_name == "gphoto:albumid")
                album_id = node_value;
        }

        node = node.nextSibling();
    }

    // Raise a popup informing success
}

void PicasawebTalker::parseResponseAddTag(const TQByteArray &data)
{
    TQString str(data);
    remaining_tags_count -= 1;
    emit signalBusy( false );
    m_buffer.resize(0);

    if (remaining_tags_count == 0)
        emit signalAddPhotoSucceeded();
}

void PicasawebTalker::parseResponseAddPhoto(const TQByteArray &data)
{
    bool success = false;
    TQString     line;
    TQString str(data);
    success = 1;
    TQDomDocument doc( "AddPhoto Response" );

    if ( !doc.setContent( data ) ) 
    {
        return;
    }

    TQDomElement docElem = doc.documentElement();
    TQString title, photo_id, album_id, photoURI; 
    TQDomNode node = docElem.firstChild(); //this should mean <entry>
    TQDomElement e;

    while( !node.isNull() ) 
    {
        if ( node.isElement()) 
        {
            TQString node_name = node.nodeName();
            TQString node_value = node.toElement().text();
            if(node_name == "title")
            {
                success = true;
                title = node_value;
            }
            else if (node_name == "id")
                photoURI = node_value;
            else if(node_name == "gphoto:id")
                photo_id = node_value;
            else if(node_name == "gphoto:albumid")
                album_id = node_value;
        }

        node = node.nextSibling();
    }

    if (!success)
    {
        emit signalAddPhotoFailed(i18n("Failed to upload photo"));
    }
    else
    {
        // Update the tags information from the tags_map
        TQStringList tags = tags_map[title];
        remaining_tags_count = tags.count();

        if (tags.count() == 0)
            emit signalAddPhotoSucceeded();

        for ( TQStringList::Iterator it = tags.begin(); it != tags.end(); ++it ) 
        {
            TQString photoURI= TQString("http://picasaweb.google.com/data/feed/api/user/"
                    "%1/albumid/%2/photoid/%3").arg(m_username).arg(album_id).arg(photo_id);
            addPhotoTag( photoURI, *it);
        }
    }
}

void PicasawebTalker::parseResponsePhotoProperty(const TQByteArray &data)
{
    bool success = false;
    TQString     line;
    TQDomDocument doc( "Photos Properties" );

    if ( !doc.setContent( data ) ) 
    {
        return;
    }

    TQDomElement docElem = doc.documentElement();
    TQDomNode node = docElem.firstChild();
    TQDomElement e;

    while( !node.isNull() ) 
    {
        if ( node.isElement() && node.nodeName() == "photoid" ) 
        {
            e = node.toElement(); // try to convert the node to an element.
            TQDomNode details=e.firstChild();
            success=true;
        }

        if ( node.isElement() && node.nodeName() == "err" ) 
        {
            kdDebug()<<"Checking Error in response"<<endl;
            TQString code=node.toElement().attribute("code");
            kdDebug()<<"Error code="<<code<<endl;
            kdDebug()<<"Msg="<<node.toElement().attribute("msg")<<endl;	
            emit signalError(code);
        }
        node = node.nextSibling();
    }

    kdDebug()<<"GetToken finished"<<endl;
    if (!success)
    {
        emit signalAddPhotoFailed(i18n("Failed to query photo information"));
    }
    else
    {
        //emit signalAddPhotoSucceeded();
    }
}

} // KIPIPicasawebExportPlugin
