/* 
 *  Copyright (C) 1999-2000 Bernd Gehrmann
 *                          bernd@physik.hu-berlin.de
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the "Artistic License" which comes with this Kit. 
 *
 * 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
 * Artistic License for more details.
 *
 * You should have received a copy of the Artistic License with 
 * this Kit, in the file named "Artistic".  If not, I'll be glad
 * to provide one.
 */


#include <stdlib.h>
#include <stdio.h>
#include <qregexp.h>

#include "misc.h"
#include "site.h"
#include "searchjob.h"


SearchJob::SearchJob(Site *site, const QString &searchtext)
    : TransferJob(KURL(site->makeQueryUrl(searchtext)), 'C',
                       makeArgs(site, searchtext), QByteArray(), false)
{
    m_site = site;
    state = Begin;
    
    connect( this, SIGNAL(data(KIO::Job*, const QByteArray &)),
             this, SLOT(gotData(KIO::Job*, const QByteArray &)) );
}


SearchJob::~SearchJob()
{}

    
QByteArray SearchJob::makeArgs(Site *site, const QString &searchtext)
{
    QByteArray a;
    QDataStream stream(a, IO_WriteOnly);
    KURL url(site->makeQueryUrl(searchtext));
    stream << url.path() << url.query() << Q_INT8(0);
    return a;
}


void SearchJob::gotData(KIO::Job *, const QByteArray &data)
{
  int pos, pos1, pos2;
  m_buf += QCString(data);

  qDebug("got data");
  for (;;) {
    switch (state) {
    case Begin:
      // Rule: The result list starts with resultListStart if given
      //       If it's empty, the result list is assumed to start at the
      //       beginning of the document
      pos = m_site->resultListStart.isEmpty()?
          0 : m_buf.find(m_site->resultListStart);
      if (pos == -1)
	return;
      qDebug("state -> ResultList");
      state = ResultList;
      m_buf.remove(0, pos+m_site->resultListStart.length());
      break;

    case ResultList:
      // Rule: The result item starts with resultItemStart if given
      //       If it's empty, the result item is assumed to start at
      //       the "cursor".
      pos1 = m_site->resultListEnd.isEmpty()?
          -1 : m_buf.find(m_site->resultListEnd);
      pos2 = m_site->resultItemStart.isEmpty()?
          0 : m_buf.find(m_site->resultItemStart);

      if (pos1 == -1 && pos2 == -1) {
	return;
      }

      if ( (pos1 != -1) && (pos2 == -1 || pos1 <= pos2) ) {
	qDebug("state -> End");
	state = End;
	return;
      }

      if (pos2 == -1) {
	return;
      }

      qDebug("state -> ResultItem");
      state = ResultItem;
      m_buf.remove(0, pos2);
      break;

    case ResultItem:
      // Rule: The result item ends with resultItemEnd if given
      //       If it's empty, the result item is assumed to end before
      //       the next resultItemStart (this implies that both
      //       cannot be empty at the same time)
      pos = m_site->resultItemEnd.isEmpty()?
          m_buf.find(m_site->resultItemStart) : m_buf.find(m_site->resultItemEnd);
      if (pos == -1 || pos == 0)
          return;

      qDebug("state -> ResultList");
      state = ResultList;
      qDebug("Parse: %s", m_buf.left(pos).latin1());
      parseItem(m_buf.left(pos));
      m_buf.remove(0, pos+m_site->resultItemEnd.length());
      break;

    default:
      return;
    }
  }
}
