/***************************************************************************
                          mimeapplication.cpp -  description
                             -------------------
    begin                : Thu Nov 23 2004
    copyright            : (C) 2003 by Mike K. Bennett
                           (C) 2004 by Diederik van der Boor
    email                : vdboor --at-- codingdomain.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 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "mimeapplication.h"
#include "../mimemessage.h"

#include <klocale.h>
#include <kdebug.h>

// Constructor
MimeApplication::MimeApplication(const QString &localIP)
  : Application(localIP)
{
}



// Destructor
MimeApplication::~MimeApplication()
{
}



// Generate a random session ID
QString MimeApplication::generateSessionId() const
{
  // The official client only changes the session ID if you quit the application.
  QString sessionId = "{6672F94C-45BF-11D7-B4AE-00010A1008DF}";

#ifdef KMESSDEBUG_MIMEAPPLICATION
  kdDebug() << "MimeApplication - Generated session ID " << sessionId << "." << endl;
#endif

  return sessionId;
}



// Return the session ID, generating one if it doesn't exist
const QString& MimeApplication::getSessionId()
{
  if ( sessionId_.isEmpty() )
  {
    sessionId_ = generateSessionId();
  }
  return sessionId_;
}



// A message for the application was received
void MimeApplication::gotMessage(const MimeMessage& message)
{
#ifdef KMESSDEBUG_MIMEAPPLICATION
  kdDebug() << "MimeApplication: An application message was received" << endl;
#endif

  QString invitationCommand = message.getValue("Invitation-Command");

  if(invitationCommand == "INVITE")
  {
    // This is the start of a contact-started app.  Get the app's cookie
    QString cookie = message.getValue("Invitation-Cookie");
    startByInvite(cookie);
    contactStarted1_ContactInvitesUser(message);
  }
  else if(invitationCommand == "ACCEPT")
  {
    // Call the next step of the process, depending on who started the app
    if(isUserStartedApp())
    {
      userStarted2_ContactAccepts(message); // Usually to send an ACCEPT message back.
      userStarted3_UserPrepares();          // Finally, start the application
    }
    else
    {
      contactStarted3_ContactConfirmsAccept(message);
    }
  }
  else if(invitationCommand == "CANCEL")
  {
    // The contact canceled the app.
    QString cancelCode = message.getValue("Cancel-Code");

    if(cancelCode == "REJECT" )
    {
      // Used to "cancel" the invitation
      contactRejected();
    }
    else if(cancelCode == "REJECT_NOT_INSTALLED")
    {
      // Used if the application type is not supported
      contactRejected( i18n("The invitation was rejected.  It's not supported by the other client.") );
    }
    else if(cancelCode == "CANCEL")
    {
      // Used to end the session prematurely
      contactAborted();
    }
    else if(cancelCode == "FAIL")
    {
      // The receiving client does not know any of the specified Session-protocols
      contactAborted( i18n("The invitation was aborted.  An internal error occured.") );
    }
    else if(cancelCode == "TIMEOUT")
    {
      // The client sending an INVITE has got bored of waiting for your ACCEPT
      // (or the principal cancelled the request)
      contactAborted( i18n("The invitation was aborted.  Timeout while waiting for user to accept.") );
    }
    else if(cancelCode == "FTTIMEOUT")
    {
      // There was an error transferring the file itself
      contactAborted( i18n("The invitation was aborted.  Timeout while waiting for file data.") );
    }
    else if(cancelCode == "OUTBANDCANCEL")
    {
      // The switchboard window in which the INVITE message was sent is closing
      contactAborted( i18n("The invitation was aborted.  The switchboard closed the chat connection.") );
    }
    else
    {
      // Fallback
      kdDebug() << "MimeApplication got unhandled Cancel-Code " << cancelCode << "." << endl;
      contactAborted( i18n("The invitation was aborted.") );
    }
  }
  else
  {
    kdDebug() << "MimeApplication got unhandled Invitation-Command " << invitationCommand << ".";
  }
}



// Send a message to the contact
void MimeApplication::sendMessage(const MimeMessage& message)
{
  MimeMessage mainMessage;
  mainMessage.addField("MIME-Version", "1.0");
  mainMessage.addField("Content-Type", "text/x-msmsgsinvite; charset=UTF-8");
  mainMessage.setBody( message.getFields() );

  emit putMsg( mainMessage );
}



// Send a cancel message
void MimeApplication::sendCancelMessage(const ApplicationCancelReason cancelReason)
{
  MimeMessage message;
  QString cancelCode;

  if(cancelReason == CANCEL_INVITATION)
  {
    cancelCode = "REJECT";
  }
  else if(cancelReason == CANCEL_NOT_INSTALLED)
  {
    cancelCode = "REJECT_NOT_INSTALLED";
  }
  else if(cancelReason == CANCEL_SESSION)
  {
    cancelCode = "CANCEL";
  }
  else if(cancelReason == CANCEL_TIMEOUT)
  {
    cancelCode = "TIMEOUT"; // TODO: what about "FTTIMEOUT"?
  }
  else if(cancelReason == CANCEL_FAILED)
  {
    cancelCode = "FAIL";
  }
  else
  {
#ifdef KMESSDEBUG_MIMEAPPLICATION
      kdDebug() << "MimeApplication: WARNING - unknown cancelReason used." << endl;
#endif
      cancelCode = "CANCEL";
  }

  message.addField( "Invitation-Command", "CANCEL"    );
  message.addField( "Invitation-Cookie",  getCookie() );
  message.addField( "Cancel-Code",        cancelCode  );

  sendMessage( message );
}


#include "mimeapplication.moc"
