/* urlsend.c
 *
 * Wimp function library
 *  Joseph Heenan, 1998.
 *
 * Implements:
 *
 *  + the Acorn URI protocol, as defined in <http://www.acorn.com/browser/uri/funcspec.html>
 *  + the ANT URL protocol, as defined in <http://www.ant.co.uk/support/tech/notes/url.html>
 *
 * NB. Does not support sending URLs over 240ish character using the ANT protocol - this
 *     would require claiming RMA.
 *
 * $Log: urlsend,v $
 * Revision 1.2  1998/09/17 10:19:47  joseph
 * Fixed problems with URIs
 *
 * Revision 1.1  1998/08/13 15:28:59  joseph
 * Added setinfover and url/uri receiving and sending
 *
 *
 */


#include <string.h>
#include <stdlib.h>

#include "swis.h"
#include "wimplib.h"
#include "wimpclib.h"

#include "urldefs.h"


/* url broadcast is 'quite' a long winded process.
 * 1) We first try a URI dispatch, if this fails we jump to the ANT broadcast (4).
 * 2) If the call succeeds, we then waits for the wimp message indicating success or failure.
 * 3) If this indicates failure, we try a:
 * 4) ANT broadcast
 * 5) If the ANT broadcast bounces, we try a ANT URL_open
 * 6) If _that_ fails, we give the user an error message!
 */
#define WORDALIGN(x) ( (x+3) & ~3 )

static int url_antbroadcast( const char *url )
{
  url_message urlblock;

  urlblock.hdr.size = WORDALIGN( sizeof(urlblock.hdr) + strlen( url ) + 1 );
  urlblock.hdr.your_ref = 0;
  urlblock.hdr.action_code = Wimp_MOpenUrl;

  *urlblock.data.url = 0;
  strncat(urlblock.data.url, url, sizeof(urlblock.data.url) - 1);
  E_CHECK_RETURN( -1, wimp_send_message(Wimp_EUserMessageRecorded, &urlblock, 0, 0, NULL) );
  return 0;
}


int url_launch( const char *url )
{
  int taskhan = 0;
  int success = 1;
  int flags;
  if ( _swix( Wimp_ReadSysInfo, _IN(0) | _OUT(0), 5, &taskhan ) )
    success = 0;

  if ( success )
  {
    if ( _swix( URI_Dispatch, _INR(0,2) | _OUT(0), URI_inform_caller, url, taskhan, &flags ) || flags & 1 )
    {
      success = 0;
    }
  }

  if ( !success )
    url_antbroadcast( url );

  return 0;
}


void url_bounce( const WimpMessage *mess )
{
  char buf[ 512 ];
  char *off;
  int han;

  if ( mess->hdr.action_code == URI_MReturnResult )
  {
    uri_returnresultmessage *msg = (uri_returnresultmessage *) mess;

    /* failed AcornURI. Try ANT broadcast */

    if ( (msg->flags & 0x01) == 0 )
      return; /* url was claimed */

    E_CHECK_RETURN( , _swix( URI_RequestURI, _INR(0, 3), 0, buf, sizeof buf, msg->uri_handle ) );

    url_antbroadcast( buf );

    /* we haven't acknowledged the returnresult message, so the URI
     * handler task will automatically free the URI */

    return;
  }
  else if ( mess->hdr.action_code != Wimp_MOpenUrl )
    return;

  /* otherwise, it was an ANT url broadcast that failed - try URLOpen_<scheme> */

  off = strchr( mess->data.bytes, ':');

  /* our url request wasn't answered :-( */
  /* try an Alias$URLOpen, instead */
  if (!off)
    return;  /* no ':' */

  strcpy( buf, "Alias$URLOpen_" );
  strncat( buf, mess->data.bytes, off - mess->data.bytes );
  if ( !getenv( buf ) )
  {
    E_REPORT( "No application has been seen that can launch this URL" );
    return;
  }
  strcat( buf, " " );
  strncat( buf, mess->data.bytes, sizeof(buf) - strlen(buf) - 1 );
  E_CHECK( wimp_start_task( buf + sizeof("Alias$") - 1, &han ) );
}
