#ifndef drwwh_H
 #include "DRW/drwwh.h"
#endif

#include "DRW/drwWwinit.h"
#include "DRW/drwWxdata.h"

#ifndef drwalloc_H
 #include "DRW/drwalloch.h"
#endif

#ifndef drw_url_H
 #include "DRWURL/drwurlh.h"
#endif

#ifndef inetsuite_H
 #include "OSlib/inetsuite.h"
#endif

#ifndef uri_H
 #include "OSlib/uri.h"
#endif

#include "DRW/drwSysvar.h"

#ifndef drwnullIfn_H
 #include "DRW/drwnullIfn.h"
#endif

#ifndef drwuseracn_H
  #include "DRW/drwuseracn.h"
#endif


static byte *drwurldarea = NULL;
static char *drwurlcmd = NULL;
static int drwurlcmdsize = 0;


extern void drw_url_free_data(void *urldataptr)

{

if (urldataptr)
 drw_os_heap_free(drwurldarea, urldataptr);

}


extern void drw_url_release_acorn_fn(void *urldataptr)

{

if (urldataptr)
 {
  drw_release_user_msg_action(message_URI_RETURN_RESULT,
                              &drw_catch_acorn_open_url_msg,
                              urldataptr);
 }

}


extern void drw_url_release_ant_fn(void *urldataptr)

{

if (urldataptr)
 {
  drw_release_user_msg_ack(message_INET_SUITE_OPEN_URL,
                           &drw_catch_rtnd_ant_open_url_msg,
                           urldataptr);

  drw_release_user_action(wimp_NULL_REASON_CODE,
                          (wimp_w) -2,
                          (wimp_i) -1,
                          NULL,
                          0,
                          -1,
                          &drw_url_catch_nulls,
                          urldataptr);
 }

}


extern void drw_start_url_loader(void *actiondata)

{

drw_url_data *urld;
int done, cmdtypesize, newurlcmdsize;
void *newurlcmd;
char *ch;

done = FALSE;

if ((urld = (drw_url_data *) actiondata))
 {
  if (strlen(urld->url))
   {
    if ((ch = strchr(urld->url, ':')))
     {
      cmdtypesize = (int) (ch - urld->url);
      newurlcmdsize = 16 + (int) strlen(ch) + cmdtypesize;

      if (newurlcmdsize > drwurlcmdsize)
       {
        if ((newurlcmd = drw_os_heap_realloc(drwurldarea,
                                    (void *) drwurlcmd,
                                    newurlcmdsize - drwurlcmdsize)))
         {
          drwurlcmd = (char *) newurlcmd;
          drwurlcmdsize = newurlcmdsize;
         }
       }

      if (newurlcmdsize <= drwurlcmdsize)
       {
        strcpy(drwurlcmd, "Alias$URLOpen_");
        strncat(drwurlcmd, urld->url, cmdtypesize);
        *(drwurlcmd + 14 + cmdtypesize) = '\0';

        if ((newurlcmdsize = drw_wimp_testsysvariable(drwurlcmd)))
         {
          strcat(drwurlcmd,  " ");
          strcat(drwurlcmd, urld->url);

          if (!drw_wimp_start_task((drwurlcmd + 6), NULL))
           done = TRUE;
         }
       }
     }
   }

  if (urld->urldonefn)
   (*urld->urldonefn)(urld->url, done);

  drw_url_free_data(actiondata);
 }

}


extern int drw_catch_acorn_open_url_msg(wimp_message *wmsg,
                                        bits msgactioncode,
                                        wimp_event_no reason,
                                        void *actiondata)

{

uri_full_message_return_result *rmsg;
drw_url_data *urld;

rmsg = (uri_full_message_return_result *) wmsg;

drw_url_release_acorn_fn(actiondata);

if (!(rmsg->flags & uri_RETURN_RESULT_NOT_CLAIMED))
 {
  if ((urld = (drw_url_data *) actiondata))
   {
    if (urld->urldonefn)
     (*urld->urldonefn)(urld->url, TRUE);

    drw_url_free_data(actiondata);
   }
 }
else
 drw_start_url_loader(actiondata);

return TRUE;

}


extern int drw_catch_rtnd_ant_open_url_msg(wimp_message *wmsg,
                                           bits msgackcode,
                                           wimp_event_no reason,
                                           void *actiondata)


{

os_error *oe;
uri_dispatch_result_flags flagsout;
uri_h urihandle;
wimp_t handler_task;
drw_url_data *urld;
int result;

result = FALSE;

oe = NULL;

handler_task = (wimp_t) 0;
urihandle = (uri_h) 0;

flagsout = (uri_dispatch_result_flags) 0;

if ((urld = (drw_url_data *) actiondata))
 {
  drw_url_release_ant_fn(actiondata);

  drw_assign_user_msg_action(message_URI_RETURN_RESULT,
                             &drw_catch_acorn_open_url_msg,
                             actiondata);

  #ifndef _DRW_USE_SWI_FN_
   oe = (os_error *) xuri_dispatch(uri_DISPATCH_INFORM_CALLER,
                                   (char const *) urld->url,
                                   pwd->wtask,
                                   &flagsout,
                                   &handler_task,
                                   &urihandle);
  #else
   oe = (os_error *) _swix(URI_Dispatch,
                           _IN(0) | _IN(1) | _IN(2) |
                           _OUT(0) | _OUT(2) | _OUT(3),
                           uri_DISPATCH_INFORM_CALLER,
                           (char const *) urld->url,
                           pwd->wtask,
                           &flagsout,
                           &handler_task,
                           &urihandle);
  #endif

  if (oe || (flagsout & uri_RETURN_RESULT_NOT_CLAIMED))
   {
    drw_url_release_acorn_fn(actiondata);
    drw_start_url_loader(actiondata);
   }
 }

return TRUE;

}


extern os_error *drw_broadcast_ant_url(drw_url_data *urld)

{

os_error *oe;
inetsuite_full_message_open_url imsg;

oe = NULL;

if (urld)
 {
  imsg.direct.your_ref = 0;
  imsg.direct.action = message_INET_SUITE_OPEN_URL;

  if (strlen(urld->url) < 236)
   {
    strcpy(imsg.direct.url, urld->url);

    imsg.direct.size = roundup((sizeof(wimp_message_header_base) +
                                strlen(urld->url) + (size_t) 1));
   }
  else
   {
    imsg.indirect.tag = 0;
    imsg.indirect.url.pointer = urld->url;
    imsg.indirect.flags = (inetsuite_open_url_flags) 0;
    imsg.indirect.body_file.offset = 0;
    imsg.indirect.target.offset = 0;
    imsg.indirect.body_mimetype.offset = 0;

    imsg.indirect.size = sizeof(inetsuite_full_message_open_url_indirect);
   }

  drw_assign_user_msgack(message_INET_SUITE_OPEN_URL,
                         &drw_catch_rtnd_ant_open_url_msg,
                         (void *) urld);

  drw_user_action_null((wimp_w) -2,
                       (wimp_i) -1,
                       NULL,
                       0,
                       -1,
                       &drw_url_catch_nulls,
                       (void *) urld);

  drw_app_start_null_events();

  if ((oe = drw_send_message(wimp_USER_MESSAGE_RECORDED,
                             (wimp_message *) &imsg,
                             (wimp_t) 0)))
   {
    if (urld->urldonefn)
     (*urld->urldonefn)(urld->url, FALSE);

    drw_url_release_ant_fn((void *) urld);
    drw_app_stop_null_events(FALSE);
    drw_url_free_data((void *) urld);
   }
 }

return oe;

}


extern int drw_url_catch_nulls(wimp_block *wb,
                               wimp_event_no action,
                               void *urldataptr)

{

drw_url_data *urld;

wb = wb;
action = action;

if ((urld = (drw_url_data *) urldataptr))
 {
  if (urld->urldonefn)
   (*urld->urldonefn)(urld->url, TRUE);

  drw_url_release_ant_fn(urldataptr);
  drw_url_free_data(urldataptr);
 }

return TRUE;

}


extern void drw_init_url_data(drw_url_data *urld)

{

if (urld)
 {
  urld->url[0] = '\0';
  urld->urldonefn = NULL;
 }

}


extern os_error *drw_launch_url(char *url,
                                drw_url_fn urldonefn,
                                int maxheapsize)
{

os_error *oe;
drw_url_data *urld;
size_t urllen;
char urldaname[32];

oe = NULL;

if (!url)
 return oe;

if (!(urllen = strlen(url)))
 return oe;

if (!drwurldarea)
 {
  sprintf(urldaname,
          "%s_urls_buffer",
          pwd->uwd->appdirname);

  if (!(drwurldarea = drw_wimp_create_os_heap(maxheapsize,
                                              DRW_MEM_DA,
                                              os_AREA_NO_USER_DRAG,
                                              urldaname,
                                              FALSE)))
   {
    if (urldonefn)
     (*urldonefn)(url, FALSE);

    return oe;
   }
 }

if (!(urld = (drw_url_data *) drw_os_heap_alloc(drwurldarea,
                roundup(sizeof (drw_url_data) + urllen + (size_t) 1))))
 {
  if (urldonefn)
   (*urldonefn)(url, FALSE);

  return oe;
 }

drw_init_url_data(urld);
strcpy(urld->url, url);
urld->urldonefn = urldonefn;

return drw_broadcast_ant_url(urld);

}


