bool IncidenceConverter::convertFromCalendarItem(ngwt__CalendarItem *item,
        KCal::Incidence *incidence)
{
    incidence->setCustomProperty("GWRESOURCE", "UID",
                                 stringToQString(item->id));

    if(item->subject && !item->subject->empty())
        incidence->setSummary(stringToQString(item->subject));

    kdDebug() << "SUMMARY: " << incidence->summary() << endl;

    if(item->created)
    {
        kdDebug() << "item created at " << item->created << endl;
        incidence->setCreated(charToQDateTime(item->created, mTimezone));
    }
    if(item->modified != 0)
    {
        kdDebug() << "item modified at " << item->created << endl;
        incidence->setLastModified(charToQDateTime(item->modified, mTimezone));
    }

    getItemDescription(item, incidence);
    getAttendees(item, incidence);

    if(item->recurrenceKey)
        incidence->setCustomProperty("GWRESOURCE", "RECURRENCEKEY", QString::number(*item->recurrenceKey));

    /*
      // This must just be a very early cut at recurrence
      if ( item->rdate && item->rdate->date ) {
        std::vector<xsd__date>* dateList = item->rdate->date;

        std::vector<xsd__date>::const_iterator it;
        for ( it = dateList->begin(); it != dateList->end(); ++it ) {
          QDate date = QDate::fromString( s2q( *it ), Qt::ISODate );
          if ( date.isValid() )
        }
      }
    */
    /*
        bool*                                isRecurring                    0;
        std::string*                         iCalId                         0;
    */

    return true;
}
KCal::Event* IncidenceConverter::convertFromAppointment( ngwt__Appointment* appointment )
{
  kDebug() <<"IncidenceConverter::convertFromAppointment()";
  if ( !appointment )
    return 0;

  KCal::Event *event = new KCal::Event();

  if ( !convertFromCalendarItem( appointment, event ) ) {
    delete event;
    return 0;
  }

  if ( appointment->allDayEvent && (*appointment->allDayEvent) )
  {
    event->setAllDay( true );

    if ( appointment->startDay != 0 )
      event->setDtStart( stringToKDateTime( appointment->startDay ).addDays( 1 ) );

    if ( appointment->endDay != 0 )
      //TODO: Use KDateTime::fromString()?
      event->setDtEnd( stringToKDateTime( appointment->endDay) );
    kDebug() <<" all day event.";
  }
  else
  {
    event->setAllDay( false );

    if ( appointment->startDate != 0 ) {
      event->setDtStart( charToKDateTime( appointment->startDate, mTimeSpec ) );
    }

    if ( appointment->endDate != 0 ) {
      event->setDtEnd( charToKDateTime( appointment->endDate, mTimeSpec ) );
    }
  }

  kDebug() <<"start date:" << event->dtStart();
  kDebug() <<"end date:" << event->dtEnd();

  if ( appointment->alarm ) {
    KCal::Alarm *alarm = event->newAlarm();
    alarm->setStartOffset( appointment->alarm->__item * -1 );
    alarm->setEnabled( appointment->alarm->enabled );
  }

  if ( appointment->place )
    event->setLocation( stringToQString( appointment->place ) );

  if ( appointment->acceptLevel ) {
    if ( *appointment->acceptLevel == Tentative )
      event->setTransparency( KCal::Event::Transparent );
    else
      event->setTransparency( KCal::Event::Opaque );
  }

  return event;
}
void IncidenceConverter::getAttendees(ngwt__CalendarItem *item, KCal::Incidence *incidence)
{
    kdDebug() << "IncidenceConverter::getAttendees()" << (item->subject ? item->subject->c_str() : "no subject")
              << endl;

    if(item->distribution && item->distribution->from)
    {
        kdDebug() << "-- from" << endl;
        KCal::Person organizer(stringToQString(item->distribution->from->displayName),
                               stringToQString(item->distribution->from->email));
        incidence->setOrganizer(organizer);
    }

    if(item->distribution && item->distribution->recipients)
    {
        kdDebug() << "-- recipients" << endl;
        std::vector<ngwt__Recipient *> recipients = item->distribution->recipients->recipient;
        std::vector<ngwt__Recipient *>::const_iterator it;

        for(it = recipients.begin(); it != recipients.end(); ++it)
        {
            ngwt__Recipient *recipient = *it;
            kdDebug() << "---- recipient " << recipient->email->c_str() << endl;
            KCal::Attendee *attendee = new KCal::Attendee(
                stringToQString(recipient->displayName),
                stringToQString(recipient->email));

            // set our status
            if(emailsMatch(stringToQString(recipient->email), mFromEmail))
                if(item->status->accepted)
                    attendee->setStatus((*item->status->accepted) ? KCal::Attendee::Accepted : KCal::Attendee::NeedsAction);
                else
                    kdDebug() << "---- found ourselves, but not accepted" << endl;
            else
                kdDebug() << "---- '" <<  "' != '" << (qStringToString(mFromEmail))->c_str() << "'" << endl;

            incidence->addAttendee(attendee);
        }
    }
}
KCal::Todo *IncidenceConverter::convertFromTask(ngwt__Task *task)
{
    if(!task)
        return 0;

    KCal::Todo *todo = new KCal::Todo();

    if(!convertFromCalendarItem(task, todo))
    {
        delete todo;
        return 0;
    }

    if(task->startDate)
    {
        todo->setHasStartDate(true);
        todo->setDtStart(stringToQDateTime(task->startDate));
    }

    if(task->dueDate)
    {
        todo->setHasDueDate(true);
        todo->setDtDue(stringToQDateTime(task->dueDate));
    }

    if(task->taskPriority)
    {
        QString priority = stringToQString(task->taskPriority);

        // FIXME: Store priority string somewhere

        int p = priority.toInt();
        if(p == 0) p = 3;

        todo->setPriority(p);
    }

    if(task->completed)
        todo->setCompleted(*task->completed);

    todo->setLocation(i18n("Novell GroupWise does not support locations for to-dos."));
    return todo;
}
void IncidenceConverter::getItemDescription( ngwt__CalendarItem *item, KCal::Incidence *incidence )
{
  if ( item->message ) {

    std::vector<ngwt__MessagePart*> parts = item->message->part;
    std::vector<ngwt__MessagePart*>::const_iterator it = parts.begin();

    for ( ; it != parts.end(); ++it ) {
      xsd__base64Binary data = (*it)->__item;

      // text/plain should be the description
      if ( stringToQString( (*it)->contentType ) == "text/plain" ) {
        QString description = QString::fromUtf8( (char*)data.__ptr, data.__size );
        incidence->setDescription( description );
        kDebug() <<"Incidence description decodes to:" << description;
        return;
      }
    }
  }
}