#include "ebay.h"

#include <klineedit.h>
#include <kiconloader.h>
#include <kapplication.h>
#include <kfiledialog.h>
#include <kglobal.h>
#include <ktoolinvocation.h>
#include <kstandardguiitem.h>

eBay::eBay(QWidget* parent) : QObject(parent)
{
  m_parent = parent;
  
  m_eBayEndpointUrl = QUrl("https://api.ebay.com/ws/api.dll");
  //m_eBayEndpointUrl = QUrl("https://api.sandbox.ebay.com/ws/api.dll");
  //m_eBayEndpointUrl = QUrl("http://localhost/headers.php");

  m_authToken = "";
  m_ruName = "none-none3b3a4-2d52--llnqnis";
  m_devName = "6a686154-c994-481a-9819-3201d0b6f070";
  m_appName = "none3b3a4-2d52-4150-be74-316e1d04e82";
  m_certName = "aff8eb9c-c561-4329-8d51-efaa930eb1bc";
  m_apiVersion = "629";
  m_siteId = "0";
  m_sessionId = "";

  pictureCache.setMaxCost(1000);
}

bool eBay::createDomDocument(QDomDocument &document, const QByteArray &data)
{
  QString errorMessage;
  int errorLine, errorColumn;
  if(!document.setContent(data, &errorMessage, &errorLine, &errorColumn))
  {
    KMessageBox::error(m_parent, i18n("There was an error parsing eBay's XML Response: Line %1, Column %2: %3\n\n%4", QString::number(errorLine), QString::number(errorColumn), errorMessage, QString(data)), i18n("XML Response Error"));
    return false;
  }
  
  if(
    document.elementsByTagName("Ack").length() != 1
    ||
    document.elementsByTagName("Ack").item(0).toElement().text() != "Success"
    )
  {
    KMessageBox::error(m_parent, i18n("The response's ack-tag is not present or did not indicate success.") + "\n\n" + document.elementsByTagName("LongMessage").item(0).toElement().text(), i18n("XML Response Error"));
    return false;
  }
  return true;
}

void eBay::setSiteId(const int &siteId)
{
  m_siteId = QString::number(siteId);
  qDebug() << __FILE__ << __FUNCTION__ << "siteId set to" << siteId;
}

QString eBay::authToken(void) const
{
  return m_authToken;
}

void eBay::setAuthToken(const QString &authToken)
{
  m_authToken = authToken;
  emit logMessage(i18n("setting authentication token."));
  emit authTokenChanged(m_authToken);
}


void eBay::slotReceivedItemPicture(KJob *job)
{
  QByteArray data = getJobData(job);
  
  if(m_imageRetrievalJobsToAuctions.contains((KIO::TransferJob*)job))
  {
    Auction* auction = m_imageRetrievalJobsToAuctions.take((KIO::TransferJob*)job);
    
    if(data.length() == 0)
    {
      qWarning("retrieved 0 bytes for picture of auction %s", qPrintable(auction->title()));
      return;
    }
    
    QPixmap* pixmap = new QPixmap();
    pixmap->loadFromData(data);
    pictureCache.insert(auction->itemId(), pixmap);
    auction->setPixmap(*pixmap);
    
//     qDebug() << __FILE__ << __FUNCTION__ << "image for" << auction->itemId() << "arrived, caching. Now" << m_imageRetrievalJobsToAuctions.size() << "more images pending.";
    
    if(m_imageRetrievalJobsToAuctions.size() == 0)
    {
      qDebug() << __FILE__ << __FUNCTION__ << "no more image retrieval jobs pending, emitting" << m_receivedAuctions.size() << "auctions.";
      emit receivedWatchList(m_receivedAuctions);
      m_receivedAuctions.clear();
    }
  }
  else
  {
//     qDebug() << __FILE__ << __FUNCTION__ << "received pic for an item thats not in m_imageRetrievalJobsToAuctions anymore. Thats wrong, this job should've been killed!";
  }
}


QByteArray eBay::getJobData(KJob *job)
{
  if(job->error() == 0)
  {
    // Retrieve the collected data, copy it for local use and then delete the original.
    if(m_jobsToBuffers.contains((KIO::TransferJob*)job))
    {
      QByteArray *collectedData = m_jobsToBuffers.take((KIO::TransferJob*)job);
      QByteArray data(*collectedData);
      delete collectedData;
      return data;
    }
    else
      return QByteArray();
  }
  else
  {
    KMessageBox::error(m_parent, i18n("There was an error communicating with the eBay servers: %1", job->errorString()), i18n("HTTP Communication Error"));
    QByteArray *collectedData = m_jobsToBuffers.take((KIO::TransferJob*)job);
    delete collectedData;
    return QByteArray();
  }
}

void eBay::addRequestHeaders(KIO::TransferJob *job, const QString &callName)
{
  QString headers(
  QString("X-EBAY-API-COMPATIBILITY-LEVEL: ") + m_apiVersion
  + ("\r\n")
  + QString("X-EBAY-API-DEV-NAME: ") + m_devName
  + ("\r\n")
  + QString("X-EBAY-API-APP-NAME: ") + m_appName
  + ("\r\n")
  + QString("X-EBAY-API-CERT-NAME: ") + m_certName
  + ("\r\n")
  + QString("X-EBAY-API-CALL-NAME: ") + callName
  + ("\r\n")
  + QString("X-EBAY-API-SITEID: ") + m_siteId
  + ("\r\n")
  + QString("Content-Type: text/xml"));

  job->addMetaData("customHTTPHeader", headers);
  //job->addMetaData("content-type:", "text/xml");

//   qDebug() << "eBay::addRequestHeaders()" << endl << headers << endl;

}

void eBay::slotReceivedData(KIO::Job *job, const QByteArray &data)
{
//   qDebug() << "eBay::slotReceivedData(): incoming bytes:" << data.length() << ": " << data;
  if(m_jobsToBuffers.contains((KIO::TransferJob*)job))
    m_jobsToBuffers.value((KIO::TransferJob*)job)->append(data);
  else
    qDebug() << "eBay::slotReceivedData(): couldn't find bytearray for this job!";
}










void eBay::slotSendRevokeToken()
{
  if(KMessageBox::Yes == KMessageBox::questionYesNo(m_parent, i18n("Are you sure you want to revoke the saved eBay authentication token?"), i18n("Reset token")))
  {
    emit logMessage("revoking token.");
  
    QString requestString("\
    <?xml version=\"1.0\" encoding=\"utf-8\"?>\
    <RevokeTokenRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
    <RequesterCredentials>\
    <DevId>" + m_devName  + "</DevId>\
    <AppId>" + m_appName + "</AppId>\
    <AuthCert>" + m_certName + "</AuthCert>\
    <eBayAuthToken>" + m_authToken + "</eBayAuthToken>\
    </RequesterCredentials>\
    </RevokeTokenRequest>\
    ");
  
    qDebug() << "eBay::slotSendRevokeToken()";
    qDebug() << requestString;
  
    KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
    addRequestHeaders(job, "RevokeToken");
    connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
    connect((KIO::Job*)job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedRevokeToken(KJob *)));
    m_jobsToBuffers.insert(job, new QByteArray());
  }
}

void eBay::slotReceivedRevokeToken(KJob *job)
{
  QByteArray data = getJobData(job);

  qDebug() << "eBay::slotReceivedRevokeToken()" << data.length();
  qDebug() << *data;
  
  QDomDocument doc;
  if(!createDomDocument(doc, data))
  {
    KMessageBox::error(m_parent, i18n("Unable to revoke eBay authentication token."), i18n("XML Response Error"));
  }
  else
  {
    emit logMessage("successfully revoked token.");
    m_authToken = "";
    emit authTokenChanged(m_authToken);
  }
}














void eBay::slotSendGetSessionID()
{
  emit logMessage("initiating token generation.");
  emit logMessage("requesting session id.");

  QString requestString("\
  <?xml version=\"1.0\" encoding=\"utf-8\"?>\
  <GetSessionIDRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
  <RequesterCredentials>\
  <DevId>" + m_devName  + "</DevId>\
  <AppId>" + m_appName + "</AppId>\
  <AuthCert>" + m_certName + "</AuthCert>\
  </RequesterCredentials>\
  <RuName>" + m_ruName + "</RuName>\
  </GetSessionIDRequest>\
  ");
  
  qDebug() << "eBay::slotSendGetSessionID()";
  qDebug() << requestString;

  KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
  addRequestHeaders(job, "GetSessionID");
  connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
  connect((KIO::Job*)job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedGetSessionID(KJob *)));
  m_jobsToBuffers.insert(job, new QByteArray());
}

void eBay::slotReceivedGetSessionID(KJob *job)
{
  QByteArray data = getJobData(job);
  
  qDebug() << "eBay::slotReceivedGetSessionID()" << data.length();
  qDebug() << *data;
  
  QDomDocument doc;
  if(!createDomDocument(doc, data))
  {
    emit logMessage("retrieving session id failed.");
    return;
  }

  // childList contains success, message
  QDomElement sessionIdElement = doc.elementsByTagName("SessionID").item(0).toElement();
  if(sessionIdElement.isNull())
  {
    KMessageBox::error(m_parent, i18n("Could not find session ID in response."), i18n("Response Error"));
    emit logMessage("retrieving session id failed.");
    return;
  }
  else
  {
    m_sessionId = sessionIdElement.text();
    emit logMessage("retrieving session id succeeded.");
    emit logMessage("waiting for user to link account to session-id/token.");
    QDesktopServices::openUrl(QUrl("https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&RuName=" + m_ruName + "&SessID=" + m_sessionId, QUrl::StrictMode));
    KMessageBox::information(m_parent, i18n("Please wait for a browser to open eBay's login-page, log in and follow the instructions. Then, press Ok."), i18n("Generating Token"));
    int ret = KMessageBox::questionYesNo(m_parent, i18n("Did you successfully link your account to the generated token?"), i18n("Generating Token"));
    if(ret == KMessageBox::Yes) slotSendFetchToken();
  }
}














void eBay::slotSendFetchToken()
{
  emit logMessage("requesting authentication token.");
  if(m_sessionId.isNull())
  {
    KMessageBox::error(m_parent, QString("Cannot fetch token when sessionID is undefined"), i18n("Internal Error"));
    return;
  }

  QString requestString("\
  <?xml version=\"1.0\" encoding=\"utf-8\"?>\
  <FetchTokenRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
  <SessionID>" + m_sessionId + "</SessionID>\
  </FetchTokenRequest>\
  ");
  
  qDebug() << "eBay::slotSendFetchToken()";
  qDebug() << requestString;
  
  KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
  addRequestHeaders(job, "FetchToken");
  connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
  connect(job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedFetchToken(KJob *)));
  m_jobsToBuffers.insert(job, new QByteArray());
}


void eBay::slotReceivedFetchToken(KJob *job)
{
  QByteArray data = getJobData(job);

  qDebug() << "eBay::slotReceivedFetchToken()" << data.length();
  qDebug() << data;
  
  QDomDocument doc;
  if(!createDomDocument(doc, data))
  {
    emit logMessage("retrieving authentication token failed.");
    return;
  }
  
  QDomElement authTokenElement = doc.elementsByTagName("eBayAuthToken").item(0).toElement();
  if(authTokenElement.isNull())
  {
    KMessageBox::error(m_parent, i18n("Could not find auth token in response."), i18n("Response Error"));
    emit logMessage("retrieving authentication token failed.");
    return;
  }
  else
  {
    m_authToken = authTokenElement.text();
    emit logMessage("retrieving authentication token succeeded.");
    emit authTokenChanged(m_authToken);
  }
}












void eBay::slotSendGetWatchList()
{
  if(m_authToken.isEmpty())
  {
    KMessageBox::information(m_parent, i18n("Please generate an eBay-authentication-token for access to your eBay-Watchlist using the Settings-tab."), i18n("Setup required"));
    return;
  }
  // Used ReturnAll previously, but that seems to also return old items
  QString requestString("\
  <?xml version=\"1.0\" encoding=\"utf-8\"?>\
  <GetMyeBayBuyingRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
  <RequesterCredentials>\
  <eBayAuthToken>" + m_authToken + "</eBayAuthToken>\
  </RequesterCredentials>\
  <DetailLevel>ReturnSummary</DetailLevel>\
  <WatchList>\
  <Sort>EndTime</Sort>\
  <IncludeNotes>false</IncludeNotes>\
  <Pagination>\
  <EntriesPerPage>100</EntriesPerPage>\
  <PageNumber>1</PageNumber>\
  </Pagination>\
  </WatchList>\
  <WarningLevel>Low</WarningLevel>\
  </GetMyeBayBuyingRequest>\
  ");

  qDebug() << "eBay::slotSendGetWatchList()";
  //qDebug() << requestString;

  KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
  addRequestHeaders(job, "GetMyeBayBuying");
  connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
  connect(job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedGetWatchList(KJob *)));
  m_jobsToBuffers.insert(job, new QByteArray());
}

void eBay::slotReceivedGetWatchList(KJob *job)
{
  QByteArray data = getJobData(job);
  // If we couldn't retrieve any data, thats probably because this GetWatchList-job was nuked below
  // caused by incoming data from a previous GetWatchList-job. Thats fine, it means that this previous
  // job has assembled the auctions, but there are still jobs fetching the images.
  if(data.size() == 0) return;
  
  // We might receive a watchlist and then fire off a couple hundred jobs to retrieve their pictures.
  // While that is happening, the user clicks again to update the watchlist again. When asking for
  // the watchlist for the n'th time, we have to make sure to clear the receivedAuctionList which
  // is still filled from the (n-1)'th time and not yet cleared, because not all pics were received
  // yet.
  // The auctions shall not be deleted, the listView in konsume.cpp owns them and takes care of that.
  while (!m_receivedAuctions.isEmpty()) m_receivedAuctions.takeFirst();

  // Trouble is that there might still be pending jobs from receiving pics and other stuff. Just
  // clearing the associations from jobs to their purposes should help, as those jobs won't result
  // in any actions on our part if they can't be found in the maps.
  // We clear the QMaps after retrieving our ReceivedGetWatchList-Job-Data above, otherwise we have
  // no data to operate on.
  // QMap<KIO::TransferJob*, QByteArray*> m_jobsToBuffers;
  // QMap<KIO::TransferJob*, Auction*> m_imageRetrievalJobsToAuctions;
  qDebug() << "eBay::slotReceivedGetWatchList(): number of jobs being deleted in m_jobsToBuffers:" << m_jobsToBuffers.size();
  QMapIterator<KIO::TransferJob*, QByteArray*> i1(m_jobsToBuffers);
  while (i1.hasNext())
  {
    i1.next();
    Q_ASSERT(i1.key()->kill());
    delete i1.value();
  }
  m_jobsToBuffers.clear();

  qDebug() << "eBay::slotReceivedGetWatchList(): number of jobs being deleted in m_imageRetrievalJobsToAuctions:" << m_imageRetrievalJobsToAuctions.size();
  QMapIterator<KIO::TransferJob*, Auction*> i2(m_imageRetrievalJobsToAuctions);
  while (i2.hasNext())
  {
    i2.next();
    Q_ASSERT(i2.key()->kill());
    delete i2.value();
  }
  m_imageRetrievalJobsToAuctions.clear();

  // All QMaps associating jobs are cleared, continue...
  
//   qDebug() << "eBay::slotReceivedGetWatchList()" << data.length();
//   qDebug() << data;

/*
  This is a sample response:
  <GetMyeBayBuyingResponse xmlns="urn:ebay:apis:eBLBaseComponents">
    <Timestamp>2009-07-30T18:25:50.902Z</Timestamp>
    <Ack>Success</Ack>
    <Version>627</Version>
    <Build>E627_CORE_BUNDLED_9778114_R1</Build>
    <BuyingSummary>
      <BiddingCount>0</BiddingCount>
      <WinningCount>0</WinningCount>
      <TotalWinningCost currencyID="USD">0.0</TotalWinningCost>
      <WonCount>0</WonCount>
      <TotalWonCost currencyID="USD">0.0</TotalWonCost>
      <WonDurationInDays>31</WonDurationInDays>
      <BestOfferCount>0</BestOfferCount>
    </BuyingSummary>
    <WatchList>
      <ItemArray>
	<Item>
	<BiddingDetails/>
	<ItemID>400064329217</ItemID>
	<ListingDetails>
	<StartTime>2009-07-28T12:04:05.000Z</StartTime>
	<EndTime>2009-07-28T14:15:31.000Z</EndTime>
	<ViewItemURL>http://cgi.ebay.com.au/ws/eBayISAPI.dll?ViewItem&amp;item=400064329217&amp;category=24071</ViewItemURL>
	<ViewItemURLForNaturalSearch>http://cgi.ebay.com.au/Energie-Marrey-Jeans-Gr-W30-L32-NEU-Wash-H9_W0QQitemZ400064329217QQcategoryZ24071QQcmdZViewItem</ViewItemURLForNaturalSearch>
	</ListingDetails>
	<ListingType>FixedPriceItem</ListingType>
	<Seller>
	<Email>info@trend-marke.de</Email>
	<UserID>trend-marke</UserID>
	</Seller>
	<SellingStatus>
	<ConvertedCurrentPrice currencyID="AUD">135.5</ConvertedCurrentPrice>
	<CurrentPrice currencyID="EUR">79.95</CurrentPrice>
	</SellingStatus>
	<ShippingDetails>
	<ShippingServiceOptions>
	<ShippingServiceCost currencyID="EUR">0.0</ShippingServiceCost>
	</ShippingServiceOptions>
	</ShippingDetails>
	<Site>Germany</Site>
	<Title>Energie Marrey Jeans Gr. W30 L32 NEU Wash H9</Title>
	<PictureDetails>
	<GalleryURL>http://thumbs.ebaystatic.com/pict/4000643292176464_1.jpg</GalleryURL>
	</PictureDetails>
	</Item>
      </ItemArray>
      <PaginationResult>
        <TotalNumberOfPages>1</TotalNumberOfPages>
	<TotalNumberOfEntries>2</TotalNumberOfEntries>
      </PaginationResult>
    </WatchList>
  </GetMyeBayBuyingResponse>
*/

  QDomDocument doc;
  if(!createDomDocument(doc, data)) return;

  // Fetch time offset using Timestamp in the XML response
  QDomElement timeElement = doc.elementsByTagName("Timestamp").item(0).toElement();
  int timeOffseteBayToLocal = 0;
  if(timeElement.isNull())
  {
    KMessageBox::error(m_parent, i18n("XML Response Error"), i18n("Could not find timestamp in response."));
    return;
  }
  else
  {
    timeOffseteBayToLocal = QDateTime::fromString(timeElement.text(), "yyyy-MM-ddTHH:mm:ss.zzzZ").secsTo(QDateTime::currentDateTime());
  }

  QDomNodeList itemList = doc.elementsByTagName("Item");

  for(int i=0; i < itemList.size(); i++)
  {
    QDomNode currentNode = itemList.at(i);
    if(currentNode.isElement())
    {
      Auction *auction = new Auction(m_parent, timeOffseteBayToLocal);

      for(QDomNode n = itemList.at(i).firstChild(); !n.isNull(); n = n.nextSibling())
      {
	QDomElement e = n.toElement();
	if(!e.isNull())
	{
	  if(e.tagName() == "Title") auction->setTitle(e.text());
	  if(e.tagName() == "ItemID") auction->setItemId(e.text());
	  
	  if(e.tagName() == "ListingDetails")
	  {
	    for(QDomNode o = e.firstChild(); !o.isNull(); o = o.nextSibling())
	    {
	      QDomElement c = o.toElement();
	      if(!c.isNull())
		if(c.tagName() == "ViewItemURL")
		  auction->setUrl(QUrl(c.text()));
	    }
	  }

	  if(e.tagName() == "SellingStatus")
	  {
	    for(QDomNode o = e.firstChild(); !o.isNull(); o = o.nextSibling())
	    {
	      QDomElement c = o.toElement();
	      if(!c.isNull())
		if(c.tagName() == "CurrentPrice")
		{
		  auction->setPriceCurrent(c.text());
		  auction->setCurrency(c.attribute("currencyID", "UNKNOWN"));
		}
		if(c.tagName() == "BidCount")
		{
		  auction->setBidCount(c.text().toInt());
		}
	    }
	  }
	  
	  if(e.tagName() == "BuyItNowPrice") auction->setPriceBuyNow(e.text());
	  if(e.tagName() == "ListingDetails")
	  {
	    for(QDomNode o = e.firstChild(); !o.isNull(); o = o.nextSibling())
	    {
	      QDomElement c = o.toElement();
	      if(!c.isNull())
		if(c.tagName() == "EndTime")
		  auction->setEnd(QDateTime::fromString(c.text(), "yyyy-MM-ddTHH:mm:ss.zzzZ"));
	    }
	  }

	  if(e.tagName() == "PictureDetails")
	  {
	    for(QDomNode o = e.firstChild(); !o.isNull(); o = o.nextSibling())
	    {
	      QDomElement c = o.toElement();
	      if(!c.isNull())
		if(c.tagName() == "GalleryURL")
		{
		  // Fetch the item's picture!
		  if(pictureCache.contains(auction->itemId()))
		  {
		    qDebug() << __FILE__ << __FUNCTION__ << "image for" << auction->itemId() << "cached, reusing.";
		    auction->setPixmap(*(pictureCache.object(auction->itemId())));
		  }
		  else
		  {
		    qDebug() << __FILE__ << __FUNCTION__ << "image for" << auction->itemId() << "not cached, downloading.";
		    KIO::TransferJob *job = KIO::get(KUrl(c.text()), KIO::NoReload, KIO::HideProgressInfo);
		    connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
		    connect(job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedItemPicture(KJob *)));
		    m_jobsToBuffers.insert(job, new QByteArray());
		    m_imageRetrievalJobsToAuctions.insert(job, auction);
		  }
		}
	    }
	  }
	}
      }
      qDebug() << __FILE__ << __FUNCTION__ << "appending new auction to list" << auction->itemId();
      m_receivedAuctions.append(auction);
    }
    else
    {
      KMessageBox::error(m_parent, i18n("The current Item is not an XML-Element."), i18n("Response Error"));
      return;
    }
  }

  // After assembling all auctions, there might be no jobs for image fetching because they were all present in the cache.
  // If so, emit the list now.
  if(m_imageRetrievalJobsToAuctions.size() == 0)
  {
    qDebug() << __FILE__ << __FUNCTION__ << "all auctions arrived, no image retrieval necessary, emitting" << m_receivedAuctions.size() << "auctions.";
    emit receivedWatchList(m_receivedAuctions);
  }
}







void eBay::slotSendRemoveFromWatchList(const QString &itemId)
{
  qDebug() << __FILE__ << __FUNCTION__;
  
  QString requestString("\
    <?xml version=\"1.0\" encoding=\"utf-8\"?>\
    <RemoveFromWatchListRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
    <RequesterCredentials>\
    <eBayAuthToken>" + m_authToken + "</eBayAuthToken>\
    </RequesterCredentials>\
    <ItemID>" + itemId + "</ItemID>\
    </RemoveFromWatchListRequest>\
  ");

  qDebug() << requestString;
  
  KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
  addRequestHeaders(job, "RemoveFromWatchList");
  connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
  connect(job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedRemoveFromWatchList(KJob *)));
  m_jobsToBuffers.insert(job, new QByteArray());
}

void eBay::slotReceivedRemoveFromWatchList(KJob *job)
{
  qDebug() << __FILE__ << __FUNCTION__;

  QByteArray data = getJobData(job);

  qDebug() << data;
  
  QDomDocument doc;

  if(!createDomDocument(doc, data))
    KMessageBox::error(m_parent, i18n("Could not confirm item deletion from watchlist"), i18n("Response Error"));
}










































/*
void eBay::slotSendGetOfficialTime()
{
  qDebug() << "eBay::slotSendGetOfficialTime()";
  
  if(m_authToken.isEmpty()) return;

  QString requestString("\
    <?xml version=\"1.0\" encoding=\"utf-8\"?>\
    <GeteBayOfficialTimeRequest xmlns=\"urn:ebay:apis:eBLBaseComponents\">\
      <RequesterCredentials>\
        <eBayAuthToken>" + m_authToken + "</eBayAuthToken>\
      </RequesterCredentials>\
    </GeteBayOfficialTimeRequest>\
  ");

  qDebug() << requestString;

  KIO::TransferJob *job = KIO::http_post(m_eBayEndpointUrl, requestString.toUtf8(), KIO::HideProgressInfo);
  addRequestHeaders(job, "GeteBayOfficialTime");
  connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(slotReceivedData(KIO::Job *, const QByteArray &)));
  connect(job, SIGNAL(result(KJob *)), this, SLOT(slotReceivedGetOfficialTime(KJob *)));
  m_jobsToBuffers.insert(job, new QByteArray());
}

void eBay::slotReceivedGetOfficialTime(KJob *job)
{
  QByteArray data = getJobData(job);

  qDebug() << "eBay::slotReceivedGetOfficialTime()";
  qDebug() << data;

  // sample response:
  //<?xml version="1.0" encoding="UTF-8"?>
  //<GeteBayOfficialTimeResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  //  <Timestamp>2009-08-04T23:35:52.344Z</Timestamp>
  //  <Ack>Success</Ack>
  //  <Version>627</Version>
  //  <Build>E627_CORE_BUNDLED_9756222_R1</Build>
  //</GeteBayOfficialTimeResponse>
  
  QDomDocument doc;
  if(!createDomDocument(doc, data)) return;
  
  QDomElement timeElement = doc.elementsByTagName("Timestamp").item(0).toElement();
  if(timeElement.isNull())
  {
    KMessageBox::error(m_parent, "Response Error", QString("Could not find timestamp in response."));
    return;
  }
  else
  {
    emit receivedOfficialTime(QDateTime::fromString(timeElement.text(), "yyyy-MM-ddTHH:mm:ss.zzzZ"));
  }
}
*/
